孙鑫VC讲座笔记6菜单编程_第1页
孙鑫VC讲座笔记6菜单编程_第2页
孙鑫VC讲座笔记6菜单编程_第3页
孙鑫VC讲座笔记6菜单编程_第4页
孙鑫VC讲座笔记6菜单编程_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

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

文档简介

1、1,弹出菜单(Pop-up)是不能用来作命令响应的。1,弹出菜单(Pop-up)是不能用来作命令响应的。2,MFC中菜单项消息如果利用ClassWizard来对菜单项消息分别在上述四个类中进行响应,则菜单消息传递顺序:View类-Doc类-CMainFrame类-App类。菜单消息一旦在其中一个类中响应则不再在其它类中查找响应函数。具体:当点击一个菜单项的时候,最先接受到菜单项消息的是CMainFrame框架类,CMainFrame框架类将会把菜单项消息交给它的子窗口View类,由View类首先进行处理;如果View类检测到没对该菜单项消息做响应,则View类把菜单项消息交由文档类Doc类进行

2、处理;如果Doc类检测到Doc类中也没对该菜单项消息做响应,则Doc类又把该菜单项消息交还给View类,由View类再交还给CMainFrame类处理。如果CMainFrame类查看到CMainFrame类中也没对该消息做响应,则最终交给App类进行处理。3,消息的分类:标准消息,命令消息,通告消息。标准消息:除WM_COMMAND之外,所有以WM_开头的消息。命令消息:来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。通告消息:由控件产生的消息,例如,按钮的单击,列表

3、框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。说明:1)从CWnd派生的类,都可以接收到标准消息。2)从CCmdTarget派生的类,都可以接收到命令消息和通告消息。4,一个菜单拦可以有若干个子菜单,一个子菜单又可以有若干个菜单项等。对菜单栏的子菜单由左至右建立从0开始的索引。对特定子菜单的菜单项由上至下建立了从0开始的索引。访问子菜单和菜单项均可以通过其索引或标识(如果有标识的话)进行。相关重要函数:CMenu* GetMenu( ) ;/CWnd:GetMenu得到窗口菜单栏对象指针。CMenu* GetSubMenu

4、( ) ;/CMenu:GetSubMenu获得指向弹出菜单对象指针UINT CheckMenuItem( );/CMenu:CheckMenuItem Adds check marks to or removes check marks from menu items in the pop-up menu. BOOL SetDefaultItem();/CMenu:SetDefaultItem Sets the default menu item for the specified menu.BOOL SetMenuItemBitmaps( );/CMenu:SetMenuItemBitma

5、ps 设置位图标题菜单。UINT EnableMenuItem();/CMenu:EnableMenuItem使菜单项有效,无效,或变灰。BOOL SetMenu( CMenu* pMenu );/CWnd:SetMenu在当前窗口上设置新菜单或移除菜单。HMENU Detach( );/CMenu:Detach Detaches a Windows menu from a CMenu object and returns the handle. 说明:1)在计算子菜单菜单项的索引的时候,分隔栏符也算索引的。2)int GetSystemMetrics()获取系统信息度量。可以用它来获取菜单标

6、题的尺寸从而设置位图标题菜单中位图的大小。3)在MFC中MFC为我们提供了一套命令更新机制,所有菜单项的更新都是由这套机制来完成的。所以要想利用CMenu:EnableMenuItem来自己控制菜单使用或不使用变灰等,必须要在CMainFrame的构造函数中将变量m_bAutoMenuEnable设置为FALSE。4)Create a CMenu object on the stack frame as a local, then call CMenus member functions to manipulate the new menu as needed. Next, call CWnd

7、:SetMenu to set the menu to a window, followed immediately by a call to the CMenu objects Detach member function. The CWnd:SetMenu member function sets the windows menu to the new menu, causes the window to be redrawn to reflect the menu change, and also passes ownership of the menu to the window. T

8、he call to Detach detaches the HMENU from the CMenu object, so that when the local CMenu variable passes out of scope, the CMenu object destructor does not attempt to destroy a menu it no longer owns. The menu itself is automatically destroyed when the window is destroyed.5)You can use the LoadMenuI

