菜单项位图示例

【勇芳软件工作室】汉化HomePreviousNext

本主题中的示例创建两个菜单,每个菜单包含几个位图菜单项。对于每个菜单,应用程序在主窗口的菜单栏中添加相应的菜单名称。

第一个菜单包含显示三种图表类型的菜单项:饼图,线条和条形图。这些菜单项的位图被定义为资源,并使用LoadBitmap功能加载。与此菜单相关联是菜单栏上的“图表”菜单名称。

第二个菜单包含显示CreatePen功能中使用的五种线条样式的菜单项:PS_SOLID,PS_DASH,PS_DOT,PS_DASHDOT和PS_DASHDOTDOT。该应用程序使用GDI绘图功能在运行时创建这些菜单项的位图。与此菜单相关联的是菜单栏上的“线条”菜单名称。

在应用程序的窗口过程中定义了两个位图句柄的静态数组。一个数组包含用于图表菜单的三个位图的句柄。另一个包含用于“线”菜单的五个位图的句柄。处理WM_CREATE消息时,窗口过程将加载图表位图,创建行位图,然后添加相应的菜单项。处理WM_DESTROY消息时,窗口过程将删除所有位图。

以下是应用程序头文件的相关部分。

//菜单项标识符

#define IDM_LINE 2

#define IDM_BAR 3

// Line-type flags

#define IDM_SOLID 4

#define IDM_DASH 5

#define IDM_DASHDOT 6

#define IDM_DASHDOTDOT 7

//图表和线菜单上的项目数

#define C_LINES 5

#define C_CHARTS 3

//位图资源标识符

#define IDB_PIE 1

#define IDB_LINE 2

#define IDB_BAR 3

//行位图的尺寸

#define CX_LINEBMP 40

#define CY_LINEBMP 10

以下是窗口过程的相关部分。窗口过程通过调用应用程序定义的LoadChartBitmaps,CreateLineBitmaps和AddBitmapMenu函数来执行其大部分初始化,本主题稍后介绍。

LRESULT CALLBACK MainWindowProc(

HWND hwnd,

UINT uMsg,

WPARAM wParam,

if(!OnCreate(hwnd))

)

{

static HBITMAP aHbmLines[C_LINES];

static HBITMAP aHbmChart[C_CHARTS];

int i;

开关(uMsg){

case WM_CREATE:

//调用应用程序定义的函数来加载

//图表菜单的位图,并为其创建

//线条菜单。

LoadChartBitmaps(aHbmChart);

CreateLineBitmaps(aHbmLines);

//调用应用程序定义的函数来创建

//包含位图菜单项的菜单。功能

//还向窗口的菜单栏添加菜单名称。

AddBitmapMenu(

hwnd, //菜单栏的所有者窗口

"&Chart", 菜单栏上的菜单名称的文本

IDM_PIE, //菜单上第一个项目的ID

aHbmChart, //数组位图句柄

C_CHARTS //菜单上的项目数量

);

AddBitmapMenu(hwnd,“&行”,IDM_SOLID,

aHbmLines, C_LINES);

break;

case WM_DESTROY:

for (i = 0; i < C_LINES; i++)

DeleteObject(aHbmLines[i]);

for (i = 0; i < C_CHARTS; i++)

DeleteObject(aHbmChart[i]);

PostQuitMessage(0);

break;

.

. //处理其他消息。

.

默认:

return (DefWindowProc(hwnd, uMsg, wParam, lParam));

}

return 0;

}

应用程序定义的LoadChartBitmaps函数通过调用LoadBitmap函数加载图表菜单的位图资源,如下所示。

VOID WINAPI LoadChartBitmaps(HBITMAP * paHbm)

{

paHbm[0] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_PIE));

paHbm[1] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_LINE));

paHbm[2] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_BAR));

}

应用程序定义的CreateLineBitmaps函数通过使用GDI绘图函数为Lines菜单创建位图。该函数创建与桌面窗口的DC具有相同属性的内存设备上下文(DC)。对于每个线型,函数创建一个位图,将其选择到存储器DC中,然后进行绘制。

VOID WINAPI CreateLineBitmaps(HBITMAP * paHbm)

{

HWND hwndDesktop = GetDesktopWindow();

HDC hdcDesktop = GetDC(hwndDesktop);

HDC hdcMem = CreateCompatibleDC(hdcDesktop);

COLORREF clrMenu = GetSysColor(COLOR_MENU);

HBRUSH hbrOld;

HPEN hpenOld;

HBITMAP hbmOld;

int fnDrawMode;

int i;

//使用菜单背景颜色创建一个画笔,

//并将其选择到内存DC中。

hbrOld = SelectObject(hdcMem, CreateSolidBrush(clrMenu));

//创建位图。选择每一个进入存储器

// DC被创建并绘制。

for (i = 0; i < C_LINES; i++) {

//创建位图并将其选择到DC中。

paHbm[i] = CreateCompatibleBitmap(hdcDesktop,

CX_LINEBMP, CY_LINEBMP);

hbmOld = SelectObject(hdcMem, paHbm[i]);

//使用画笔填写背景。

PatBlt(hdcMem, 0, 0, CX_LINEBMP, CY_LINEBMP, PATCOPY);

//创建笔并将其选入DC。

hpenOld = SelectObject(hdcMem,

CreatePen(PS_SOLID + i, 1, RGB(0, 0, 0)));

//画线保留背景颜色

//笔为白色,请使用R2_MASKPEN绘图模式。

fnDrawMode = SetROP2(hdcMem, R2_MASKPEN);

MoveToEx(hdcMem, 0, CY_LINEBMP / 2, NULL);

LineTo(hdcMem, CX_LINEBMP, CY_LINEBMP / 2);

SetROP2(hdcMem, fnDrawMode);

//删除笔,然后选择旧的笔和位图。

DeleteObject(SelectObject(hdcMem, hpenOld));

SelectObject(hdcMem, hbmOld);

}

//删除画笔并选择原始画笔。

DeleteObject(SelectObject(hdcMem, hbrOld));

//删除内存DC并释放桌面DC。

DeleteDC(hdcMem);

ReleaseDC(hwndDesktop, hdcDesktop);

}

应用程序定义的AddBitmapMenu函数创建一个菜单,并向其中添加指定数量的位图菜单项。然后在指定的窗口的菜单栏中添加相应的菜单名称。

VOID WINAPI AddBitmapMenu(

HWND hwnd, //拥有菜单栏的窗口

LPSTR lpszText, 菜单栏上的菜单名称的文本

UINT uID, //第一个位图菜单项的ID

HBITMAP *paHbm, //菜单项的位图

int cItems) //号码位图菜单项

{

HMENU hmenuBar = GetMenu(hwnd);

HMENU hmenuPopup = CreatePopupMenu();

MENUITEMINFO mii;

int i;

//将位图菜单项添加到菜单中。

for (i = 0; i < cItems; i++) {

mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_DATA;

mii.fType = MFT_BITMAP;

mii.wID = uID + i;

mii.dwTypeData = (LPSTR) (paHbm[i]);

InsertMenuItem(hmenuPopup, i, TRUE, &mii);

}

//向菜单栏添加菜单名称。

mii.fMask = MIIM_TYPE | MIIM_DATA | MIIM_SUBMENU;

mii.fType = MFT_STRING;

mii.hSubMenu = hmenuPopup;

mii.dwTypeData = lpszText;

InsertMenuItem(hmenuBar,

GetMenuItemCount(hmenuBar), TRUE, &mii);

}