MFC Windows 程序设计 第四章 菜单

来源:互联网 发布:海迅开料软件 编辑:程序博客网 时间:2024/06/01 07:36

1、AppWizard 生成的工程,包含的头文件#include "Stdafx.h"必须放在第一行,因为VC忽略在#include "Stdafx.h" 之前的任何信息,stdafx.h为预编译头文件,编译后生成projectname.pch和stdAfx.obj,
   编译一次后就不用再编译了,而已加快程序编译速度,一般将不更改的头文件、c运行时头文件和其他静态类型头文件包含在里面。
2、基于视图的应用程序体系结构WM_PAINT和用户区鼠标消息、键盘消息处理程序都必须在视图中进行处理,所有在框架窗口使用OnSetFocus(焦点传递给视图)
   和重载OnCmdMsg(可以在框架窗口、视图、应用程序类中均可处理命令处理程序和更新处理程序)。
3、可以在VC6工作区的Resource View标签里直接编辑加速键、菜单、图标、对话框、字符串资源、版本信息,手工修改时,必须使用open as text 命令打开。
4、顶层菜单(无命令ID)、下拉式菜单、弹出式菜单、菜单项、系统菜单(Alt+空格可唤出),菜单项由menu item IDs(菜单ID)或command IDs(命令ID)唯一确定。
5、MFC类CMenu菜单类的成员m_hMenu持有菜单句柄,可以通过CMenu::TrackPopupMenu显示上下文菜单,CMenu::EnableMenuItem、DrawItem和MeasureItem。
6、可以调用CreateMenu、InsertMenu创建菜单,另一种是通过CMenu::LoadMenuIndirect创建,常用的是用rc资源文件定义,可以通过资源编辑器进行编辑,在应用程序运行时加载生成的菜单。
7、资源文件为二进制对象,由RC.exe编译链接到应用程序的exe文件中,包含菜单、图标、位图、字符串资源,由一个字符串或者整形ID唯一确定。
8、菜单项由#define语句定义,在afxres.h头文件中定义了一些常用的菜单项,自定义菜单项范围建议在0x8000-0xDFFF之间,菜单项使用POPUP定义顶级菜单,MenuItem定义菜单项,&定义与Alt一起
   使用的快捷键,SEPARATOR定义小横线分隔菜单项,使用(...)表示该项选中后还需要进一步输入,使用制表符(\t)分隔加速键,使文本对齐,使用Grayed使菜单项无效,使用CHECKED使菜单项复选。
9、菜单项加载 CFrameWnd::Create和CFrameWnd::LoadFrame和CMenu::LoadMenu,使用CMenu可以加载多个菜单。
10、菜单项命令响应:WM_INITMENU、WM_INITMENUPOPUB、WM_MENUSEECT、WM_COMMAND,用户选中菜单会发生WM_COMMAND命令,wParam参数低位保留盖菜单项的ID,MFC使用消息映射宏来处理菜单命令,
    命令处理程序:OM_COMMAND(ID_FILE_NEW, OnFileNew),命令处理程序可以随意命名,与消息处理程序名称固定不同,批量命令处理程序:ON_COMMAND_RANGE(ID_FIRST,ID_END,OnCommand)
    UI更新处理程序:ON_UPDATE_COMMAND_UI(COMMAND_ID,OnUpdateCommand);批量UI更新处理程序:ON_UPDATE_COMMAND_UI_RANGE(COMMAND_FIRST,COMMAND_END,OnUpdateCommand);
    更新处理程序使用CCmdUI的成员函数Enable、SetCheck、SetRadio、SetText更新菜单状态,CCMDUI.m_nID保存菜单项ID,命令处理程序和更新处理程序可同时处理下拉菜单和弹出的上下文菜单等多个地方。
11、加速键:ACCELERATORS也引发WM_COMMAND命令,可以通过CFrameWnd::LoadAccelTable加载加速键(使用宏MAKEINTRESOURCE将整形转换成字符串),LoadFrame也可以加载,如果加速键资源ID
    和菜单资源ID相同,则可以通过这个命令一起加载,CFrameWnd对加速键做了处理,如果继承自CWnd则必须与CFrameWnd一样对加速键做处理,使用加速键可以确保命令发生到主窗口而不是拥有
    输入焦点的子窗口,加速键可以脱离菜单使用。   