9、ndirect member function to create a menu from a template in memory, but a menu created from a resource by a call to LoadMenu is more easily maintained, and the menu resource itself can be created and modified by the menu editor.6)EXAMPLE:CMenu menu;/定义为局部对象menu.LoadMenu(IDR_MAINFRAME);SetMenu(&menu)

10、;menu.Detach();/ 这里menu对象作为一个局部对象。使用Detach()从menu对象中分离窗口菜单句柄,从而当menu对象析构的时候窗口菜单资源不随之销毁。5,命令更新机制:菜单项状态的维护是依赖于CN_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,MFC就在其中创建一个CCmdUI对象。在后台操作系统发出WM_INITMENUPOPUP消息,然后由MFC的基类如CFrameWnd接管并创建一个CCmdUI对象和第一个菜单项相关联,调用对象成员函数DoUpdate()(注:这个函数在MSDN中没有找到说明)发出CN_UPDATE_

11、COMMAND_UI消息,这条消息带有指向CCmdUI对象的指针。此后同一个CCmdUI对象又设置为与第二个菜单项相关联,这样顺序进行,直到完成所有菜单项。更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用于永久显示的顶级菜单项目。说明:1)可以手工或用ClassWizard来给菜单项添加UPDATE_COMMAND_UI消息响应,利用响应函数中传进来的CCmdUI对象指针可完成设置菜单项可使用,不可使用,变灰,设置标记菜单等操作。6,如果要想让工具栏上的某个图标与菜单项的某个菜单相关联,只需要将图标的ID设置为该菜单项的ID。工具栏图标的索引记数顺序是:从做至右从0开始,分隔符也算索

12、引号。7,利用向项目中添加VC的POPMENU控件:Project-Add to Project-Components and Controls.系统增加的内容:A,一个菜单资源;B,在派生View类中增加了OnContextMenu()函数说明:1)CWnd:OnContextMenu Called by the framework when the user has clicked the right mouse button (right clicked) in the window. You can process this message by displaying a contex

13、t menu using the TrackPopupMenu.2)BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL );/CMenu:TrackPopupMenu Displays a floating pop-up menu at the specified location and tracks the selection of items on the pop-up menu. A floating pop-up menu can appear anywhere on th

14、e screen.8,利用调用TrackPopupMenu函数,手工添加弹出菜单:1)用资源管理器添加一个菜单资源2)在鼠标右键消息响应函数中,加载菜单资源,并获得要显示的子菜单指针,并用该指针调用TrackPopupMenu函数便完成任务(但要注意:鼠标响应函数传进来的坐标是客户区坐标,而TrackPopupMenu函数中使用的是屏幕坐标,在调用TrackPopupMenu前要调用ClientToScreen客户区坐标到屏幕坐标的转换)事例代码:CMenu menu;menu.LoadMenu(IDR_MENU1);CMenu *pPopup=menu.GetSubMenu(0);Clien

15、tToScreen(&point);pPopup-TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,this);说明:CWnd:ClientToScreen(.);/将一个坐标点或一个矩形区域坐标转换成屏幕坐标。CMenu:TrackPopupMenu(.);/在指定位置以指定的方式显示弹出菜单。CWnd:ScreenToClient(.);/Converts the screen coordinates of a given point or rectangle on the display to client

16、coordinates. 9,当弹出菜单属于框架窗口的时候(可在TrackPopupMenu函数参数中设置),弹出菜单上的消息,在路由的时候,仍然遵循View-DOC-MainFrame-APP的响应顺序。10,动态菜单编程:所有的资源对象都有一个数据成员保存了资源的句柄。CMenu:AppendMenu /Appends a new item to the end of a menu.CMenu:CreatePopupMenu /Creates an empty pop-up menu and attaches it to a CMenu object.CMenu:InsertMenu /I

