ClipMenuでメニュー項目を選択すると、ペーストするために、Command + v を送信するようになっています。これまでは、Cocoabuilderで紹介されていたCarbon APIを使っていました。
CGPostKeyboardEvent( (CGCharCode)0, (CGKeyCode)55, true ); // command key down CGPostKeyboardEvent( (CGCharCode)'v', (CGKeyCode)9, true ); // 'v' key down CGPostKeyboardEvent( (CGCharCode)'v', (CGKeyCode)9, false ); // 'v' key up CGPostKeyboardEvent( (CGCharCode)0, (CGKeyCode)55, false ); // command key up
でも、これだと、Shiftキーを押しながらメニュー項目を選択すると、Command + v ではなく、Command + Shift + v が送信されてしまいます。CGPostKeyboardEventを呼び出した時点で押し下げされているキーと混ざってしまうんですね。
これまでは問題なかったんですが、新しく、「修飾キー + クリック」にいろいろな機能を割り当てられるように変更したので、問題が生じるようになりました。
そこで、Xcode 3.1のAPIリファレンスを検索してみると、どうもCGPostKeyboardEvent関数の利用は非推奨になっていて、代わりにCGEventCreateKeyboardEvent関数の利用がおすすめのようです。
こちらを使えば、キーボードイベントの作成と、そのイベントをカスタマイズしてからイベントシステムへの送信ができるようになるそうです。対応環境は、Mac OS X 10.4以降と、新しめのAPIですね。
早速試してみました。CGPostKeyboardEventと同じように、command down → v down → v up → command upという手順で呼んでみると、うまく動かない?そこで、CocoabuilderでCGEventCreateKeyboardEventを検索してみると、Dave DeLongさんの質問から始まった二つのスレッドを発見。
- Cocoabuilder – (Dave DeLong) Posting Keyboard Events
- Cocoabuilder – (Dave DeLong) More on Keyboard Event posting
DeLongさんは、数時間悪戦苦闘し、思いつく限りググった末に質問を投稿されたようです。お陰で、この関数の使い方が解りました。感謝です!
修飾キーの入力はそれ用のイベントを作るのではなく、CGEventSetFlags関数を使って、文字キーの入力イベントに追加する形にすれば良いんですね。修正したコードは、こうなりました。
CGEventSourceRef sourceRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
if (!sourceRef) {
NSLog(@"No event source");
return;
}
CGEventRef eventDown, eventUp;
eventDown = CGEventCreateKeyboardEvent(sourceRef, (CGKeyCode)9, true); // v key down
CGEventSetFlags(eventDown, kCGEventFlagMaskCommand); // command key press
eventUp = CGEventCreateKeyboardEvent(sourceRef, (CGKeyCode)9, false); // v key up
CGEventPost(kCGSessionEventTap, eventDown);
CGEventPost(kCGSessionEventTap, eventUp);
CFRelease(eventDown);
CFRelease(eventUp);
CFRelease(sourceRef);
同じスレッドに、CGPostKeyboardEvent関数を使った方法も掲載されていました。Keyboard Maestroの作者さんの投稿?
Cocoabuilder – (Peter N Lewis) Re: Posting Keyboard Events
CGEnableEventStateCombining関数で、キーやマウスの状態を、アプリケーション側で生成するイベントに混ぜ合わせるかどうかを切り替えられるようです。ただ、こちらの関数も、今は非推奨の扱いになっているようで、Mac OS X 10.4よりも古いバージョンに対応させる必要がなければ、積極的に使わない方が良さそうです。
Quartz Event Servicesのリファレンスをざっと眺めてみましたが、キーボードやマウスに関するイベントが作れるので、結構重宝しそうです。


