MFC 菜单栏杂记

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);  
}
原文地址:https://www.cnblogs.com/duyy/p/3777873.html