17、nserts a new menu item at the position specified by nPosition and moves other items down the menu. CMenu:GetSubMenu /Retrieves a pointer to a pop-up menu.CWnd:GetMenu /Retrieves a pointer to the menu for this window.CMenu:DeleteMenu /Deletes an item from the menu. 11,手动给动态菜单项添加响应函数:在Resource.h中可以添加资

18、源的ID在头文件中写消息函数原型在代码文件中添加消息映射和添加消息响应函数说明:可以先创建一个临时的菜单项,设置它的ID和动态菜单项的一致,然后对它用向导进行消息响应,然后删除临时菜单。再在代码文件中把消息映射放到宏外(注意一定要放到宏外面,因为CLASSWIZARD发现菜单删除了,同时要把其宏对里的消息映射也删除掉的)12,CWnd:DrawMenuBar /Redraws the menu bar. If a menu bar is changed after Windows has created the window, call this function to draw the ch

19、anged menu barCWnd:GetParent /get a pointer to a child windows parent window (if any). CWnd:Invalidate /注意其参数的作用13,集合类:CStringArray,CStringArray,CDWordArray,CPtrArray,CStringArray,CUIntArray,CWordArray其中成员函数:CArray:GetAt CArray:Add14,命令消息是到OnCommand函数的时候完成路由的。由于CWnd:OnCommand 是个虚函数,可以在框架类中重写OnComman

20、d函数,从而可以截获菜单消息使它不再往下(VIEW类)路由。例:BOOL CMainFrame:OnCommand(WPARAM wParam, LPARAM lParam) / TODO: Add your specialized code here and/or call the base classint MenuCmdId=LOWORD(wParam);/取命令IDCMenu2View *pView=(CMenu2View*)GetActiveView();/获取当前VIEW类指针if(MenuCmdId=IDM_PHONE1 & MenuCmdIdm_strArray.GetSize

21、()/消息范围判断 CClientDC dc(pView); dc.TextOut(0,0,pView-m_strArray.GetAt(MenuCmdId-IDM_PHONE1); return TRUE; /函数返回,避免调用CFrameWnd:OnCommand函数,在CFrameWnd:OnCommand中截获的消息会交由VIEW类处理return CFrameWnd:OnCommand(wParam, lParam); /调用基类OnCommand函数,在CFrameWnd:OnCommand中截获的消息会交由VIEW类处理MSDN说明:virtual BOOL OnCommand(

22、 WPARAM wParam, LPARAM lParam );/The framework calls this member function when the user selects an item from a menu, when a child control sends a notification message, or when an accelerator keystroke is translated. OnCommand processes the message map for control notification and ON_COMMAND entries,

23、 and calls the appropriate member function. Override this member function in your derived class to handle the WM_COMMAND message. An override will not process the message map unless the base class OnCommand is called.15,LOWORD与HIWORD宏WORD LOWORD( DWORD dwValue / value from which low-order word is re

24、trieved);WORD HIWORD( DWORD dwValue / value from which high-order word is retrieved);/The LOWORD macro retrieves the low-order word from the given 32-bit value. /The HIWORD macro retrieves the high-order word from the given 32-bit value. 16,CFrameWnd:GetActiveView CView* GetActiveView( ) const;/获取当前

25、视窗口指针(单文档框架中)17,源文件是单独参与编译的。菜单消息一旦在其中一个类中响应则不再在其它类中查找响应函数。具体:当点击一个菜单项的时候,最先接受到菜单项消息的是CMainFrame框架类,CMainFrame框架类将会把菜单项消息交给它的子窗口View类,由View类首先进行处理;如果View类检测到没对该菜单项消息做响应,则View类把菜单项消息交由文档类Doc类进行处理;如果Doc类检测到Doc类中也没对该菜单项消息做响应,则Doc类又把该菜单项消息交还给View类,由View类再交还给CMainFrame类处理。如果CMainFrame类查看到CMainFrame类中也没对该消

26、息做响应,则最终交给App类进行处理。3,消息的分类:标准消息,命令消息,通告消息。标准消息:除WM_COMMAND之外,所有以WM_开头的消息。命令消息:来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。通告消息:由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。说明:1)从CWnd派生的类,都可以接收到标准消息。2)从CCmdTarget派生的类,都可以接收到

