Реклама

Qt WinAPI - Урок 006. Разбор QKeySequence для RegisterHotKey в WinAPI

РуководствоQtHotKey, QKeySequence, Qt, RegisterHotKey, WinAPI, горячие клавиши1070

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 соответственно, поэтому логическое ИЛИ либо сложение данных чисел даст необходимое число комбинации. Следовательно необходимо в методе winKeyMod, выделить модификаторы из последовательности и в случае их наличия прибавить к числу модификатора, которое вернёт данный метод.

А winHotKey вернёт код горячей клавиши в виде переменной char. А выделен код клавиши будет в качестве кода UNICODE.

В статье о глобальных горячий клавиша х в WinAPI уже рассказывалось, что обработка производится в методе 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;
}
Реклама

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
Последние комментарии
  • EVILEG
  • 13 июля 2017 г. 2:12

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Ну например так можете сделать.void MoveItem::mousePressEvent(QGraphicsSceneMouseEvent *event){ if (QApplication::mouseButtons() == Qt::RightButton) { this->deleteLa...

  • Mark
  • 13 июля 2017 г. 1:26

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Подскажите пожалуйста как в данном проекте по перетаскиванию организовать удаление объекта со scene методом delete item, допустим при щелчке ПКМ по объекту QGraphicsScene. Мои попытки оказалис...

  • EVILEG
  • 10 июля 2017 г. 21:34

Qt/C++ - Урок 048. QThread - работа с потоками с помощью moveToThread

А что делали? Повторяете урок или как? Пытались просто скачать проект в конце статьи и запустить?

Qt/C++ - Урок 048. QThread - работа с потоками с помощью moveToThread

У меня происходит переполнение счетчика count, появляется ошибка malloc(): memory corruption (fast). Не подскажите, как с этим бороться?

  • EVILEG
  • 9 июля 2017 г. 2:07

GameDev на Qt - Урок 3. Уничтожение противников

Поэтому в пятом уроке есть исходники всего проекта )))). Вообще, все эти материалы были не предыдущей версии сайта, которая на WordPress. Во время переноса мог что-то потерять.

Сейчас обсуждают на форуме

тестирование классов в QT

это вопрос.

Как реализовать отправку e-mail

Возможно что уже и нет необходимости в почтовом клиенте, но в своё время так же столкнулся с данной проблемой в QT. Нашел один интересный проект под названием libqxt, там реализовано дов...

  • Asteri
  • 14 июля 2017 г. 12:23

css

Делюсь, может, пригодится когда-нибудь) QTableView QHeaderView { background-color: #ffffff; } Вот так эта проблема лечится, градиент задать не получается, но хоть...

  • EVILEG
  • 12 июля 2017 г. 19:52

QSqlQuery выполнение sql запросов из файла

Мне думается, что это уже будет дело вкуса и вашего взгляда на проект. Если Вы действительно собираетесь просто скармливать своему софту SQL скрипты, которые должны будут выполняться для...

QML Canvas + Line. Bug?

Вот оно что, значит не баг) Спасибо