1.关于为毛要使用detach()函数
CMenu menu; menu.LoadMenu(IDR_MAINFRAME); SetMenu(&menu); menu.Detach(); //如果不加这句,等着崩溃吧
detach就是把windows资源和C++对象分离开来,如果你不detach,由于menu对象是局部对象,退出函数后menu就自我销毁了。他的 析构函数会强迫销毁那个菜单系统资源,相当于调用诸如DeleteMenu(hMenu)之类的函数(注意区分C++对象和系统菜单对象),detach之后,c++对象还是会析构,但是系统资源则不会被销毁!
2.获取菜单ID
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
ON_COMMAND(ID_32772,OnOpen)
END_MESSAGE_MAP()
void CMainWindow::OnOpen(){ UINT nID=(UINT)LOWORD(GetCurrentMessage()->wParam); CString s; s.Format(_T("%d"),nID); ::AfxMessageBox(s); }
3.一组连续命令ID
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd) ON_COMMAND_RANGE(AAA,BBB,OnOpen) //ID范围从AAA到BBB END_MESSAGE_MAP() void CMainWindow::OnOpen(UINT nID){ CString s; s.Format(_T("%d"),nID); ::AfxMessageBox(s); }
4.右键弹出式菜单
void CMdiView::OnRButtonDown(UINT nFlags, CPoint point) { CView::OnRButtonDown(nFlags, point); CMenu* menu_bar = AfxGetMainWnd()->GetMenu(); CMenu* file_menu = menu_bar->GetSubMenu(0); ASSERT(file_menu); ClientToScreen(&point); file_menu->TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, point.x, point.y, this); }
5.OnContextMenu和OnRButtonDown区别
当鼠标压下,鼠标弹起两个消息依次发生,才会发生OnContextMenu消息. 你在OnRButtonDown里用一个Message输出文字,则后面的鼠标弹起消息被MessageBox接受了.故OnContextMenu没有被调用. ------------------------------------------------------------------------------------------------- OnRButtonDown就是鼠标右键消息. 但 "ContextMenu "不一定是鼠标右键触发的. 比如按windows键盘上的属性键,或按shift+F10都是ContextMenu. 所以, 不要使用OnRButtonDown取代OnContextMenu
void CMainWindow::OnContextMenu(CWnd* pWnd, CPoint point)
{
CPoint pt=point;
CMenu menu;
CMenu* PopupMenu=NULL;
ScreenToClient(&pt);
//加载菜单
menu.LoadMenu(IDR_MAINFRAME);
PopupMenu=menu.GetSubMenu(1);
PopupMenu->TrackPopupMenu(TPM_RIGHTBUTTON | TPM_LEFTALIGN,point.x,point.y,this);
}