2021年1月28日木曜日

Qt win でホットキーを使う

 
Qtで作った音楽のプレイヤーを愛用してるんだが、席を離れるときの一時停止をいちいちマウスでやるのが面倒でキーを使いたい、でもショートカットはアクティブなプロセスでしか受け取れない、そこでウインドウズ環境ならホットキーを使おうということ
ホットキーを調べたら、キーをシステムに登録してやればそのキーが押されたときに登録したウインドウに対してシステムからメッセージが来るのでそれを処理すれば良いことがわかった
普通にwin32で書けば簡単なんだが、これをQtで書くとどうなるかって事です
Qtのイベントドリブンはwin32のメッセージループでは無くコネクトの仕組みを使う、これがネックだった
元ネタはこれです、ありがとうございました
Qtでグローバルホットキーを利用する
https://qiita.com/soramimi_jp/items/c2be72a1493012e20d37

1 <pro>
LIBS += user32.lib
まずはこれ、projectファイルにライブラリを追加する

2 <h>
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
ヘッダに関数を追加、これがほぼ全てです。QWidget Class はProtected Functionsとしてこの関数を実装していてシステムからのメッセージを直接処理できるようになってます。普段は使う必要ないと思いますが。

3 <cpp>
#include <windows.h>
#define ID_HOTKEY 1
ソースにヘッダを追加

3-1 <<コンストラクタ>>
    if (! RegisterHotKey((HWND)winId(), ID_HOTKEY, 0 , VK_MEDIA_PLAY_PAUSE))
        qDebug()<<"error--Regist";
}
コンストラクタで任意のキーをレジストします
この例ではmodifierは0で設定してません

3-2 <<デストラクタ>>
    UnregisterHotKey((HWND)winId(), ID_HOTKEY);
デストラクタでこのキーを解放します

3-3 nativeEventメソッド
bool MainWindow::nativeEvent(QByteArray const &eventType, void *message, long *result){
    MSG *mes=(MSG*)message;
    if (mes->message == WM_HOTKEY) {
        qDebug()<<"kitayo";
        return true;
    }
    return false;
}
コンストラクタで登録したキーが押されると、ウインドウにメッセージが来て、この関数が呼ばれる
message 変数からmessageを取り出してWM_HOTKEYであれば処理する
処理したらtrueを返し、処理しなければfalseでQtにメッセージを返す
この例ではキーの種類はチェックしてないけどチェックも出来ます
複数のホットキーを登録した場合にはチェックが必要ですね

いろいろ事前に調べて結構実装までは時間を要したけど、実装自体はすぐだった
下調べをしっかりやればコーディングが楽、当たり前だけど
適当に書いてバグを除く作業も楽しいけどね、一度ですっと通ったときは快感だな
久しぶりでプログラミングしたがやはり楽しいねえ

0 件のコメント:

コメントを投稿