27、命令消息和通告消息。4,一个菜单拦可以有若干个子菜单,一个子菜单又可以有若干个菜单项等。对菜单栏的子菜单由左至右建立从0开始的索引。对特定子菜单的菜单项由上至下建立了从0开始的索引。访问子菜单和菜单项均可以通过其索引或标识(如果有标识的话)进行。相关重要函数:CMenu* GetMenu( ) ;/CWnd:GetMenu得到窗口菜单栏对象指针。CMenu* GetSubMenu( ) ;/CMenu:GetSubMenu获得指向弹出菜单对象指针UINT CheckMenuItem( );/CMenu:CheckMenuItem Adds check marks to or removes c

28、heck marks from menu items in the pop-up menu. BOOL SetDefaultItem();/CMenu:SetDefaultItem Sets the default menu item for the specified menu.BOOL SetMenuItemBitmaps( );/CMenu:SetMenuItemBitmaps 设置位图标题菜单。UINT EnableMenuItem();/CMenu:EnableMenuItem使菜单项有效,无效,或变灰。BOOL SetMenu( CMenu* pMenu );/CWnd:SetMe

29、nu在当前窗口上设置新菜单或移除菜单。HMENU Detach( );/CMenu:Detach Detaches a Windows menu from a CMenu object and returns the handle. 说明:1)在计算子菜单菜单项的索引的时候,分隔栏符也算索引的。2)int GetSystemMetrics()获取系统信息度量。可以用它来获取菜单标题的尺寸从而设置位图标题菜单中位图的大小。3)在MFC中MFC为我们提供了一套命令更新机制,所有菜单项的更新都是由这套机制来完成的。所以要想利用CMenu:EnableMenuItem来自己控制菜单使用或不使用变灰等,

30、必须要在CMainFrame的构造函数中将变量m_bAutoMenuEnable设置为FALSE。4)Create a CMenu object on the stack frame as a local, then call CMenus member functions to manipulate the new menu as needed. Next, call CWnd:SetMenu to set the menu to a window, followed immediately by a call to the CMenu objects Detach member funct

31、ion. The CWnd:SetMenu member function sets the windows menu to the new menu, causes the window to be redrawn to reflect the menu change, and also passes ownership of the menu to the window. The call to Detach detaches the HMENU from the CMenu object, so that when the local CMenu variable passes out

32、of scope, the CMenu object destructor does not attempt to destroy a menu it no longer owns. The menu itself is automatically destroyed when the window is destroyed.5)You can use the LoadMenuIndirect member function to create a menu from a template in memory, but a menu created from a resource by a c

33、all to LoadMenu is more easily maintained, and the menu resource itself can be created and modified by the menu editor.6)EXAMPLE:CMenu menu;/定义为局部对象menu.LoadMenu(IDR_MAINFRAME);SetMenu(&menu);menu.Detach();/ 这里menu对象作为一个局部对象。使用Detach()从menu对象中分离窗口菜单句柄,从而当menu对象析构的时候窗口菜单资源不随之销毁。5,命令更新机制:菜单项状态的维护是依赖于C

34、N_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,MFC就在其中创建一个CCmdUI对象。在后台操作系统发出WM_INITMENUPOPUP消息,然后由MFC的基类如CFrameWnd接管并创建一个CCmdUI对象和第一个菜单项相关联,调用对象成员函数DoUpdate()(注:这个函数在MSDN中没有找到说明)发出CN_UPDATE_COMMAND_UI消息,这条消息带有指向CCmdUI对象的指针。此后同一个CCmdUI对象又设置为与第二个菜单项相关联,这样顺序进行,直到完成所有菜单项。更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用于永