12、使用CMenu::CreateMenu(顶层菜单),CMenu::CreatePopMenu(子菜单),CMenu::AppendMenu(根据第一个参数来确定是添加菜单项(MF_STRING)还是将子菜单挂到顶层菜单上(MF_POPUP))来手工创建菜单,
    CMenu::Detach将顶层菜单与CMenu分离,函数结束后,顶层菜单不会消失,使用CMenu::AppendMenu,CMenu::InsertMenu,CMenu::ModifyMenu,CMenu::DeleteMunu,CMenu::RemoveMenu(会保留子菜单)
    来编辑菜单项,先通过CWnd::GetMenu来获取顶层菜单,CMenu::GetSubMenu可以获取子菜单,删除菜单时,可以通过位置(MF_BYPOSITION)和菜单ID(MF_BYCOMMAND)来进行,修改菜单时,如果
    修改的是子菜单,则第三个参数使用菜单句柄而不是菜单ID,句柄通过CMenu->m_hMenu获得。
    系统菜单通过GetSystemMenu来获得,参数为False时,指向系统菜单副本,参数为TRUE时,重置系统菜单,系统菜单命令在ON_WM_SYSCOMMAND(OnSysCommand)消息映射中执行,可以在此函数中对系统
    菜单做处理,第一个参数nID包含菜单ID,使用(nID & 0xFFF0)获取菜单ID。
13、图形菜单,在CMenu::AppendMenu参数中使用CBitMap位图指针,不过位图尺寸固定,不能随屏幕尺寸变化,使用自制菜单则没有此问题,自制菜单使用MF_OWNDERDRAW进行标识,
    模板不支持MF_OwnerDraw,使用CMenu::ModifyMenu实现传统菜单项到自制菜单项的转换,在自制菜单第一次显示时,会发生WM_MEASUREITEM消息,询问菜单项的尺寸,
    函数原型:afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis), LPMEASUREITEMSTRUCT中的CtlType为ODT_MENU表示为菜单,itemID为菜单项ID,itemWidth和itemHeight
    为高度和宽度,一般指定为lpmis->itemheight = ::GetSystemMetrics(SM_CYMENU)(系统菜单栏高度),宽度为高度的4倍。之后WM_DRAWITEM消息会发生,在此函数中画自制菜单
    函数原型:afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis),lpdis结构中的itemAction包含ODA_DRAWENTIRE时,重画所有菜单,ODA_SELECT加亮和不加亮显示,画部分菜单,
    itemState包含ODS_CHECKED、ODS_DISABLED、ODS_GRAYED、ODS_SELECTED,另外可以直接使用CMenu::MeasureItem和CMenu::DrawItem来重画菜单,在OnMenuChar消息处理函数中增加键盘快捷键。
14、使用嵌套的方式实现层叠菜单,在模板中勾选Pop-up选项,可添加层叠菜单,上下文菜单,在单击右键时,Windows会发生WM_CONTEXTMENU消息,可在对应的消息处理过程中实现右键菜单,右键菜单可
    通过CMenu::TrackPopupMenu函数来显示,函数原型:BOOL TrackPopupMenu(UINT nFlags, int x, int y, CWnd* pWnd LPRECT lpRect = NULL),nFlags包含TMP_LEFTALIGN以及TMP_LEFTBUTTON
    和TMP_RETURNCMD等标志,x、y表示屏幕坐标,pWnd确保窗口能收到菜单各种操作引发的消息(鼠标下面的窗口),上下文菜单可通过资源加载方式和CMenu成员函数来实现,TMP_LEFTALIGN表示对齐方式,TMP_LEFTBUTTON
    表示使用鼠标左右键激活菜单,TMP_RETURNCMD表示选中菜单项的命令ID,默认情况下如果菜单项没有命令和更新处理程序,菜单项则无效,如果使用TMP_RETURNCMD,则必须将框架窗口的
    m_bAutoMenuEnable设置为FALSE。
15、视图创建时,传递AFX_IDW_PANE_FIRST表明活动窗口ID,Windows不允许直接把位图“位块传送”(blit)到显示表面,必须先选入内存dc,再把他复制到屏幕DC中,使用OBM_CHECK位图ID,
    必须在StdAfx.h头文件中包含afxwin.h语句之前增加#define OEMRESOURCE,在编辑菜单时,可以使用ID_COLOR_RED=10000,指定菜单ID,使用Range宏时,菜单必须是连续的,框架窗口是菜单的所有者
    接收WM_MEASUREITEM和WM_DRAWITEM消息,自制上下文菜单弹出时,也需发送到框架窗口。   
原创粉丝点击