QKeySequence WinAPI ішіндегі жылдам пернелер тізбегінен өте ерекшеленеді. QKeySequence шын мәнінде жылдам перне бөлгіші "+" белгісі болып табылатын жол, сонымен қатар бірнеше реттілік болған жағдайда ", " реттілігі. Ал WinAPI -да Alt, Ctrl, Shift модификаторлары таңбасыз бүтін сан түрімен және пернетақта коды арқылы көрсетілетін жылдам пернелер бар.
QKeySequence ішінде бір реттілік болғанда және оны WinAPI жүйесінде жаһандық жылдам перне ретінде тіркеу қажет болғанда опцияны талдап көрейік. Бұл әрекетті орындау үшін, QKeySequence тек болатынына келісеміз. Ctrl, Alt, Shift түрлендіргіші ретінде пернелер және жылдам перне ретінде ағылшын алфавитінің әріптерінің бірі.
Әрі қарай, QKeySequence талдау үшін біз екі функцияны жазамыз:
- unsigned int winKeyMod(QKeySequence) - модификаторлардың бүтін комбинациясын қайтаратын;
- char winHotKey(QKetSequence) - жылдам перне кодын қайтарады.
Биттік нұсқадағы Alt, Ctrl және Shift модификаторларының сәйкесінше 0b00000001, 0b00000010 және 0b00000100 мәндері бар, сондықтан логикалық OR немесе осы сандарды қосу қажетті комбинация нөмірін береді. . Сондықтан winKeyMod, әдісінде реттіліктен модификаторларды таңдау керек және олар бар болса, осы әдіс қайтаратын модификатордың нөміріне қосу керек.
WinHotKey жылдам перне кодын таңба айнымалысы ретінде қайтарады. Таңдалған кілт коды UNICODE. коды сияқты болады.
WinAPI ішіндегі жаһандық жылдам перне x туралы мақалада өңдеу **nativeEvent әдісінде орындалатыны айтылған, сондықтан біз бұл сұрақты кешіктірмейді және тікелей код тізіміне барады.
QKeySequence талдауы
mainwindow.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
mainwindow.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; }