CFrameWndEx 窗口中未处理 WM_MENUSELECT

发布于 2024-12-28 21:39:08 字数 1398 浏览 0 评论 0原文

我正在尝试处理基于 CFrameWndEx 主框架窗口的 VS2008(和 VS2010)SDI 项目中的 WM_MENUSELECT 消息。

我从 VS2008 向导创建一个简单的项目(单个文档,“MFC 标准”,“使用经典菜单”选项),结果类似于(添加 WM_MENUSELECT 消息后):

class CMainFrame : public CFrameWnd
{
///...
public:
    afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu);
};

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_WM_CREATE()
    ON_WM_MENUSELECT()
END_MESSAGE_MAP()

///...
void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
    CFrameWnd::OnMenuSelect(nItemID, nFlags, hSysMenu);
}

当在 CMainFrame 中放置断点时,这有效 OnMenuSelect 当使用菜单时触发(在这种情况下每次)

用 CFrameWndEx 替换 CFrameWnd (或通过使用带有选项单个文档的向导创建一个新项目,“MFC标准”、“使用菜单栏和工具栏”选项)

class CMainFrame : public CFrameWndEx
{
///....
public:
    afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu);   
};

并且

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWndEx)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
    ON_WM_CREATE()
    ON_WM_MENUSELECT()
END_MESSAGE_MAP()

///....    
void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
    CFrameWndEx::OnMenuSelect(nItemID, nFlags, hSysMenu);
}

该消息永远不会被触发。

我什至已经使用 CFrameWndEx 将项目精简到严格的最低限度,但我仍然无法收到消息。

知道为什么吗?提示、提示总是受欢迎的。 谢谢。 最大限度。

I'm trying to handle the WM_MENUSELECT message in a VS2008 (and VS2010) SDI project based on a CFrameWndEx main frame window.

I create a simple project from the VS2008 wizard (single document, "MFC standard", "use classic menu" options) which results in something like (after added the WM_MENUSELECT message):

class CMainFrame : public CFrameWnd
{
///...
public:
    afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu);
};

and

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_WM_CREATE()
    ON_WM_MENUSELECT()
END_MESSAGE_MAP()

///...
void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
    CFrameWnd::OnMenuSelect(nItemID, nFlags, hSysMenu);
}

This works, when putting a breakpoint in CMainFrame::OnMenuSelect it is triggered when the menu is used (in that case everytime)

Replacing CFrameWnd by CFrameWndEx (or by creating a new project with the wizard with the options single document, "MFC standard", "use a menubar and toolbar" options)

class CMainFrame : public CFrameWndEx
{
///....
public:
    afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu);   
};

and

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWndEx)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
    ON_WM_CREATE()
    ON_WM_MENUSELECT()
END_MESSAGE_MAP()

///....    
void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
    CFrameWndEx::OnMenuSelect(nItemID, nFlags, hSysMenu);
}

The message will never be triggered.

I've even stripped down the project using CFrameWndEx to the strict minimum and I still cannot get the message.

Any idea why ? tips, hints are always welcome.
Thanks.
Max.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我很坚强 2025-01-04 21:39:08

消息映射开头的宏中的基类必须正确(ON_WM_MENUSELECT 上方)。我的猜测是,当您更改基类时,您没有将其更改为 CFrameWndEx

The base class must be correct in the macro at the start of the message map (above the ON_WM_MENUSELECT). My guess is that you didn't change it to CFrameWndEx when you changed the base class.

倦话 2025-01-04 21:39:08

啊啊,单步执行 MFC 源代码的美好时光!它一直是关键 ;-)

CMFCPopupMenu::SetSendMenuSelectMsg() 是您的新朋友。

只需在 CMainFrame::OnCreate() 中添加这一行:

CMFCPopupMenu::SetSendMenuSelectMsg(TRUE);

最重要的是,MFC 菜单和工具栏不是标准 Windows 对象的常见包装器。他们使用不同的模型以不同的方式实现事物。

现在,为了向后兼容,您可以要求这些类充当它们的前辈并发送 WM_MENUSELECT,默认情况下它们不会这样做。

注意:可能有新的机制或最佳实践来操纵这些对象。可能值得研究它们而不是强制进行兼容性设置。

Aaah, the good old times of single-stepping into the source code of MFC! It's always been the key ;-)

CMFCPopupMenu::SetSendMenuSelectMsg() is your new friend.

Just add this line in your CMainFrame::OnCreate() :

CMFCPopupMenu::SetSendMenuSelectMsg(TRUE);

The bottom line is that MFC menus and toolbars aren't the usual wrappers around standard Windows objects. They implement things differently, using a different model.

Now, for the sake of backward compatibility, you can ask those classes to act as their predecessors and send a WM_MENUSELECT, which they don't by default.

Note: There are probably new mechanisms or best practices to manipulate these objects. It's probably worth investigating them rather than forcing a compatibility setting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文