在MFC应用程序中设置全局热键的正确方法是什么?

发布于 2025-02-09 06:13:43 字数 92 浏览 3 评论 0原文

我知道如何使用加速器表在我的应用程序中设置热键。但是,我如何在全球范围内获得热键呢?

即我的应用程序正在运行,但最小化。但是我仍然希望它检测并处理一个热键。

I know how to use the accelerator table to setup hot keys within my app. But how do I get a hot key at global level?

I.e. My app is running, but minimised. Yet I still want it to detect and process a hot key.

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

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

发布评论

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

评论(1

瞳孔里扚悲伤 2025-02-16 06:13:43

如果您需要一个系统范围的热键,则应使用 registerHotkey ,传递窗口手柄的窗口过程负责处理事件。在应用程序级别上,这通常是cframewnd/cframewndex衍生的窗口实现。

一旦注册了热键,接收窗口就可以在其自定义 cwnd :: onhotkey 覆盖。确保添加 on_wm_hotkey(on_wm_hotkey( )消息处理程序到接收窗口实现的消息图。

对于标准,默认生成的SDI/MDI应用程序,您需要应用以下更改。

mainfrm.h:

class CMainFrame : public CFrameWnd
{
    // ...
private:
    // Hot key handler routine
    afx_msg void OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2);
};

mainfrm.cpp:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    // ...

    // Make sure that WM_HOTKEY messages are routed to this window
    ON_WM_HOTKEY()
END_MESSAGE_MAP()

// Hot key ID; can be any value in the range 0x0000 through 0xBFFF
// Allows the application to identify this hot key in case there is more than one
constexpr int MyHotKeyId = 42;

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
    // ...

    // Register a global system-wide hot key (Ctrl+Shift+Alt+I)
    if (!::RegisterHotKey(this->m_hWnd, MyHotKeyId,
                          MOD_ALT | MOD_SHIFT | MOD_CONTROL | MOD_NOREPEAT,
                          'I')) {
        auto const ec = ::GetLastError();
        auto const err_msg = std::format(L"RegisterHotKey failed (error: {})\n",
                                         ec);
        ::OutputDebugStringW(err_msg.c_str());

        // Probably a good idea to handle failure more gracefully than this:
        return -1;
    }

    return 0;
}

void CMainFrame::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2) {
    // Handle hot key; nHotKeyId is MyHotKeyId in this case
}

请注意,接收wm_hotkey消息授予接收线前景激活许可。如果您希望您的应用程序在收到注册的热键后进入前景,则可以使用以下onHotkey实现:

void CMainFrame::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2) {
    if (this->IsIconic()) {
        this->ShowWindow(SW_RESTORE);
    }
    this->SetForegroundWindow();
}

无需刷新任务栏按钮,一切都按预期工作。

If you need a system-wide hotkey then you should use RegisterHotKey, passing in the window handle whose window procedure is responsible for handling the event. At the application level this is commonly the CFrameWnd/CFrameWndEx-derived window implementation.

Once the hotkey is registered, the receiving window can observe the event in its custom CWnd::OnHotKey override. Make sure to add the ON_WM_HOTKEY() message handler to the message map of the receiving window implementation.

For a standard, default-generated SDI/MDI application you'd need to apply the following changes.

MainFrm.h:

class CMainFrame : public CFrameWnd
{
    // ...
private:
    // Hot key handler routine
    afx_msg void OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2);
};

MainFrm.cpp:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    // ...

    // Make sure that WM_HOTKEY messages are routed to this window
    ON_WM_HOTKEY()
END_MESSAGE_MAP()

// Hot key ID; can be any value in the range 0x0000 through 0xBFFF
// Allows the application to identify this hot key in case there is more than one
constexpr int MyHotKeyId = 42;

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
    // ...

    // Register a global system-wide hot key (Ctrl+Shift+Alt+I)
    if (!::RegisterHotKey(this->m_hWnd, MyHotKeyId,
                          MOD_ALT | MOD_SHIFT | MOD_CONTROL | MOD_NOREPEAT,
                          'I')) {
        auto const ec = ::GetLastError();
        auto const err_msg = std::format(L"RegisterHotKey failed (error: {})\n",
                                         ec);
        ::OutputDebugStringW(err_msg.c_str());

        // Probably a good idea to handle failure more gracefully than this:
        return -1;
    }

    return 0;
}

void CMainFrame::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2) {
    // Handle hot key; nHotKeyId is MyHotKeyId in this case
}

Note that receiving a WM_HOTKEY message grants the receiving thread foreground activation permission. If you want your application to come to the foreground upon receiving a registered hot key, you can use the following OnHotKey implementation:

void CMainFrame::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2) {
    if (this->IsIconic()) {
        this->ShowWindow(SW_RESTORE);
    }
    this->SetForegroundWindow();
}

No flashing the taskbar button, everything just works as intended.

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