添加线和图形到菜单
下列的代码例子显示了怎样新建一个包含位图项的菜单。它新建了两个菜单。首先是一个包含三个位图项的图表菜单:一个圆形统计图表,一个线形统计图表和一个条形统计图表。这个例子说明了怎样从应用程序的资源文件中装入这些位图,及怎样使用CreatePopupMenu和AppendMenu函数去新建菜单和菜单项。
第二个菜单是一个线形菜单。它包含显示线形风格的位图(假如这些是系统定义好的)线形风格位图是在运行时使用GDI函数新建的。
这是应用程序资源定义文件中定义的位图资源。
PIE BITMAP pie.bmp
LINE BITMAP line.bmp
BAR BITMAP bar.bmp
这是应用程序头文件的有关部分。
// 菜单项标识符
#define IDM_SOLID PS_SOLID
#define IDM_DASH PS_DASH
#define IDM_DASHDOT PS_DASHDOT
#define IDM_DASHDOTDOT PS_DASHDOTDOT
#define IDM_PIE 1
#define IDM_LINE 2
#define IDM_BAR 3
// 线类形标记
#define SOLID 0
#define DOT 1
#define DASH 2
#define DASHDOT 3
#define DASHDOTDOT 4
// 画笔大不
#define CPENS 5
// 图表类型标记
#define PIE 1
#define LINE 2
#define BAR 3
// 函数原型
LRESULT APIENTRY MainWndProc(HWND, UINT, WPARAM, LPARAM);
VOID MakeChartMenu(HWND);
VOID MakeLineMenu(HWND, HPEN, HBITMAP);
下列的例子显示了怎样在应用程序中新建菜单及菜单项。
LRESULT APIENTRY MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HPEN hpen[CPENS];
static HBITMAP hbmp[CPENS];
int i;
switch (uMsg)
{
case WM_CREATE:
// 新建图表和线形菜单
MakeChartMenu(hwnd);
MakeLineMenu(hwnd, hpen, hbmp);
return 0;
// 处理其他的窗口消息
case WM_DESTROY:
for (i = 0; i < CPENS; i++)
{
DeleteObject(hbmp[i]);
DeleteObject(hpen[i]);
}
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return NULL;
}
VOID MakeChartMenu(HWND hwnd)
{
HBITMAP hbmpPie; // 圆形统计分格图表位图句柄
HBITMAP hbmpLine; // 线形图表位图句柄
HBITMAP hbmpBar; // 条形图表位图句柄
HMENU hmenuMain; // 主菜单句柄
HMENU hmenuChart; // 图表菜单句柄
// 从资源文件中装入图形,线形和条形图表位图
hbmpPie = LoadBitmap(hinst, MAKEINTRESOURCE(PIE));
hbmpLine = LoadBitmap(hinst, MAKEINTRESOURCE(LINE));
hbmpBar = LoadBitmap(hinst, MAKEINTRESOURCE(BAR));
// 新建图表菜单并添加它到菜单栏
// 附加圆形,线形和条形菜单条到图表菜单。
hmenuMain = GetMenu(hwnd);
hmenuChart = CreatePopupMenu();
AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (UINT) hmenuChart,
"Chart");
AppendMenu(hmenuChart, MF_BITMAP, IDM_PIE, (LPCTSTR) hbmpPie);
AppendMenu(hmenuChart, MF_BITMAP, IDM_LINE,
(LPCTSTR) hbmpLine);
AppendMenu(hmenuChart, MF_BITMAP, IDM_BAR, (LPCTSTR) hbmpBar);
return;
}
VOID MakeLineMenu(HWND hwnd, HPEN phpen, HBITMAP phbmp)
{
HMENU hmenuLines; // 线形菜单句柄
HMENU hmenu; // 主菜单句柄
COLORREF crMenuClr; // 菜单条背景颜色
HBRUSH hbrBackground; // 背景刷句柄
HBRUSH hbrOld; // 早先刷句柄
WORD wLineX; // 线形位图的宽
WORD wLineY; // 线形位图的高
HDC hdcMain; // 主窗口的DC句柄
HDC hdcLines; // 兼容DC句柄
HBITMAP hbmpOld; // 早先位图句柄
int i; // 循环计数器
// 新建线形菜单。添加它到菜单栏
hmenu = GetMenu(hwnd);
hmenuLines = CreatePopupMenu();
AppendMenu(hmenu, MF_STRING | MF_POPUP,
(UINT) hmenuLines, "&Lines");
// 为菜单项背景颜色新建一个刷子。
crMenuClr = GetSysColor(COLOR_MENU);
hbrBackground = CreateSolidBrush(crMenuClr);
// 为线形位图新建一个兼容设备描述符,
// 并在其中选择背景刷
hdcMain = GetDC(hwnd);
hdcLines = CreateCompatibleDC(hdcMain);
hbrOld = SelectObject(hdcLines, hbrBackground);
// 获得复选标记位图的尺寸。
// 线形位图的宽将是复选标记位图宽的五倍
wLineX = GetSystemMetrics(SM_CXMENUCHECK) * (WORD) 5;
wLineY = GetSystemMetrics(SM_CYMENUCHECK);
// 在设备描述符中新建位图并选择它们,一次一个,
// 用菜单项背景色填充它来初始化每一个位图。
for (i = 0; i < CPENS; i++)
{
phbmp[i] = CreateCompatibleBitmap(hdcMain, wLineX, wLineY);
if (i == 0)
hbmpOld = SelectObject(hdcLines, phbmp[i]);
else
SelectObject(hdcLines, phbmp[i]);
ExtFloodFill(hdcLines, 0, 0, crMenuClr, FLOODFILLBORDER);
}
// 新建画笔
phpen[0] = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
phpen[1] = CreatePen(PS_DOT, 1, RGB(0, 0, 0));
phpen[2] = CreatePen(PS_DASH, 1, RGB(0, 0, 0));
phpen[3] = CreatePen(PS_DASHDOT, 1, RGB(0, 0, 0));
phpen[4] = CreatePen(PS_DASHDOTDOT, 1, RGB(0, 0, 0));
// 在兼容设备描述符中选择一个画笔和一个位图,
// 在位图中绘制一个线形,并应用这个位图到线形菜单中作为一个项。
for (i = 0; i < CPENS; i++)
{
SelectObject(hdcLines, phbmp[i]);
SelectObject(hdcLines, phpen[i]);
MoveToEx(hdcLines, 0, wLineY / 2, NULL);
LineTo(hdcLines, wLineX, wLineY / 2);
AppendMenu(hmenuLines, MF_BITMAP, i + 1,
(LPCTSTR) phbmp[i]);
}
// 释放主窗口的设备描述符并消毁兼容设备描述符。同样,消毁背景刷
ReleaseDC(hwnd, hdcMain);
SelectObject(hdcLines, hbrOld);
DeleteObject(hbrBackground);
SelectObject(hdcLines, hbmpOld);
DeleteDC(hdcLines);
return;
}