【问题标题】:Modeless dialogs and accelerators无模式对话框和加速器
【发布时间】:2011-08-19 14:05:08
【问题描述】:

当用户在无模式对话框中按下CTRL+S 时,我想执行一些操作。 加速器非常适合这个,除了我无法控制线程的消息循环(想想插件),所以我不能调用TranslateAccelerator

嵌套消息循环不是一个选项,因为主应用程序在调用 PeekMessage 之间进行了大量处理。

  • 有什么方法可以“强制”现有的消息循环来处理我的加速器吗?
  • 除了加速器还有其他方法可以捕获CTRL+S吗?

我考虑过在WH_GETMESSAGE 上使用一个窗口挂钩,它在从GetMessagePeekMessage 返回之前被调用。但是我不确定在我成功调用TranslateAcellerator 后会发生什么,我不能让应用程序知道我处理了它。 WH_MSGFILTER 将要求应用程序实现对 CallMsgFilter 的调用,而使用调试器快速浏览它并不会这样做。

我的最后一个想法是将控件子类化,这是我试图避免的。这将需要一些机制来向父窗口发出按键事件信号,我认为这不是一个很好的设计。此外,如果我添加更多控件,我将不得不对每个控件进行子类化。

感谢任何提示。

【问题讨论】:

    标签: c++ windows dialog accelerator modeless


    【解决方案1】:

    这是一个相当臭名昭著的互操作问题,当使用 Winforms 在本机程序中实现 UI 时,它也会抬头。微软的建议是粗略的:启动你自己的线程来显示窗口,这样你就可以启动你自己的消息循环。您需要 SetParent() 来避免 Z 顺序问题。可怕的东西,在提交之前请考虑三次模态对话框。

    【讨论】:

    • 不好的是插件接口不是线程安全的,所以我最终会陷入同步问题的深处。我曾经在这条路上走过一次,几乎从一开始就将其消除了,仅仅为了一个键盘快捷键是不值得的。
    • 好,你三思而后行。
    【解决方案2】:

    【讨论】:

    • 正如我所说,我可以将控件子类化,然后处理 WM_CHAR(它在 WM_GETDLGCODE 上返回 DLGC_WANTALLKEYS),这样应该是可能的。但这不是一个最佳解决方案,如果我希望快捷方式在整个对话框中工作,则需要对所有其他子控件进行子类化。
    • 很公平。你能在getmessage中绕道吗?不过对于一个插件来说有点讨厌......
    • 其实这正是 WH_GETMESSAGE 的用途。问题是我不知道如果我处理传入的消息然后主应用程序仍然调用 TranslateMessage 和 DispatchMessage 是否安全。也许我应该绕过这两个,但是我怎么知道 API 是从主循环调用的,而不是其他模式消息循环?
    猜你喜欢
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多