35、久显示的顶级菜单项目。说明:1)可以手工或用ClassWizard来给菜单项添加UPDATE_COMMAND_UI消息响应,利用响应函数中传进来的CCmdUI对象指针可完成设置菜单项可使用,不可使用,变灰,设置标记菜单等操作。6,如果要想让工具栏上的某个图标与菜单项的某个菜单相关联,只需要将图标的ID设置为该菜单项的ID。工具栏图标的索引记数顺序是:从做至右从0开始,分隔符也算索引号。7,利用向项目中添加VC的POPMENU控件:Project-Add to Project-Components and Controls.系统增加的内容:A,一个菜单资源;B,在派生View类中增加了OnCon

36、textMenu()函数说明:1)CWnd:OnContextMenu Called by the framework when the user has clicked the right mouse button (right clicked) in the window. You can process this message by displaying a context menu using the TrackPopupMenu.2)BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect

37、= NULL );/CMenu:TrackPopupMenu Displays a floating pop-up menu at the specified location and tracks the selection of items on the pop-up menu. A floating pop-up menu can appear anywhere on the screen.8,利用调用TrackPopupMenu函数,手工添加弹出菜单:1)用资源管理器添加一个菜单资源2)在鼠标右键消息响应函数中,加载菜单资源,并获得要显示的子菜单指针,并用该指针调用TrackPopup

38、Menu函数便完成任务(但要注意:鼠标响应函数传进来的坐标是客户区坐标,而TrackPopupMenu函数中使用的是屏幕坐标,在调用TrackPopupMenu前要调用ClientToScreen客户区坐标到屏幕坐标的转换)事例代码:CMenu menu;menu.LoadMenu(IDR_MENU1);CMenu *pPopup=menu.GetSubMenu(0);ClientToScreen(&point);pPopup-TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,this);说明:CWnd:Clien

39、tToScreen(.);/将一个坐标点或一个矩形区域坐标转换成屏幕坐标。CMenu:TrackPopupMenu(.);/在指定位置以指定的方式显示弹出菜单。CWnd:ScreenToClient(.);/Converts the screen coordinates of a given point or rectangle on the display to client coordinates. 9,当弹出菜单属于框架窗口的时候(可在TrackPopupMenu函数参数中设置),弹出菜单上的消息,在路由的时候,仍然遵循View-DOC-MainFrame-APP的响应顺序。10,动态菜

40、单编程:所有的资源对象都有一个数据成员保存了资源的句柄。CMenu:AppendMenu /Appends a new item to the end of a menu.CMenu:CreatePopupMenu /Creates an empty pop-up menu and attaches it to a CMenu object.CMenu:InsertMenu /Inserts a new menu item at the position specified by nPosition and moves other items down the menu. CMenu:GetS

41、ubMenu /Retrieves a pointer to a pop-up menu.CWnd:GetMenu /Retrieves a pointer to the menu for this window.CMenu:DeleteMenu /Deletes an item from the menu. 11,手动给动态菜单项添加响应函数:在Resource.h中可以添加资源的ID在头文件中写消息函数原型在代码文件中添加消息映射和添加消息响应函数说明:可以先创建一个临时的菜单项,设置它的ID和动态菜单项的一致,然后对它用向导进行消息响应,然后删除临时菜单。再在代码文件中把消息映射放到宏外

42、(注意一定要放到宏外面,因为CLASSWIZARD发现菜单删除了,同时要把其宏对里的消息映射也删除掉的)12,CWnd:DrawMenuBar /Redraws the menu bar. If a menu bar is changed after Windows has created the window, call this function to draw the changed menu barCWnd:GetParent /get a pointer to a child windows parent window (if any). CWnd:Invalidate /注意其参数的作用13,集合类:CStringArray,CStringArray,CDWordArray,CPtrArray,CStringArray,CUIntArray,CWordArray其中成员函数:CArray:GetAt CArray:Add14,命令消息是到OnCommand函数的时候完成路由的。由于CWnd:OnCommand 是个虚函数,可以在框架类中重写OnCommand函数,从而可以截获菜单消息使它不再往下(VIEW类)路由。例:BOOL CMainFrame:OnCommand(WPARAM wParam, LPARAM lParam) / TODO: A

温馨提示

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

评论

0/150

提交评论