Programming

QtでKeyEventを送信①

以前、QtでのMidiアクセスという記事を投稿したのですが、今度は別プロセスにKeyEventを送信する必要があり、これがMidiアクセスより遥かに苦戦したので実現出来るまでの備忘録です。

前に書いていませんでしたが、Qtとはマルチプラットフォームの開発ツールで、WindowsでもMacでもLinuxでも同じコードで同じものを作ることが出来る便利なものなんですが、機能が用意されていないものもあります。QKeyEventクラスというのがあるのですが、これは自分のアプリに入力されたキーボード情報を知る為のものであり、他のプロセスにKeyEventを送信するとかではないんですよね。こっちも作っといてくれよと思うのですが、このような場合は自分で作るしかありません。まずWindowsでは、送信したいウィンドウズのハンドルを取得し、それをForgroundに持ってきます。そして、keybd_event関数で送信します。色々試しましたがこの方法で上手くいきました。

void QKeyEventSendWin::sendKeyEvent(int iPos, unsigned char uKey)
{
#if defined(__WINDOWS_MM__)
    if (iPos < 0 || iPos >= _oHandleList.length() ){
        return;
    }

    HWND hWnd = _oHandleList.at(iPos);
    SetForegroundWindow(hWnd);

    keybd_event(uKey, 0,0,0);
    keybd_event(uKey, 0,KEYEVENTF_KEYUP,0);

#endif
}

全てのサンプルコードを載せると量が多くなってしまうので割愛していますが、_oHandleListは、予め取得しておいた今動いているプロセスのハンドルリストです。

次にMacですが、他のプロセスにキーイベントを送信するレクチャーが載っている日本語の記事がなく、英語のページを検索するとちらほらと出てきます。CGEventPostToPSNというObjective-cの関数を使うといいみたいです。

CGEventRef key_down = CGEventCreateKeyboardEvent(NULL, uKey, true);
CGEventPostToPSN(&_psnArray[iPos], key_down);

CGEventRef key_up = CGEventCreateKeyboardEvent(NULL, uKey, false);
CGEventPostToPSN(&_psnArray[iPos], key_up);

CFRelease(key_down);
CFRelease(key_up);

CGEventPostToPSNの第一引数に設定している&_psnArray[iPos]とうのは、予め 取得しておいた今動いているプロセスの PSNリストです。PSNというのは、Macのウィンドウハンドルにあたるものなんでしょうか?この今動いているプロセスのPSNを取得するやり方が、こちらのページにありました!ありがたいです。

ここまで調べるのも一筋縄ではなかったんですが、問題はここからでした。長くなるので前半、後半に分けます。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

PAGE TOP