rettetdemdativ
rettetdemdativ

Reputation: 379

C++ Win32 Listen for global keybinds

I am trying to implement global hotkeys on Windows in my C++/Qt application. I used RegisterHotKey, which surprisingly worked and I can see that pressing the combination triggers my event, but since I did not know any other way, I just used a loop, which now blocks my windows and stops it from ever showing up.

You can find my code below. How do I listen for this combination? There certainly has to be another way.

void set_win32_keys(MainWindow *mwin) {
    HWND main_hwnd = (HWND)mwin->winId();
    RegisterHotKey(main_hwnd, 2, MOD_CONTROL | MOD_SHIFT, 0x32 /*2 key*/);
    MSG *msg;
    msg = new MSG();
    BOOL b_ret;
    while ((b_ret = GetMessage(msg, main_hwnd, 0, 0)) != 0) {
      if (b_ret == -1) {
        qDebug() << "Error";
      } else {
        if (msg->message == WM_HOTKEY) {
          mwin->new_screenshot();
          qDebug() << msg;
        }
      }
    }
  }

Upvotes: 1

Views: 1164

Answers (2)

Felix
Felix

Reputation: 7146

Shameless plug: I have written a library for Qt that provides global hotkeys in a cross-platform manner - and allows the usage of for example QKeySequence to create the hotkey. It allows you to use a QKeySequenceEdit to let the user enter his own shortcut:

https://github.com/Skycoder42/QHotkey

Example:

//MainWindow constructor:
QHotkey *hotkey = new QHotkey(Qt::Key_2, Qt::ControlModifier | Qt::ShiftModifier, true, this);
connect(hotkey, &QHotkey::activated, this, &MainWindow::new_screenshot);

And that's it! Hope it helps

Upvotes: 4

Alexander V
Alexander V

Reputation: 8698

How can I listen to the system hot key bound to the app main window?

Many system events can be caught at main window native event handler. And the original author post actually binds to main window. The below should process the requested message:

class MainWindow : public QMainWindow
{
      // ... snip ...
      bool nativeEvent(const QByteArray& eventType, void* message, long* result) override;
      // ... snip ...
};

bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
    MSG* pMsg = reinterpret_cast<MSG*>(message);

    if (pMsg->message == WM_HOTKEY)
    {
       // process pMsg->wParam / lParam etc.

       // the intended action
       this->new_screenshot();
    }

    // call the parent, could be QWidget::nativeEvent
    return QMainWidow::nativeEvent(eventType, message, result);
}

Because of assumption that mwin has QMainWindow*:

HWND main_hwnd = (HWND)mwin->winId();
RegisterHotKey(main_hwnd, 2, MOD_CONTROL | MOD_SHIFT, 0x32 /*2 key*/);

Upvotes: 3

Related Questions