创建普通菜单步骤如下:
创建右键菜单的步骤如下:
当然,如果你选择在已有菜单上进行编辑的话,也是可以的,就省略了其中的一些步骤。本节的例子就是在已有的菜单里面添加自己定义的菜单项。对于右键菜单你也可以选择已有的菜单中的一栏作为弹出菜单。
使用菜单后,要涉及清除的问题,和窗口相连的菜单句柄在窗口摧毁的时候会由Windows自动释放,不需要手工释放,但没有和窗口相连的菜单就要由程序自己来释放了,方法是使用DestroyMenu函数,比如没有和窗口相连而仅用TrackPopupMenu弹出的菜单句柄。本例中,我们使用的是窗口关联的菜单句柄,因此我们不需要调用DestroyMenu消除菜单资源。
菜单消息:当用户选择一个菜单项时,windwos通常向窗口过程发送几个不同的消息。在大多数情况下,你的程序可以忽略大部分的消息,只需要把他们传递给DefWindowProc即可。
对于已有菜单,我们可以使用GetSystemMenu,GetMenu ,GetSubMenu来获取菜单句柄。当需要更改菜单时,可以使用下面的API进行更改。 AppendMenu, DeleteMenu,InsertMenu,ModifyMenu,RemoveMenu等等。
/
//
// Menu
IDM_MAIN MENU
BEGIN
POPUP "文件(&F)"
BEGIN
MENUITEM "打开文件(&O)...", IDM_OPEN
MENUITEM "关闭文件(&C)...", IDM_OPTION
MENUITEM SEPARATOR
MENUITEM "退出(&X)", IDM_EXIT
END
POPUP "查看(&V)"
BEGIN
MENUITEM "字体(&F)...\tAlt+F", IDM_SETFONT
MENUITEM "背景色(&B)...\tCtrl+Alt+B", IDM_SETCOLOR
MENUITEM SEPARATOR
MENUITEM "被禁用的菜单项", IDM_INACT, INACTIVE
MENUITEM "被灰化的菜单项", IDM_GRAY, GRAYED
MENUITEM SEPARATOR
MENUITEM "大图标(&G)", IDM_BIG
MENUITEM "小图标(&M)", IDM_SMALL
MENUITEM "列表(&L)", IDM_LIST
MENUITEM "详细资料(&D)", IDM_DETAIL
MENUITEM SEPARATOR
POPUP "工具栏(&T)"
BEGIN
MENUITEM "标准按钮(&S)", IDM_TOOLBAR
MENUITEM "文字标签(&C)", IDM_TOOLBARTEXT
MENUITEM "命令栏(&I)", IDM_INPUTBAR
END
MENUITEM "状态栏(&U)", IDM_STATUSBAR
END
POPUP "帮助(&H)"
BEGIN
MENUITEM "帮助主题(&H)\tF1", IDM_HELP
MENUITEM SEPARATOR
MENUITEM "关于(&A) ...", IDM_ABOUT
END
END
/
//
// Accelerator //加速键,在资源视图中,添加快捷键资源
IDC_SDKPOPUPMENU ACCELERATORS
BEGIN
"/", IDM_ABOUT, ASCII, ALT, NOINVERT
"?", IDM_ABOUT, ASCII, ALT, NOINVERT
VK_F1, IDM_HELP, VIRTKEY, NOINVERT
"B", IDM_SETCOLOR, VIRTKEY, CONTROL, ALT, NOINVERT
"F", IDM_SETFONT, VIRTKEY, ALT, NOINVERT
END
关键代码
#define IDC_MYICON 2
#define IDD_SDKPOPUPMENU_DIALOG 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 103
#define IDI_SDKPOPUPMENU 107
#define IDI_SMALL 108
#define IDC_SDKPOPUPMENU 109
#define IDR_MAINFRAME 128
#define IDM_MAIN 0x2000
#define IDA_MAIN 0x2000
#define IDM_OPEN 0x4101
#define IDM_OPTION 0x4102
#define IDM_EXIT 0x4103
#define IDM_SETFONT 0x4201
#define IDM_SETCOLOR 0x4202
#define IDM_INACT 0x4203
#define IDM_GRAY 0x4204
#define IDM_BIG 0x4205
#define IDM_SMALL 0x4206
#define IDM_LIST 0x4207
#define IDM_DETAIL 0x4208
#define IDM_TOOLBAR 0x4209
#define IDM_TOOLBARTEXT 0x4210
#define IDM_INPUTBAR 0x4211
#define IDM_STATUSBAR 0x4212
#define IDM_HELP 0x4301
#define IDM_ABOUT 0x4302
TCHAR szClassName[] = L"Menu Example";
TCHAR szCaptionMain[] = L"menu";
TCHAR szMenuHelp[] = L"帮助主题(&H)";
TCHAR szMenuAbout[] = L"关于本程序(&A)...";
HWND g_hWinMain;
HMENU g_hMenu;
HMENU g_hSubMenu;
void DisplayMenuItem(DWORD dwCommandID)
{
TCHAR szBuffer[256] = {0};
wsprintf(szBuffer, L"您选择了菜单命令:%08x",dwCommandID);
MessageBox(g_hWinMain,szBuffer, L"菜单选择",MB_OK);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
g_hMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDM_MAIN));//加载菜单资源,返回菜单句柄
g_hSubMenu = GetSubMenu(g_hMenu,1); //获取主菜单的第2个子菜单,用作快捷菜单
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, g_hMenu, hInstance, NULL);//把菜单放到窗口中
g_hWinMain=hWnd;
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
POINT stPos;
HMENU hSysMenu;
switch (message)
{
case WM_CREATE:
hSysMenu = GetSystemMenu(hWnd,FALSE);//获取系统菜单句柄
AppendMenu(hSysMenu,MF_SEPARATOR,0,NULL);//把分割线附加到系统菜单中
AppendMenu(hSysMenu,0,IDM_HELP,szMenuHelp);//把菜单项help附加到系统菜单中
AppendMenu(hSysMenu,0,IDM_ABOUT,szMenuAbout);//把菜单项about附加到系统菜单中
break;
case WM_COMMAND: //用户菜单项命令的消息
DisplayMenuItem(wParam);//显示对话框
//对于单项项的标识(单项,双选)的标识
if(LOWORD(wParam) == IDM_EXIT)
{
DestroyWindow(hWnd);
}
else if(LOWORD(wParam) >= IDM_TOOLBAR && LOWORD(wParam) <= IDM_STATUSBAR) //多选的 工具栏的:标准按钮,命令栏,文字标签
{
UINT uState = GetMenuState(g_hMenu,LOWORD(wParam),MF_BYCOMMAND);
if(uState == MF_CHECKED)
uState = MF_UNCHECKED;
else
uState = MF_CHECKED;
CheckMenuItem(g_hMenu,LOWORD(wParam),uState);//复选或撤销指定菜单的菜单条目
}
else if(LOWORD(wParam) >= IDM_BIG && LOWORD(wParam) <= IDM_DETAIL)//单选的 大图标,小图标,列表,详细资料
{
CheckMenuRadioItem(g_hMenu,IDM_BIG,IDM_DETAIL,LOWORD(wParam),MF_BYCOMMAND);//单选[IDM_BIG,IDM_DETAIL]中的一个
}
//CheckMenuItem,CheckMenuRadioItem分别用于改变菜单项的状态。菜单项的状态可以通过GetMenuState函数获得。
break;
case WM_SYSCOMMAND://系统菜单项的命令消息
if(LOWORD(wParam) == IDM_HELP || LOWORD(wParam) == IDM_ABOUT)//附加到系统菜单的help,about的菜单项
DisplayMenuItem(wParam);
else
return DefWindowProc(hWnd,message,wParam,lParam);
break;
case WM_RBUTTONDOWN:
GetCursorPos(&stPos);//获取光标位置
TrackPopupMenu(g_hSubMenu,TPM_LEFTALIGN,stPos.x,stPos.y,NULL,hWnd,NULL);//在指定位置显示快捷菜单,并跟踪菜单选项
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}