4

編集 - これについて多くの意見が得られないため、ここにスキニーがあります。キーボード イベントを PSN に投稿しています。次に、別のウィンドウに切り替えて、さらにいくつかのイベントを投稿し (今回は tat セッション レベル)、最初のウィンドウに戻ります。PSN への投稿を再開しても、何も起こりません。マウスまたはスクロール ホイールを動かすまで。これはなぜですか? また、どうすれば回避できますか (修正しない場合)?

オリジナル - いくつかのキーボード イベントを PSN に投稿するループを設定すると、最初の起動時以外は正常に動作することがわかりました。イベントは、マウスで手動で何かをしたときにのみ投稿されるようです-わずかに動かしただけでも。詳細はこちらです。

外部アプリケーションにはテキスト行のリスト ボックスがあり、コピー コマンドを投稿して (そしてペーストボードをチェックして) 読んでいます。残念ながら、これがこのテキストを取得する唯一の方法です。

ときどき、アプリケーションがリストからフォーカスを外しますが、これは私が検出できます。これが発生した場合、フォーカスを戻す最も確実な方法は、マウス イベントを送信してリストの真上にあるテキスト フィールドをクリックし、「タブ」キーボード イベントを送信してフォーカスをリストに移動することです。

そのため、起動時にループが正常に実行され、リストを下にスクロールしてテキストをコピーします。フォーカスが移動すると、それが正常に検出され、イベントが送信されてフォーカスがリストに戻ります。しかし、何も起こらないようです。ループはフォーカスが変更されたことを検出し続けますが、マウスを動かしたときにのみイベントが機能します。または、スクロール ホイールを使用することもできます。変。

これが初めて発生すると、問題なく動作します。フォーカスが移動するたびに、何もしなくても PSN イベントが元に戻ります。

ループで実行されるコードは次のとおりです-動作することが確認されています:

    //copy to pasteboard - CMD-V
e3 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)8, true);
CGEventSetFlags(e3, kCGEventFlagMaskCommand);
CGEventPostToPSN(&psn, e3);
CFRelease(e3);
e4 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)8, false);
CGEventPostToPSN(&psn, e4);
CFRelease(e4);

//move cursor down
e1 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)125, true);
CGEventPostToPSN(&psn, e1);
CFRelease(e1);
e2 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)125, false);
CGEventPostToPSN(&psn, e2);
CFRelease(e2);

そして、ここでフォーカスを切り替え、これも機能します (最初に必要な場合を除く)。

    //click in text input box - point is derived earlier
e6 = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, point, 0);
CGEventPostToPSN(&psn, e6);
CFRelease(e6);
e7 = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, point, 0);
CGEventPostToPSN(&psn, e7);
CFRelease(e7);

//press tab key to move to chat log table
CGEventRef e = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)48, true);
//CGEventPost(kCGSessionEventTap, e);
CGEventPostToPSN(&psn, e);
CFRelease(e);
CGEventRef e11 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)48, false);
CGEventPostToPSN(&psn, e11);
CFRelease(e11); 
4

2 に答える 2

2

ねえ、私はそれがあなたが聞きたいことではないことを知っていますが、applescriptはこの種のことに対してはるかにうまく機能します-コピーコマンドを投稿してテキストフィールドを読み取り、近くのアイテムにクリックイベントを送信してフォーカスを設定し、次にタブイベントを送信します-それは本当に最高ではありませんそれを行う方法。

イベントをシミュレートする際の問題は、それらを生成することがすべてではないということです。ターゲット アプリがそれらを正しく解釈した場合にのみ、それらは「イベント」になります。対象のアプリがココアアプリなのか知っていますか?

たとえば、コードの 2 番目のビットでは、4 つのイベントを作成します。ターゲット アプリは、あまり制御できないイベント処理ループを実行し、キューに入れられたイベントをチェックする必要があります。これを行うと、マウス ダウン、マウス アップ、キー ダウン、キー アップが同時に検出されます。これらの同時イベントをマウスクリックとキープレスとして解釈したいのですが、そうすると誰が言えますか?

イベントキューのフラッシュの組み合わせをミックスに追加し、ターゲットアプリにrunloop を実行させ、シミュレートされたイベントの間に一時停止を挿入し、イベントのタイムスタンプをいじること、これを機能させることができるかもしれませんが、おそらくうまくいきません。それほど信頼できるものではありません。

Applescript では、別のアプリでテーブルの行 3 のテキストを取得できます。

tell application "System Events"
  tell process targetAppName
    set frontmost to true
    tell window named windowTitle
      tell table 1
        set value of attribute "AXFocused" to true
        set txtField to first text field of row 3
        return value of txtField
      end tell
    end tell
  end tell
end tell

cocoa アプリから、文字列を Applescript として実行したり、さまざまなスクリプトで関数を呼び出したり、変数を渡したり、値を返したりすることができます。

于 2010-05-25T12:14:31.343 に答える
1

null CGEventSourceRef でイベントを作成する代わりに、次の方法で入力ソースを作成してみてください。

CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);

このメーリングリストメッセージによると、これがCGEventCreateXXXEventでのイベント投稿成功の秘訣のようです。Google 検索は、多くの開発者がこれに問題を抱えていることを示していますが、これは私が見つけた 1 つの成功した投稿であり、(NULL ではなく) 適切な CGEventSourceRef が、この例と他のすべての例の 1 つの違いのようです。見つけました。キーボードイベントの投稿に関する問題を解決しました。

于 2010-11-08T23:53:21.060 に答える