QKeySequence unterscheidet sich stark von der Hotkey-Sequenz in WinAPI. QKeySequence ist eigentlich eine Zeichenfolge, in der das Hotkey-Trennzeichen das "+" -Zeichen sowie die Sequenz ", " ist, falls es mehrere Sequenzen gibt. Wohingegen in WinAPI Modifikatoren Alt, Strg, Shift vorhanden sind, die durch einen vorzeichenlosen Ganzzahltyp dargestellt werden, und eine Tastenkombination, die durch einen Tastaturcode dargestellt wird.
Analysieren wir die Option, wenn es eine Sequenz in QKeySequence gibt und diese als globaler Hotkey in WinAPI registriert werden muss. Dazu vereinbaren wir, dass QKeySequence als Modifikator verwendet werden muss nur die Tasten Strg, Alt, Shift** und einer der Buchstaben des englischen Alphabets als Hotkey.
Als Nächstes schreiben wir zwei Funktionen, um QKeySequence zu parsen:
- unsigned int winKeyMod(QKeySequence) - was eine ganzzahlige Kombination von Modifikatoren zurückgibt;
- char winHotKey(QKetSequence) - Gibt den Hotkey-Code zurück.
Die Modifikatoren Alt, Strg und Shift in der bitweisen Version haben die Werte 0b00000001, 0b00000010 bzw. 0b00000100 , sodass das logische ODER oder die Addition dieser Zahlen die erforderliche Kombinationsnummer ergibt . Daher ist es in der Methode winKeyMod, erforderlich, Modifikatoren aus der Sequenz auszuwählen und, falls vorhanden, zur Nummer des Modifikators hinzuzufügen, den diese Methode zurückgibt.
Und winHotKey gibt den Hotkey-Code als char-Variable zurück. Und der ausgewählte Schlüsselcode ist der Code UNICODE.
Im Artikel über globaler Hotkey x in WinAPI wurde bereits gesagt, dass die Verarbeitung in der nativeEvent-Methode erfolgt, also wir werde mit dieser Frage nicht zögern und direkt zum Code-Listing gehen.
QKeySequence analysieren
Hauptfenster.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QKeySequence> #include <windows.h> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); protected: bool nativeEvent(const QByteArray &eventType, void *message, long *result); private: Ui::MainWindow *ui; unsigned int winKeyMod(QKeySequence sequence); char winHotKey(QKeySequence sequence); }; #endif // MAINWINDOW_H
Hauptfenster.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // Зададим последовательность горячих клавиш QKeySequence keySequence(Qt::CTRL + Qt::ALT + Qt::SHIFT + 'A'); /* Разрегистрируем последовательность с Id 100, * в примере не обязательно, но полезно для функции изменения HotKey * */ UnregisterHotKey((HWND) MainWindow::winId(), 100); // Регистрируем HotKey RegisterHotKey((HWND)MainWindow::winId(), // Id окна обработчика событий 100, // Id хоткея winKeyMod(keySequence), // Разбираем модификаторы из QKeySequence winHotKey(keySequence)); // Выделяем горячую клавишу в последовательности } MainWindow::~MainWindow() { delete ui; } /* Модификаторы в WinAPI представляют собой комбинацию целочисленных значений. * Поэтому возвращаем суммированное безнаковое число для установки модификатора * */ unsigned int MainWindow::winKeyMod(QKeySequence sequence) { QStringList list = sequence.toString().split("+"); unsigned int keyModificator = 0; // Проходим по QStringList и проверяем на наличие модификаторов foreach (QString str, list) { if(str == "Ctrl"){ keyModificator += MOD_CONTROL; // 0x0002 continue; } else if(str == "Alt"){ keyModificator += MOD_ALT; // 0x0001 continue; } else if(str == "Shift"){ keyModificator += MOD_SHIFT; // 0x0004 continue; } } // В данном примере вернём return keyModificator; // 0b00000111 или 7 } // Выделяем горячую клавишу из последовательности char MainWindow::winHotKey(QKeySequence sequence) { QStringList list = sequence.toString().split("+"); char hotKey = 'E'; // По умолчанию будем возвращать 'E' foreach (QString str, list) { if(str != "Ctrl" && str != "Alt" && str != "Shift"){ hotKey = str.at(0).unicode(); // Если не является модификатором, то возвращаем символ } } return hotKey; } // Обрабатываем событие нажатия последовательности горячих клавиш bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) { Q_UNUSED(eventType) Q_UNUSED(result) MSG* msg = reinterpret_cast<MSG*>(message); if(msg->message == WM_HOTKEY){ switch (msg->wParam) { case 100: { qDebug() << "Key Sequence worked"; return true; break; } default: break; } } return false; }