5月 9th, 2009 at 0:47:34
みんなと同じようにパソコン操作をしたい!その願いのお手伝いができたら嬉しい・・・と非営利活動しております。 Macは素人です。マウスやキーボードのイベントをソフトで発行する方法を知りたくて検索していましたらたどり着きました。 貴重な情報をありがとうございます。Macへの移植などのアドバイスを頂けたら嬉しいです。
5月 10th, 2009 at 17:33:29
hikenさん、
ホームページを拝見させて頂き、「できマウス。」プロジェクトには大変感銘を受けました。
JoyToKeyも、Windows PCを利用していた際には活用させて頂いたソフトです。Macでも欲しいソフトの一つでもあります。
お役に立てれば良かったのですが、ハードウェア寄りの低レベルな知識もほとんどありませんし、残念ながら現状では貢献できそうもありません。
お力になれず、申し訳ありません。
5月 10th, 2009 at 23:17:42
レスをいただきありがとうございます。
下記のようなソフトを作るアドバイスをお願いできないでしょうか?
1.マウスカーソルを移動し、一定時間経過したら、その場所でクリック イベントを発行するソフト。 2.ボタンを配置し、そのボタンを選択すると、キーイベントをは行する ソフト。
サンプルソースコードがあるURLなども教えていただけたら嬉しいです。
5月 11th, 2009 at 22:48:44
わかる範囲で、サンプルを作ってみました。
http://www.naotaka.com/mac/archive/AccessibleAppSample.zip
サンプルアプリケーションとソースコード(Xcode 3.1.2で作成)が入っています。Mac OS X 10.5でしか試していませんが、アプリケーションの方はMac OS X 10.4でも動くはずです。
アプリケーションを起動して表示される画面で、「Move and Click」を押すと、その時のマウスポインタの位置から、XとYで指定したピクセルだけ移動して、クリックをします。
Delayのスライダーを動かすと、移動してからクリックまでの遅延時間を設定できます。
画面下半分にある三つのボタンは、それぞれ、Command+Q(終了)、Command+W(閉じる)、Command+H(隠す)に割り当てられています。動作対象は、このサンプルアプリケーション自身です。
他のアプリケーションに対して、キー入力をさせる方法等、これ以上のことは残念ながらわかりません。
Mac OS Xでの、アクセシビリティ製品の開発について調べた情報は、別のページにまとめておきましたので、そちらをご覧下さい。
http://www.naotaka.com/blog/2009/05/11/accessibility/
また、Mac OS Xでの開発については、下記のようなメーリングリストや掲示板等が有用だと思われます。こちらで質問されれば、より的確な回答を頂けるのではないでしょうか。
5月 12th, 2009 at 15:47:27
うわー!!ありがとうございます。 ”たのしいCocoaプログラミング”を見ながら、Macのプログラミングに挑戦していました。 KeyEventの部分をコピーさせていただこうとブログを開きましたら、サンプルソースまで作られ掲載されてありました。 早速ダウンロードし、Buildして動作を確認いたしました。 ソースの中には、参考のURLの記載もあり、これまた感激です。 メーリングリストのご紹介も含め、とにかく感謝です。
いずれにしろ、「できクリック。」の移植は、おかげさまで早まると思います。 Mac版の「できクリック。」のページ公開の際は、このブログをリンクさせていただいてもよろしいでしょうか?
5月 12th, 2009 at 20:34:08
どうも、ありがとうございます。ほとんどお役に立てていないのに、恐縮です。
「できクリック。」の開発、頑張って下さい。
5月 13th, 2009 at 12:40:44
naotakaさんの作られたサンプルと同じものを作ってみようと、新規プロジェクトから作業してみました。 しかし、Interface Builderでつまずいております。 今までのWindowsのプログラミングとは違って、戸惑いがあります。 Macのプログラミングをされていらっしゃる方には、Interface Builderは、使いやすいんでしょうね。 今後もサンプルを参考に挑戦していきたいと思っております。
エールを頂きながらで恐縮ですが、ここでお願いがあります。 今回のサンプルコードで、「できクリック。」の移植は可能だと思っております。こちらから、Windowsのアプリのソースをご提供させていただきますので、Macへの移植をお願いできないでしょうか? マウスのボタン操作が困難な方のアプリとなります。 一日でも早期にご利用者様にご提供できたらと思っております。
この情報も大変貴重です。ありがとうございます。
5月 13th, 2009 at 14:11:12
Interface Builderは使い方が独特なので、戸惑われるのも当然ではないでしょうか。こちらのサイトのアドバイスが、的を射ていると思います。
Interface builder の操作は概ね直感的で簡単ながら、細かい部分で独特のコツがあります。ポイントは「とにかくいじりまくる」ことです。いろいろ試してみる事が大切です。失敗を恐れてはいけません(ただし、失敗しても元の状態に戻れるよう、バックアップコピーを取るなどの工夫は各自で行うべきでしょう)。また、インターネットを検索する事で様々な有益な情報が得られるでしょう。
http://cocomonar.sourceforge.jp/FAQ_Site/metal.html
移植のお話ですが、WindowsプログラミングはObject Pascal言語のDelphiをかじった程度なので、ソースコードを提供して頂いても、活用できそうもありません。Delphiでさえも、もう何年も触れていないため、よく覚えていませんし。
それよりも、もし問題がなければ、ソースコードを公開して、移植者を募ってみてはどうでしょう?腕に覚えのある方にお願いするのが、一番の近道ではないでしょうか。
5月 13th, 2009 at 21:57:17
まさにその通りでした。 下記サイトにヒントがありました。
http://www.macmacmac.mydns.jp/modules/tinyd0/index.php?id=20
“File’s Owner”の”delegate”と作成した”App Controller”のオブジェクトを接続します。
この作業も行なっておりませんでした。
見ようみまねで、naotakaさんの作られたサンプルの動作になりました。エールをありがとうございます。 また、分からないことが生じましたら、教えてください。