如何为 DocTemplate 自定义绘制 MFC 菜单

Howto custom-draw an MFC Menu for a DocTemplate

我用这一行初始化我的 MFC 应用程序的视图:

CSingleDocTemplate pDocTemplate(
   new CSingleDocTemplate(
      IDR_MAINFRAME,
      RUNTIME_CLASS(CMyDoc),
      RUNTIME_CLASS(CMainFrame),
      RUNTIME_CLASS(CMyDataView)
   )
);
AddDocTemplate(pDocTemplate);

IDR_MAINFRAME 是我的主菜单的标识符。 自定义绘制此菜单的最佳方法是什么?我已经有一个派生自 CMenu 的 class,它在上下文菜单方面做得很好。不同的是我自己创建上下文菜单,而这个菜单是由框架创建的。

要覆盖主菜单,我试过:

customMenu.LoadMenu(IDR_MAINFRAME);
customMenu.ChangeToOwnerDraw(customMenu, *m_MenuProperties);
m_pMainWnd->SetMenu(&customMenu);

,但不知何故,对于第一个项目(即 POPUP),MeasureItem 未在 customMenu class 实例化中触发,导致点击一个小方块,不同按钮的文本相互重叠.

MENUITEM 按预期显示,但对于子菜单(以及子子菜单和子子子菜单)的每个 POPUP,样式错误(阅读:未调用 MeasureItem)。对于 sub、subsub 和 subsubsubmenus 中的 MENUITEMS,我收到来自框架的 MeasureItem 调用。

感谢您发表评论。原来我的 CMenu 派生 class 中有一个错误。我使用了 codeguru 中的代码示例。 在那里,ModifyMenu 为 POPUP 菜单发送 ID 0,而不是 POPUP 菜单的真实 ID。 void CWnd::OnMeasureItem(...) 搜索要测量的菜单,但一无所获(它寻找 0,因为 ModifyMenu 告诉他这样做,但实际的 POPUP 菜单有一些其他 ID)和 returns NULL。如果您的菜单中有一个 SEPARATOR,它会找到一个要测量的菜单,因为该分隔符的 ID 为 0。

解决方法如下:

  • 不发送 0,而是发送 reinterpret_cast<UINT>(menu.GetSubMenu(i)->GetSafeHmenu()) 作为 ID(wincore.cpp 中的 AFX_STATIC CMenu* AFXAPI _AfxFindPopupMenuFromID(CMenu* pMenu, UINT nID) 检查 ID 的方式相同)。
  • 此外,添加标志 MF_POPUP。