[MacOSX] 低レベルAPIでマウス,キーボードを制御
MacOSXでは,Quartzに含まれる低レベルAPIで,マウスやキーボードのイベントをシステム側にPostすることができる.
調べるとPanther当たりまでは,色々とバグがあったようだが,大分使えるようになってきているらしい.
ここでは,マウスイベント,キーボードイベントのPostについて,調べたことをまとめてみる.
マウスイベント
マウスのクリックイベントをPostする
CGPostMouseEvent
Synthesizes a low-level mouse-button event on the local machine.
CGEventErr CGPostMouseEvent ( CGPoint mouseCursorPosition, boolean_t updateMouseCursorPosition, CGButtonCount buttonCount, boolean_t mouseButtonDown, );
一つめの引数はマウスの目的位置,二つめの引数はマウスをそこにちゃんと動かすかのフラグ,三つ目の引数はマウスボタンの番号,四つ目の引数はマウスをクリックするかのフラグである.
buttonCountは,1が左,2が右,3が真ん中ボタンになるらしい.
例えば,一番左上隅をクリックするようにマウスを制御する場合は,以下のようにコーディングする.
CGPoint point; point.x=0; point.y=0; CGPostMouseEvent(point, TRUE, 1, TRUE); //mouse down CGPostMouseEvent(point, TRUE, 1, FALSE); //mouse up
ちゃんと,マウスアップのイベントをPostしないと,クリックしたことにならないことがあるので要注意.
また,デスクトップの表示領域は以下のAPIで取得できる.
int width = CGDisplayPixelsWide(kCGDirectMainDisplay); int height = CGDisplayPixelsHigh(kCGDirectMainDisplay);
マウスの表示を制御する
マウスのポインタの表示/非表示を設定するには,以下のAPIを利用する.
CGDisplayErr CGDisplayHideCursor(CGDirectDisplayID display); // カーソルを隠す CGDisplayErr CGDisplayShowCursor(CGDirectDisplayID display); // カーソルを表示する
マウスのポインタの表示位置を設定するには,以下のAPIを利用する.ただし,このAPIの場合,マウスが移動したことによるイベントは発生しない.マウスのイベントをちゃんと発生させたい場合は,上記のCGPostMouseEventを利用する.
CGDisplayErr CGDisplayMoveCursorToPoint(CGDirectDisplayID display, CGPoint point);
CGDirectDisplayID displayには,ディスプレイの識別子を入力するのだが,複数のディスプレイを利用したりしていない場合は,kCGDirectMainDisplayを引数にすれば,大丈夫.
詳しくは,Appleのこの辺の資料を参考にされたい.
Technical Note TN2007
キーボードイベント
キーボードイベントをシステムにPostする
キーボードイベントは,以下のAPIでPostできる.
CGEventErr CGPostKeyboardEvent ( CGCharCode keyChar, CGKeyCode virtualKey, boolean_t keyDown );
三つ目の引数は,キーの押しと,上げるのフラグである.
しかし,一つめと二つめの引数が何を意味するかが,よくわからない.そこで,ヘッダファイルCGRemoteOperation.hと,ネットの情報を調べてみた.
それらをまとめると,
となるらしい.
なぜ,こんなバラバラになっているのかが,よくわからないのだが,Appleのドキュメントにないので致し方ない.直感すると,CGKeyCodeで,複数の修飾キーを設定できると思うのだが・・・.
これらを利用して,コマンドキー+'C',いわゆるコピーショートカットを実現する場合は,以下のようなコードになる.
CGPostKeyboardEvent((CGCharCode)NULL, (CGKeyCode)55, true); CGPostKeyboardEvent((CGCharCode)'c', (CGKeyCode)9, true); CGPostKeyboardEvent((CGCharCode)'c', (CGKeyCode)9, false); CGPostKeyboardEvent((CGCharCode)NULL, (CGKeyCode)55, false);
コマンドキーを押す,Cキーを押す,Cキーを放す,コマンドキーを放すの順番で入力したことになる.