Menu 如何为DoctTemplate自定义绘制MFC菜单

Menu 如何为DoctTemplate自定义绘制MFC菜单,menu,mfc,ownerdrawn,Menu,Mfc,Ownerdrawn,我使用以下行初始化MFC应用程序的视图: CSingleDocTemplate pDocTemplate( new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CMyDataView) ) ); AddDocTemplate(pDocTemplate); IDR_MAINFRAME是

我使用以下行初始化MFC应用程序的视图:

CSingleDocTemplate pDocTemplate(
   new CSingleDocTemplate(
      IDR_MAINFRAME,
      RUNTIME_CLASS(CMyDoc),
      RUNTIME_CLASS(CMainFrame),
      RUNTIME_CLASS(CMyDataView)
   )
);
AddDocTemplate(pDocTemplate);
IDR_MAINFRAME是我的主菜单的标识符。 自定义绘制此菜单的最佳方法是什么?我已经有了一个从CMenu派生的类,它对contextmenus做了很好的工作。不同之处在于我自己创建了contextmenus,而这个菜单是由框架创建的

要覆盖主菜单,我尝试了:

customMenu.LoadMenu(IDR_MAINFRAME);
customMenu.ChangeToOwnerDraw(customMenu, *m_MenuProperties);
m_pMainWnd->SetMenu(&customMenu);
,但不知何故,对于第一个项目(即弹出窗口),在customMenu类实例化中没有触发MeasureItem,从而导致单击一个小正方形,不同按钮的文本相互重叠


菜单项按预期显示,但对于子菜单(以及子菜单和子菜单)的每次弹出,样式错误(读取:MeasureItem未调用)。对于sub、subsub和SubSubMenus中的MENUITEMS,我收到来自框架的MeasureItem调用。

感谢您的评论。原来我的CMenu派生类中有一个bug。我使用了来自的代码示例。 在那里,ModifyMenu发送弹出菜单的ID 0,而不是弹出菜单的真实ID
void CWnd::OnMeasureItem(…)
搜索要测量的菜单,但未找到任何内容(它查找0,因为ModifyMenu告诉他这样做,但实际的弹出菜单具有其他ID)并返回NULL。如果菜单中有分隔符,它将找到一个要测量的菜单,因为分隔符的ID为0

解决办法如下:

  • 不要发送0,而是发送
    重新解释_cast(menu.GetSubMenu(i)->GetSafeHmenu())
    作为ID(
    AFX\u静态CMenu*AFXAPI\u AfxFindPopupMenuFromID(CMenu*pMenu,UINT-nID)
    在wincore.cpp中检查ID的方式相同)
  • 此外,添加标志MF_弹出窗口

我认为MFC会动态创建文档(子)菜单。您可以尝试截取WM_INITMENUPOPUP并从那里定制它们。您的
CMainFrame
是从哪个类派生的?如果它是
CFrameWndEx
|
CMDIFrameWndEx
并且您使用的是
CMFCMenubar
,则很可能无法按照您想要的方式工作,因为MFC功能包覆盖了正常菜单的行为。