windows sdk编程系列文章06 ---- 菜单.doc_第1页
windows sdk编程系列文章06 ---- 菜单.doc_第2页
windows sdk编程系列文章06 ---- 菜单.doc_第3页
windows sdk编程系列文章06 ---- 菜单.doc_第4页
windows sdk编程系列文章06 ---- 菜单.doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

windows sdk编程系列文章 - 菜单2008-04-09 22:34本课中我们将在我们的应用程序中加入一个菜单。理论:菜单可以说是WINDOWS最重要的元素之一。有了它,用户可以方便地选择操作命令.用户只要细读一下所有的菜单项就可以明了应用程序所提供的大概功能,而且可以立即操作,无须去阅读手册了.正因为菜单给了用户一种方便的方式,所以您在应用程序中加入菜单时就要遵守一般的标准.譬如:一般头两个菜单项是File和Edit,最后是Help,您可以在这中间插入您要定义的菜单项.如果所运行的菜单命令会弹出一个对话框,那么就要在该菜单项后加入省略符(.).菜单是一种资源,除菜单外还有其它像对话框,字符串,图标,位图资源等.在链接时链接程序将把资源加入到可执行程序中去,最后我们的执行程序中就既包括机器指令又包括了资源. 您可以在任何文本编辑器中编写脚本文件,在文件中您可以指定资源呈现出来的外观和其它的一些属性.当然更直观的方法是用资源编辑器,通常资源编辑器都打包在编译环境中,像Visual C+, Borland C+等都带了资源编辑器. 我们可以按以下方式来定义一个菜单资源: MyMenu MENU menu list here这和C语言中的结构体的定义非常相似。 MyMenu类似于被定义的变量,而MENU则类似于关键字。当然您可以用另外一种办法,那就是用BEGIN和END来代替花括号,这和PASCAL语言中的风格相同。 在菜单项的列表中是一大串的MENUITEM和POPUP语句。MENUITEM定义了一个菜单项,当选择后不会激活对话框。它的语法如下: MENUITEM &text, ID ,options它由关键字MENUITEM开头,紧跟在MENUITEM后的是指菜单项的名称字符串,符号“&“后的第一个字符将会带下画线,它也是该菜单项的快捷键。ID的作用当该菜单被选中时,WINDOWS的消息处理过程用来区分菜单项用的。毫无疑问,ID号必须唯一。options有以下可供选择的属性: GRAYED 代表该菜单项处于非激活状态,即当其被选中时不会产生WM_COMMAND消息。该菜单以灰色显示。 INACTIVE 代表该菜单项处于非激活状态,即当其被选中时不会产生WM_COMMAND消息。该菜单以正常颜色显示。 MENUBREAK 该菜单项和随后的菜单项会显示在新列中。 HELP 该菜单项和随后的菜单项右对齐。 您可以单独使用以上标志位,也可以把它们或在一起。当然INACTIVE和GRAYED不能同时使用。 POPUP的语法如下: POPUP &text ,optionsmenu listPOPUP定义了一个菜单项当该菜单项被选中时又会弹出一个子菜单。另外有一种特别类型的MENUITEM语句MENUITEM SEPARATOR,它表示在菜单项位置画一条分隔线。 定义完菜单后,您就可以在程序中使用脚本中定义的菜单资源了。 您可以在程序的两个地方(或叫做用两种方式)使用它们: 在WNDCLASSEX结构体的成员lpszMenuName中。譬如,您有一个菜单“FirstMenu“,您可以按如下方法把它联系到您的窗口:(见FirstWindow6-1) TCHAR MenuName = _T(FirstMenu);.stdWndClass.lpszMenuName = MenuName; . 在CreateWindowEx函数中指明菜单的句柄:(见FirstWindow6-2) HMENU hMenu; TCHAR MenuName = _T(FirstMenu); .hMenu = LoadMenu(hInstance,MenuName);hWinMain = CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain, WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,hMenu,hInstance,NULL); .您也许会问,这两着之间有什么不同呢?当您用第一种方法时,由于是在窗口类中指定,故所有由该窗口类派生的窗口都将有相同的菜单。如果您想要从相同的类中派生的窗口有不同的菜单那就要使用第二中方法,该方法中通过函数CreateWindowEx指定的菜单会“覆盖”WNDCLASSEX结构体中指定的菜单。 接下来我们看看当用户选择了一个菜单项时它是如何通知WINDOWS 窗口过程的: 当用户选择了一个菜单项时,WINDOWS窗口过程会接收到一个WM_COMMAND消息,传进来的参数wParam的底字节包含了菜单项的ID号。 好了,上面就是关于菜单项的一切,下面我们就来实践。 例子:#include Windows.h#include tchar.h#define IDM_TEST 1#define IDM_HELLO 2#define IDM_GOODBYE 3#define IDM_EXIT 4TCHAR MenuName = _T(FirstMenu);TCHAR Test_string = _T(You selected Test menu item);TCHAR Hello_string = _T(Hello, my friend);TCHAR Goodbye_string = _T(See you again, bye);HWND hWinMain;TCHAR szClassName = _T(MyClass);TCHAR szCaptionMain = _T(My First Window!);TCHAR FontName = _T(宋体);WNDCLASSEX stdWndClass;WPARAM keyChar = 0x20; /0x20是空格的ascii码,保证没有按键的时候程序正常显示。BOOL MouseClick = FALSE;POINT hitPoint;LRESULT CALLBACK ProcWinMain( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ) PAINTSTRUCT stPs; HDC hDC; HFONT hFont,hOldFont; switch(Msg) case WM_PAINT: hDC = BeginPaint(hWnd,&stPs); hFont = CreateFont(24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,FontName); hOldFont = (HFONT)SelectObject(hDC,hFont); SetTextColor(hDC,RGB(200,200,50); SetBkColor(hDC,RGB(0,0,255); TextOut(hDC,0,0,(char *)&keyChar,1); if(MouseClick) TextOut(hDC,hitPoint.x,hitPoint.y,szCaptionMain,lstrlen(szCaptionMain); SelectObject(hDC,hOldFont); EndPaint(hWnd,&stPs); break; case WM_COMMAND: switch(LOWORD(wParam) case IDM_TEST: MessageBox(NULL,Test_string,szCaptionMain,MB_OK); break; case IDM_HELLO: MessageBox(NULL,Hello_string,szCaptionMain,MB_OK); break; case IDM_GOODBYE: MessageBox(NULL,Goodbye_string,szCaptionMain,MB_OK); break; case IDM_EXIT: DestroyWindow(hWnd); break; break; case WM_LBUTTONDOWN: hitPoint.x = LOWORD(lParam); hitPoint.y = HIWORD(lParam); MouseClick = TRUE; InvalidateRect(hWnd,NULL,TRUE); break; case WM_CHAR: keyChar = wParam; InvalidateRect(hWnd,NULL,TRUE); break; case WM_DESTROY: PostQuitMessage(NULL); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam ); return 0;int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) MSG stMsg; WNDCLASSEX stdWndClass; RtlZeroMemory(&stdWndClass, sizeof(stdWndClass); stdWndClass.hCursor = LoadCursor(0,IDC_ARROW); stdWndClass.cbSize = sizeof(stdWndClass); stdWndClass.style = CS_HREDRAW|CS_VREDRAW; stdWndClass.lpfnWndProc = ProcWinMain; stdWndClass.hbrBackground = (HBRUSH)COLOR_WINDOW; stdWndClass.lpszClassName = szClassName; stdWndClass.hInstance = hInstance; stdWndClass.lpszMenuName = MenuName; RegisterClassEx(&stdWndClass); hWinMain = CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain, WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL); if(!hWinMain) return 0; ShowWindow(hWinMain,SW_SHOWNORMAL); UpdateWindow(hWinMain); while(GetMessage(&stMsg,NULL,0,0) TranslateMessage(&stMsg); DispatchMessage(&stMsg); return stMsg.wParam;*rsrc.rc * #define IDM_TEST 1 #define IDM_HELLO 2 #define IDM_GOODBYE 3 #define IDM_EXIT 4FirstMenu MENU POPUP &PopUp MENUITEM &Say Hello,IDM_HELLO MENUITEM Say &GoodBye, IDM_GOODBYE MENUITEM SEPARATOR MENUITEM E&xit,IDM_EXIT MENUITEM &Test, IDM_TEST 分析:我们先来分析资源文件:#define IDM_TEST 1 /* equal to IDM_TEST equ 1*/#define IDM_HELLO 2#define IDM_GOODBYE 3#define IDM_EXIT 4上面的几行定义了菜单项的ID号。只要注意菜单项ID号必须唯一外,您可以给ID号任何值。 FirstMenu MENU用关键字MENU定义菜单。POPUP &PopUp MENUITEM &Say Hello,IDM_HELLO MENUITEM Say &GoodBye, IDM_GOODBYE MENUITEM SEPARATOR MENUITEM E&xit,IDM_EXIT 定义一个有四个菜单项的子菜单,其中第三个菜单项是一个分隔线。MENUITEM &Test, IDM_TEST定义主菜单中的一项。下面我们来看看源代码。TCHAR MenuName = _T(FirstMenu);TCHAR Test_string = _T(You selected Test menu item);TCHAR Hello_string = _T(Hello, my friend);TCHAR Goodbye_string = _T(See you again, bye);MenuName是资源文件中指定的菜单的名字。因为您可以在脚本文件中定义任意多个菜单,所以在使用前必须指定您要使用那一个,接下来的行是在选中菜单项时显示在相关对话框中的字符串。IDM_TEST equ 1 ; Menu IDsIDM_HELLO equ 2IDM_GOODBYE equ 3IDM_EXIT equ 4定义用在WINDOWS窗口过程中的菜单项ID号。这些值必须和脚本文件中的相同。 case WM_COMMAND: switch(LOWORD(wParam) case IDM_TEST: MessageBox(NULL,Test_string,szCaptionMain,MB_OK); break; case IDM_HELLO: MessageBox(NULL,Hello_string,szCaptionMain,MB_OK); break; case IDM_GOODBYE: MessageBox(NULL,Goodbye_string,szCaptionMain,MB_OK); break; case IDM_EXIT: DestroyWindow(hWnd); break; break;在本窗口过程中我们处理WM_COMMAND消息。当用户选择了一个菜单项时,该菜单项的ID放入参数wParam中被同时送到WINDOWS的窗口过程,我们把它保存到eax寄存器中以便和预定义的菜单项ID比较用。前三种情况下,当我们选中Test、Say Hello、Say GoodBye菜单项时,会弹出一个对话框其中显示一个相关的字符串,选择Exit菜单项时,我们就调用函数DestroyWindow,其中的参数是我们窗口的句柄,这样就销毁了窗口。 就像您所看到的,通过在一个窗口类中指定菜单名的方法来给一个应用程序生成一个菜单是简单而直观的。除此方法外您还可以用另一种方法,其中资源文件是一样的,源文件中也只有少数的改动,这些改动如下: HMENU hMenu;定义了一个变量来保存我们的菜单的句柄,然后: hMenu = LoadMenu(hInstance,MenuName); hWinMain = CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain, WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,hMenu,hInstance,NULL);调用LoadMenu函数,该函数需要实例句柄和菜单名的字符串,调用的结果返回指向菜单的句柄,然后传给函数CreateWindowEx刚返回的菜单句柄就可以了。windows sdk编程系列文章 - 再谈菜单的动态加载2008-04-09 22:35上节课我们讲述的是菜单静态加载的办法,除此之外菜单还可以通过API在程序中动态的创建和加载。理论:创建普通菜单步骤如下:1)创建菜单 如:CreateMenu2) 添加菜单项 如:AppendMenu3)加载菜单 LoadMenu4)设置菜单到窗口 SetMenu5)处理菜单响应6)消除菜单 DestroyMenu创建右键菜单的步骤如下:1)创建菜单 如:CreateMenu2) 添加菜单项 如:AppendMenu3)使用TrackPopupMenu加载菜单。4)处理菜单响应5)消除菜单 DestroyMenu当然,如果你选择在已有菜单上进行编辑的话,也是可以的,就省略了其中的一些步骤。本节的例子就是在已有的菜单里面添加自己定义的菜单项。对于右键菜单你也可以选择已有的菜单中的一栏作为弹出菜单。使用菜单后,要涉及清除的问题,和窗口相连的菜单句柄在窗口摧毁的时候会由Windows自动释放,不需要手工释放,但没有和窗口相连的菜单就要由程序自己来释放了,方法是使用DestroyMenu函数,比如没有和窗口相连而仅用TrackPopupMenu弹出的菜单句柄。本例中,我们使用的是窗口关联的菜单句柄,因此我们不需要调用DestroyMenu消除菜单资源。菜单消息:当用户选择一个菜单项时,windwos通常向窗口过程发送几个不同的消息。在大多数情况下,你的程序可以忽略大部分的消息,只需要把他们传递给DefWindowProc即可。1)WM_INITMENU 消息,wParam :主菜单句柄, lParam : 0这个消息是当一个菜单将要激活时发出。当用户点击菜单栏上的项或者 使用菜单键选择 。这个消息允许应用程序在显示之前修改菜单。可以在这时修改顶层菜单。2)WM_MENUSELECT: LOWORD(wParam): 选中项:菜单id或者弹出式菜单句柄。 HIWORD(wParam): 选择标志 lParam: 包含选中项的菜单句柄。 当用户选择某个菜单项时,这个消息就会被发送到菜单所属的窗口。 这个消息是一个菜单跟踪消息,wParam告诉你当前选中的是菜单中的哪一项,wParam的高位字中的“选择标志”可以是下列这些标志的组合: MF_GRAYED、MF_DISABLED、MF_CHECKED、MF_BITMAP、MF_POPUP、MF_HELP、MF_SYSMENU和 MF_MOUSESELECT. 如果你需要根据菜单项的选择来改变窗口客户区的内容,那么可以你可以使用这个消息。3)WM_INITMENUPOPUP: wParam: 弹出式菜单句柄 LOWORD(lParam):弹出式菜单索引 HIWORD(lParam):系统菜单为1,其他为0 如果要在弹出式菜单显示之前启用或者禁用菜单项,那么这个消息就很重要。4) WM_COMMAND: LOWORD(wParam): 菜单id HIWOED(wParam): 0 lParam: 0 如果这个消息是由子窗口控制产生,如button产生则:LOWORD(wParam): 控制ID HIWORD(lParam): 通知码 lParam: 子窗口句柄。如果这个消息是由子窗口或者快捷键产生,则通知码为1,由菜单产生,通知码为0。通过参数,可以区分这个消息的来源是来自于控件,快捷键还是菜单。5) WM_SYSCOMMAND: 类似于WM_COMMAND消息,只是WM_SYSCOMMAND表示用户从系统菜单中选择一个启动菜单项或者用户选择最大化,最小化,关闭按钮。 LOWORD(wParam): 菜单id HIWOED(wParam): 0 lParam: 0如果消息是由按鼠标产生的,LOWORD(wParam)和HIWORD(lParam)将包含鼠标光标的位置x,y屏幕坐标。对于windows预先定义的系统菜单项,用wParam表示。 SC_CLOSE,SC_MAXIMIZE,SC_MINIMIZE,SC_MOVE等等。对于已有菜单,我们可以使用GetSystemMenu,GetMenu ,GetSubMenu来获取菜单句柄。当需要更改菜单时,可以使用下面的API进行更改。 AppendMenu, DeleteMenu,InsertMenu,ModifyMenu,RemoveMenu等等。例子:接下来,我们看一个例子:(见光盘myMenu)Menu.rc/#include winuser.h/#define ICO_MAIN 0x1000 /图标/#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/ICO_MAIN ICON Main.ico/IDM_MAIN menu discardableBEGIN 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) ,HELP BEGIN menuitem 帮助主题(&H)tF1, IDM_HELP menuitem separator menuitem 关于本程序(&A).,IDM_ABOUT ENDEND/IDA_MAIN acceleratorsBEGIN VK_F1, IDM_HELP, VIRTKEY B, IDM_SETCOLOR,VIRTKEY,CONTROL,ALT F, IDM_SETFONT,VIRTKEY,ALTEND/main.cpp#include windows.h#define ICO_MAIN 0x1000 /图标/#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 0x4302char szClassName = Menu Example;char szCaptionMa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论