Evgenii Legotckoi
Jan. 3, 2016, 10:35 p.m.

Qt WinAPI - Lesson 005. Global HotKey WinAPI in Qt5

To work with global HotKey in Qt5 , there is a virtual method nativeEvent . This method replaces the methods winEvent , x11Event , macEvent of Qt 4.8 .

The especiality in the HotKey to Qt is that if the window is not in focus, that is, it is, for example, will be minimized to the system tray, then registered QShortcut simply will not work. It is therefore necessary to work with the global events from the operating system, that is, go to the realization of the platform-specific code in the application to Qt.

RegisterHotKey

In this example Let us examine the option of working with WinAPI. For this we use the function RegisterHotKey.

  1. BOOL WINAPI RegisterHotKey(
  2. _In_opt_ HWND hWnd,
  3. _In_ int id,
  4. _In_ UINT fsModifiers,
  5. _In_ UINT vk
  6. );

RegisterHotKey parameters

hWnd [in, optional]

Тип: HWND
A handle to the window that will receive WM_HOTKEY messages generated by the hot key. If this parameter is NULL , WM_HOTKEY messages are posted to the message queue of the calling thread and must be processed in the message loop.

id [in]

Type: int
The identifier of the hot key. If the hWnd parameter is NULL, then the hot key is associated with the current thread rather than with a particular window. If a hot key already exists with the same hWnd and id parameters, see Remarks for the action taken.

fsModifiers [in]

Type: UINT The keys that must be pressed in combination with the key specified by the uVirtKey parameter in order to generate the WM_HOTKEY message. The fsModifiers parameter can be a combination of the following values.

  • MOD_ALT 0x0001 - Either ALT key must be held down.
  • MOD_CONTROL 0x0002 - Either CTRL key must be held down.
  • MOD_NOREPEAT 0x4000 - Changes the hotkey behavior so that the keyboard auto-repeat does not yield multiple hotkey notifications. Windows Vista: This flag is not supported.
  • MOD_SHIFT 0x0004 - Either SHIFT key must be held down.
  • MOD_WIN 0x0008 - Either WINDOWS key was held down. These keys are labeled with the Windows logo. Keyboard shortcuts that involve the WINDOWS key are reserved for use by the operating system.

vk [in]

Type: UINT
The virtual-key code of the hot key.

UnregisterHotKey

Disable keyboard shortcuts.

  1. BOOL WINAPI UnregisterHotKey(
  2. _In_opt_ HWND hWnd,
  3. _In_ int id
  4. );

UnregisterHotKey Parameters

hWnd [in, optional]

Type: HWND
A handle to the window associated with the hot key to be freed. This parameter should be NULL if the hot key is not associated with a window.

id [in]

Type: int
The identifier of the hot key to be freed.

An example of a HotKey in WinAPI

Create a project to work with HotKey. This project will be present QSystemTrayIcon object class. Let's hide the application in the system tray and check hotkeys. That combination is "ALT + SHIFT + D", for example. In this project, the handler hotkeys will MainWindow. Treatment of combinations of hot keys will be made in nativeEvent.

Check on the selected combination of hot keys will produce via qDebug().

mainwindow.h

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3.  
  4. #include <QMainWindow>
  5. #include <QSystemTrayIcon>
  6. #include "windows.h" // Connect WinAPI library
  7.  
  8. namespace Ui {
  9. class MainWindow;
  10. }
  11.  
  12. class MainWindow : public QMainWindow
  13. {
  14. Q_OBJECT
  15.  
  16. public:
  17. explicit MainWindow(QWidget *parent = 0);
  18. ~MainWindow();
  19.  
  20. protected:
  21. // The method for processing native events from the OS in Qt
  22. bool nativeEvent(const QByteArray &eventType, void *message, long *result);
  23.  
  24. private slots:
  25. void iconActivated(QSystemTrayIcon::ActivationReason reason);
  26.  
  27. private:
  28. Ui::MainWindow *ui;
  29. QSystemTrayIcon *trayIcon;
  30. };
  31.  
  32. #endif // MAINWINDOW_H

mainwindow.cpp

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QDebug>
  4.  
  5. MainWindow::MainWindow(QWidget *parent) :
  6. QMainWindow(parent),
  7. ui(new Ui::MainWindow)
  8. {
  9. ui->setupUi(this);
  10. /* System Tray Icon is necessary to the application window is not in focus
  11. * */
  12. trayIcon = new QSystemTrayIcon(this);
  13. trayIcon->setIcon(this->style()->standardIcon(QStyle::SP_ComputerIcon));
  14. trayIcon->show();
  15.  
  16. connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
  17. this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
  18.  
  19. // Register HotKey "ALT+SHIFT+D"
  20. RegisterHotKey((HWND)MainWindow::winId(), // Set the system identifier of the widget window that will handle the HotKey
  21. 100, // Set identifier HotKey
  22. MOD_ALT | MOD_SHIFT, // Set modifiers
  23. 'D'); // We define hotkeys for HotKey
  24. }
  25.  
  26. MainWindow::~MainWindow()
  27. {
  28. delete ui;
  29. }
  30.  
  31. bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
  32. {
  33. Q_UNUSED(eventType)
  34. Q_UNUSED(result)
  35. // Transform the message pointer to the MSG WinAPI
  36. MSG* msg = reinterpret_cast<MSG*>(message);
  37.  
  38. // If the message is a HotKey, then ...
  39. if(msg->message == WM_HOTKEY){
  40. // ... check HotKey
  41. if(msg->wParam == 100){
  42. // We inform about this to the console
  43. qDebug() << "HotKey worked";
  44. return true;
  45. }
  46. }
  47. return false;
  48. }
  49.  
  50. void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
  51. {
  52. switch (reason){
  53. case QSystemTrayIcon::Trigger:
  54. !isVisible() ? show() : hide();
  55. break;
  56. default:
  57. break;
  58. }
  59. }

Note

To ensure that the project is compiled with MSVC build a set, add the following lines to pro project file:

  1. win32-msvc*{
  2. LIBS += -luser32
  3. }

Conclusion

As a result of this processing will code the global keyboard shortcuts, even if the application window will be hidden in the system tray tray.

Video

Do you like it? Share on social networks!

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • AK
    April 1, 2025, 11:41 a.m.
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
  • ИМ
    Nov. 22, 2024, 9:51 p.m.
    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
  • Evgenii Legotckoi
    Oct. 31, 2024, 11:37 p.m.
    Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup