【发布时间】:2012-10-12 13:51:37
【问题描述】:
我已经定义了一个所有者绘制的菜单类。该类考虑了this article 中定义的系统菜单的MeasureItem 问题(即根据菜单是否为系统菜单调整自定义测量值)。但是我遇到的问题是在正确的时间对系统菜单进行子类化。
目前我已使用以下两个代码 sn-ps 尝试对其进行子类化(在覆盖的 CFrameWnd::LoadFrame 中):
-
尝试1:
mSysMenu是CMenu的子类,它还重写了Attach自动设置菜单为所有者绘制(bool参数只是传递来通知它是否是系统菜单)mSysMenu.Attach(GetSystemMenu(FALSE)->GetSafeHmenu(), true);当我右键单击任务栏按钮时,此选项失败,在
wincore.cpp(CWnd::OnMeasureItem)中生成 3 个断言,以及一个丑陋、变形的所有者绘制菜单 - 与_AFX_THREAD_STATE类有关。 但是,当我从OnLButtonDown调用TrackPopupMenu之前,我右键单击任务栏,一切都很好。 -
尝试 2:这只是创建了一个类似变形的菜单测量,但没有任何所有者绘制尝试的迹象
CVSPMenu* sysMenu = (CVSPMenu*)CMenu::FromHandle(GetSystemMenu(FALSE)->GetSafeHmenu()); sysMenu->SetOwnderDrawn(true);
我也尝试过在OnInitMenuPopup 中做事,但传入的菜单指针似乎并没有使用(只是导致断言和失败)。
所以我的问题是,我如何以及在哪里子类化系统菜单?
【问题讨论】:
-
这听起来像是一个非常艰难的方法。您确定需要对菜单进行子类化,而不仅仅是从子类化窗口自定义它吗?
-
很酷,我解决了这个问题。事实证明,只有通过 TrackPopupMenu 调用才能正确测量自定义绘制的系统菜单(显然在某些隐藏级别上,系统菜单通过替代方法显示)。所以我覆盖了未记录的 0x0313 消息并在那里调用了 TrackPopupMenu ,它正确地测量了它等等 :)
-
如果您之前没有调用 GetSystemMenu() 并且无法修改,则传递给系统菜单的 OnInitMenuPopup 的菜单指针是默认的 SystemMenu。 blogs.msdn.com/b/oldnewthing/archive/2010/05/28/10016691.aspx
-
这是非常有用的信息!在系统菜单上很难找到信息,干杯!!
标签: c++ windows winapi mfc menu