Qt WinAPI - Lesson 005. Global HotKey WinAPI in Qt5

Qt, HotKey, RegisterHotKey, UnregisterHotKey, WinAPI, горячие клавиши

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.

BOOL WINAPI RegisterHotKey(
  _In_opt_ HWND hWnd,
  _In_     int  id,
  _In_     UINT fsModifiers,
  _In_     UINT vk
);

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.

BOOL WINAPI UnregisterHotKey(
  _In_opt_ HWND hWnd,
  _In_     int  id
);

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

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSystemTrayIcon>
#include "windows.h" // Connect WinAPI library

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    // The method for processing native events from the OS in Qt
    bool nativeEvent(const QByteArray &eventType, void *message, long *result);

private slots:
    void iconActivated(QSystemTrayIcon::ActivationReason reason);

private:
    Ui::MainWindow *ui;
    QSystemTrayIcon *trayIcon;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /* System Tray Icon is necessary to the application window is not in focus
     * */
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(this->style()->standardIcon(QStyle::SP_ComputerIcon));
    trayIcon->show();

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    // Register HotKey "ALT+SHIFT+D"
    RegisterHotKey((HWND)MainWindow::winId(),   // Set the system identifier of the widget window that will handle the HotKey
                   100,                         // Set identifier HotKey
                   MOD_ALT | MOD_SHIFT,         // Set modifiers
                   'D');                        // We define hotkeys for HotKey
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    Q_UNUSED(eventType)
    Q_UNUSED(result)
    // Transform the message pointer to the MSG WinAPI
    MSG* msg = reinterpret_cast<MSG*>(message);

    // If the message is a HotKey, then ...
    if(msg->message == WM_HOTKEY){
        // ... check HotKey
        if(msg->wParam == 100){
            // We inform about this to the console
            qDebug() << "HotKey worked";
            return true;
        }
    }
    return false;
}

void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason){
    case QSystemTrayIcon::Trigger:
        !isVisible() ? show() : hide();
        break;
    default:
        break;
    }
}

Note

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

win32-msvc*{
    LIBS += -luser32
}

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

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Donate

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

LP
Nov. 12, 2019, 8:22 a.m.
Lev Parhimovich

C++ - Test 006. Enumerations

  • Result:50points,
  • Rating points-4
LP
Nov. 12, 2019, 7:35 a.m.
Lev Parhimovich

C++ - Test 005. Structures and Classes

  • Result:66points,
  • Rating points-1
LP
Nov. 12, 2019, 7:26 a.m.
Lev Parhimovich

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
Last comments
b
Nov. 9, 2019, 8:28 a.m.
bastonc

спасибо ещё раз. огромное, за уделённое время
b
Nov. 9, 2019, 8:24 a.m.
bastonc

Спасибо Вам большое. Буду изучать.
Nov. 9, 2019, 5:58 a.m.
Evgenij Legotskoj

Добрый день. По первым двум вопросам вы найдёте ответ в этой статье - PyQt5 - Урок 008. Работа с QTableWidget (Обновление урока 006) Что касается последнего вопроса, то я вам…
Nov. 9, 2019, 2:50 a.m.
Evgenij Legotskoj

Как и обещал, вы можете посмотреть новую статью QML - Урок 037. Кастомизация кнопок в QML (Обновление урока 002) . Там же найдёте ссылку на Git репозиторий. Не забудьте поставить звёз…
b
Nov. 8, 2019, 7:40 a.m.
bastonc

Приветствую. Подскажите пожалуйста пару моментов. 1. Как сделать столбец не редактируемый, а остальные ячейки остаются редактируемыми 2. Как оталвливать события двойного клика для реда…
Now discuss on the forum
KZ
Nov. 13, 2019, 10:07 a.m.
Konstantin Znamenskii

Добрый день. Я хочу узнать, как наиболее грамотно обновлять Maintenance Tool у пользователя. Я периодически выкладываю обновления пакетов самой программы, но мне также нужно вносить изменения в …
Nov. 13, 2019, 9:33 a.m.
Pavel.K

Приложение трэкинг задач. Есть вложения. Добавляем вложение и отправляем его на сервер. Для синхронного вызова методов в синхронизации, используем QEventLoop при отправке вложений. В момент син…
Nov. 13, 2019, 6:41 a.m.
Ruslan Polupan

Ну ка кбы уже лет 10 как работает :-) Просто нужна отдельная прога для добавления таких записей, отдать клиентам чтобы мозг не парили....
Nov. 13, 2019, 3:13 a.m.
Evgenij Legotskoj

Добрый день. Думаю, что да. Выбранный стиль можно подгружать при запуске программы. Во всяком случае, есть такой пример на C++ - Controls Gallery . И там есть такой код #incl…
Nov. 12, 2019, 9:35 a.m.
Evgenij Legotskoj

Добрый день. Для корректной вставки ссылок на youtube вставляйте их через пустую строку, таким образом Первая ссылка Вторая ссылкаТретья ссылка
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB