如何为 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。
我用这一行初始化我的 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。