SDK第二天—菜单
接着上一天的内容,添加一个菜单,并加入各项,用记事本打开resource.rc,可以找到如下内容
IDR_MENU1 MENU DISCARDABLE //这里定义菜单名
BEGIN
MENUITEM "Exit", IDM_EXIT //添加菜单项EXIT
POPUP "Edit" //添加弹出菜单
BEGIN
MENUITEM "Copy(&C)/tCtrl+C", IDM_COPY
MENUITEM "Paste", IDM_PASTE
MENUITEM SEPARATOR
MENUITEM "SeleceAll", IDM_SELECTALL
END
MENUITEM "About", IDM_ABOUT
END
同时在resource.h中可以找到IDM_EXIT等的定义
#define IDM_EXIT 40001
#define IDM_COPY 40002
#define IDM_PASTE 40003
#define IDM_SELECTALL 40004
#define IDM_ABOUT 40005
#define IDM_ALIGNLEFT 40006
#define IDM_ALIGNRIGHT 40007
这样就把菜单资源和我们的主程序关联起来了。
接着就要把菜单在窗口中显示出来,我们可以在初始化窗口时指定菜单
wndclass.lpszMenuName=(LPCSTR)IDR_MENU1;
这样编译,运行就可以看到菜单出现在主窗口上部了
菜单项的消息响应:
菜单消息归类于WM_COMMAND,而对于特定的菜单项,有相应的消息值跟他对应,所以只要对WM_COMMAND消息进行进一步的分流,就可以添加各个菜单的消息响应。具体代码如下:
case WM_COMMAND:
wparam=LOWORD(wParam);
switch(wparam)
{
case IDM_EXIT:
PostQuitMessage(0);
return 0;
case IDM_COPY:
MessageBox(hwnd,"Copy Content","Menu",MB_OK);
return 0;
case IDM_PASTE:
MessageBox(hwnd,"Paste Content","Menu",MB_OK);
return 0;
case IDM_SELECTALL:
MessageBox(hwnd,"Select All Content","Menu",MB_OK);
return 0;
case IDM_ABOUT:
MessageBox(hwnd,"About: Designed by csenior","Menu",MB_OK);
return 0;
}
Break;
另外还有一种创建菜单的方式:利用CreateMenu,CreatePopupMenu,GetMenu,InsertMenu,AppendMenu函数,我们试着在WM_CREATE消息中添加如下代码:
case WM_CREATE:
HMENU hMainMenu;
HMENU hAddMenu;
hMainMenu=GetMenu(hwnd);
hAddMenu=CreatePopupMenu();
InsertMenu(hMainMenu,2,MF_BYPOSITION | MF_STRING | MF_POPUP,(UINT)hAddMenu,"格式");
AppendMenu(hAddMenu,MF_STRING,IDM_ALIGNLEFT,"Left Align");
AppendMenu(hAddMenu,MF_STRING,IDM_ALIGNRIGHT,"Right Align");
编译运行,可以看到多了个菜单条。
这里GetMenu(hwnd)获得hwnd窗口的菜单。然后通过InsertMenu把之前创建的hAddMenu连接到hMainMenu上去。最后添加各子菜单项
之前在CreateWindow创建窗口时,倒数第三个参数就是HMENU结构,试着在这里给他赋一个值:
HMENU hMenu,hCMenu1,hCMenu2,hCMenu3;
hMenu=CreateMenu();
hCMenu1=CreatePopupMenu();
hCMenu2=CreatePopupMenu();
hCMenu3=CreatePopupMenu();
InsertMenu(hMenu,0,MF_BYPOSITION | MF_STRING | MF_POPUP,(UINT)hCMenu1,"File");
InsertMenu(hMenu,1,MF_BYPOSITION | MF_STRING | MF_POPUP,(UINT)hCMenu2,"View");
InsertMenu(hMenu,2,MF_BYPOSITION | MF_STRING | MF_POPUP,(UINT)hCMenu3,"Edit");
AppendMenu(hMenu,MF_STRING,(UINT)41001,"About");
AppendMenu(hCMenu1,MF_STRING,(UINT)41002,"Open");
AppendMenu(hCMenu1,MF_STRING,(UINT)41003,"Close");
AppendMenu(hCMenu2,MF_STRING,(UINT)41004,"Big");
AppendMenu(hCMenu2,MF_STRING,(UINT)41005,"Small");
AppendMenu(hCMenu3,MF_STRING,(UINT)41006,"Copy");
AppendMenu(hCMenu3,MF_STRING,(UINT)41007,"Paste");
hWnd=CreateWindow("HelloWin",wintitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,hMenu,hInstance,NULL);
运行,我们可以看到菜单变了,因此在此处也可以添加修改程序的菜单,但是这里不能用GetMenu,因为hWnd窗口句柄还没被实例化
关于菜单命令的消息参数说明下:
基本参数说明:
wNotifyCode=HIWORD(wParam)1
WID=LOWORD(wParam);
hWndCtl=(HWND)1Param”;
当WM_CoMMAND命令是由选择菜单命令产生时WNotifycode参数为0,wID参数
为菜单项的标识导,hwndctl参数为NULL。
当WM_COMMAND命今是来自于快捷键时WNotifycode参数为1 WID是快捷键标
识号,hWndCtl参数为NULL。
如果是因为控件向父窗口发出通知消息面产生WM—COMMAND消息时。
WNotifycode参数为通知代码,wID为控件标识号,hwndctl参数为控件句柄。
通过EnabaleMenuItem,EnableMenuRadioItem,可以设置菜单项的状态为有效,无效,灰色三种,同时可以调用CheckMenuItem,CheckMenuRadioItem来改变菜单项的选种状态具体如下代码:
EnableMenuItem(hMainMenu,IDM_EXIT,MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hAddMenu,1,MF_BYPOSITION | MF_GRAYED);
CheckMenuItem(hMainMenu,IDM_COPY,MF_BYCOMMAND |MF_CHECKED); CheckMenuRadioItem(hAddMenu,IDM_ALIGNLEFT,IDM_ALIGNRIGHT,IDM_ALIGNLEFT,MF_BYCOMMAND);