1.创建菜单
a.编程方法,用CreateMenu,InsertMenu和其它CMenu函数
b.将一系列定义菜单内容的数据结构初始化,用CMenu::LoadMenuIndirect创建。
c.创建菜单资源,在程序运行时,加载生成的菜单。
.RC,菜单项正文中的”&”定义了和Alt键一起使用的快捷键,显示和选中子菜单项。
同一菜单下,多个菜单项快捷键相同,快捷方式在菜单项间循环,按下Enter来选中某一项。
菜单项ID有效范围:1–0xEFFF
建议的区间划分:
区间 | 适合 |
---|---|
0x1-0x7FFF | Application |
0x8000-0xDFFF | Application |
0xE000-0XEFFF | MFC |
菜单项中跟在制表符后的文本,如 Open\t Ctrl+O表示加速键。加速键一般为若干键组合,组合触发时,选中菜单项。
2.加载并显示菜单
a.通过CWnd::Create把菜单挂接到窗口。
b.virtual BOOL LoadFrame(
UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
CWnd* pParentWnd = NULL,
CCreateContext* pContext = NULL
);
c.
CMenu menu;
menu.LoadMenu(nID);
SetMenu(&menu);// SetMenu后一般调用 CWnd::DrawMenuBar()来重画菜单栏
menu.Detach(); // 使menu析构时不会销毁菜单
挂接到窗口的菜单在窗口被销毁时,会被自动销毁。
3.菜单消息
打开下拉菜单,菜单挂接的窗口收到 WM_INITMENU.
显示子菜单前,菜单挂接的窗口收到 WM_INITPOPUP
加亮条上下移动时,菜单挂接的窗口收到 WM_MENUSELECT
用户选中某项时,菜单挂接的窗口收到 WM_COMMAND
4.菜单的键盘加速键
对CFrameWnd使用LoadFrame时,已经做好了对加速键支持。
对从CWnd派生的用户窗口,要使用加速键:
1.给派生类添加数据成员 HACCEL m_hAccelTable;
2.在应用程序开始时,m_hAccelTable = ::LoadAccelerators(MAKEINTRESOURCE(nID));
3.处理 窗口的PreTranslateMessage
BOOL CWndxxx::PreTranslateMessage(MSG* pMsg)
{
if(CWnd::PreTranslateMessage(pMsg))
{
return TRUE;
}
if(m_hAccelTable)
{
return ::TranslateAccelrator(m_hWnd, m_hAccelTable, pMsg);
}
return FALSE;
}
StdAfx.h预编译头文件,适合放置应用程序使用的库的头文件
Visual C++忽略 #include “stdafx.h”前的语句。
5.菜单进阶
1.编程方式创建
CMenu main;
main.CreateMenu();
CMenu popup;
popup.CreatePopupMenu();
popup.AppendMenu(nFlags, nID, "xxx");
main.AppendMenu(nFlags, nID, "xxx");
SetMenu(&main);
popup.Detach();
main.Detach();
DrawMenuBar();
CMenu:
AppendMenu
InsertMenu
ModifyMenu
DeleteMenu
RemoveMenu
确定菜单项时, 通过ID确认,需知道菜单项任意上层菜单项指针。通过位置确认,须知道菜单项所在直接上级菜单指针。
CWnd::GetMenu
CMenu::GetSubMenu
CWnd::GetSystemMenu // 获取指向系统菜单的指针
往系统菜单添加的菜单项的ID低4位需要是0。
2.自绘菜单
图形菜单,通过CMenu::AppendMenu结合位图实现
自绘
包含自制菜单项的菜单显示时,Windows发给菜单所有者一个WM_DRAWITEM。
包含自制菜单项的菜单首次显示前,Windows给菜单所有者一个WM_MEASUREITEM
如子菜单包含5个自制菜单项,则子菜单首次显示时,挂接的窗口收到5个 WM_MEASUREITEM和WM_DRAWITEM。以后每次显示时,收到5个WM_DRAWITEM。
typedef struct tagMEASUREITEMSTRUCT {
UINT CtlType; // 自制菜单位ODT_MENU
UINT CtlID;// 自制菜单无
UINT itemID;// 菜单项ID
UINT itemWidth;// 尺寸信息
UINT itemHeight;//尺寸信息
ULONG_PTR itemData;// 自制菜单无
} MEASUREITEMSTRUCT, NEAR *PMEASUREITEMSTRUCT, FAR *LPMEASUREITEMSTRUCT;
typedef struct tagDRAWITEMSTRUCT {
UINT CtlType; // 对自制菜单 ODT_MENU
UINT CtlID;// 对自制菜单无
UINT itemID;// 自制菜单的菜单项ID
UINT itemAction;//
UINT itemState;// ODS_CHECKED/ODS_DISABLED/ODS_GRAYED/ODS_SELECTED
HWND hwndItem;// 对自制菜单为,包含此菜单项菜单句柄
HDC hDC;// 关联的设备描述表句柄
RECT rcItem;// 尺寸信息
ULONG_PTR itemData;//
} DRAWITEMSTRUCT, NEAR *PDRAWITEMSTRUCT, FAR *LPDRAWITEMSTRUCT;
CFrameWnd::m_bAutoMenuEnable,此项为TRUE时,CFrameWnd菜单的菜单项没关联到 ON_COMMAND时自动变灰。
自制菜单项没键盘快捷键,可通过 OnMenuChar,实现类似功能。
3.上下文菜单
WM_CONTEXTMENU // 窗口内右键单击时,产生此消息
显示上下文菜单:
BOOL TrackPopupMenu(
UINT nFlags, // 涉及XY对应位置的解释,要不要给拥有窗口发通知,返回值,动画
int x,
int y,
CWnd* pWnd,
LPCRECT lpRect = 0// 无意义
);