2

実際にマウスをクリックせずにCocoaアプリケーションでのマウスクリックをシミュレートしたいと思います。*現在のマウスの位置を指定して、クリックに応答するビューを特定する必要はありません。

どのビューが応答するかをCocoaフレームワークで処理してほしいので、NSViewオブジェクトのメソッド呼び出しが私が探しているものではないと思います。つまり、このメソッドを呼び出すことになるメソッド呼び出しが必要だと思います。

私は現在、CGEventCreateMouseEventとCGEventPostを使用して、特定のグローバルな場所でマウスをクリックすることでこれを機能させています。ただし、この手法では実際にはマウスをクリックします。したがって、これは機能しますが、動作に完全に満足しているわけではありません。たとえば、CGEventPostが呼び出されているときにキーボードのキーを押したままにすると、そのキーがイベントにラップされます。また、クリックをシミュレートするウィンドウ上に別のプロセスのウィンドウを移動すると、CGEventPostメソッドはそのウィンドウでマウスをクリックします。つまり、プロセス全体でグローバルに機能しています。1つのウィンドウで機能するテクニックが欲しいのですが。NSWindowオブジェクトに何かあるのでしょうか?

Cocoaのドキュメントで、「マウスイベントはNSWindowオブジェクトによってイベントが発生したNSViewオブジェクトにディスパッチされる」と読みました。

わかった。そこで、ディスパッチを行うために呼び出されるメソッドを知りたいのですが。ウィンドウでこのメソッドを呼び出してから、現在のマウスの位置を指定して、フレームワークに呼び出すNSViewを認識させます。

どんな助けでも大歓迎です。私はCocoaフレームワークを学び始めたばかりなので、ここでの用語/言い回しのいずれかが完全に正しくない場合はお詫び申し上げます。

4

3 に答える 3

4

実際のクリックで何が起こるかについて、あなたが探している忠実度を正確に知ることは困難です。たとえば、クリックしてアプリをアクティブにしますか?クリックしてウィンドウを一番上に表示しますか?それをキーにするかメインにするか?場所がタイトルバーにある場合、ウィンドウを閉じる、最小化する、ズームする、または移動する可能性がありますか?

John Caswellが指摘したように、適切に構築さNSEventれたものを渡す-[NSApplication sendEvent:]と、実際のイベントの処理が厳密にシミュレートされます。ほとんどの場合、NSApplicationはイベントをイベントのウィンドウとその-[NSWindow sendEvent:]メソッドに転送します。他のことをする可能性を避けたい場合は、ウィンドウのメソッドNSApplicationに直接ディスパッチすることができます。-sendEvent:しかし、それはあなたが望むものに正確に応じて、いくつかの望ましい振る舞いを打ち負かすかもしれません。

クリックされたウィンドウまたはビューの応答が内部イベント追跡ループを実行することである場合はどうなりますか?同期します。つまり、呼び出すコードは、-sendEvent:そのループが完了するまで制御を取り戻すことはなく、後続のイベントを配信できない場合は完了しない可能性があります。実際、このようなループは、を介して後続のイベントを検索するため-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]、合成イベントがキューにない場合、それらは表示されません。したがって、実際のイベントの処理をさらに適切にシミュレーションするには、を使用してイベント(マウスダウン、マウスドラッグ、マウスアップ)をキューに投稿する必要があります-[NSApplication postEvent:atStart:]

あなたの最初の仕事は、あなたが達成しようとしていること、すべての潜在的な落とし穴とコーナーケースについて本当に深く考え、それらをどのように処理したいかを決めることだと思います。

ものに関しては、CGEvent...を使用して特定のプロセスにイベントを投稿できCGEventPostToPSN()ます。ターゲットウィンドウの前にある場合でも、他のアプリのウィンドウはクリックされません。ただし、ターゲットアプリ内の別のウィンドウをクリックする場合があります。

于 2013-09-21T23:34:02.607 に答える
2

わかった。そこで、ディスパッチを行うために呼び出されるメソッドを知りたいのですが。ウィンドウでこのメソッドを呼び出してから、現在のマウスの位置を指定して、フレームワークに呼び出すNSViewを認識させます。

NSView *target = [[theWindow contentView] hitTest:thePoint];

私はあなたの問題について完全に明確ではないので、あなたがしたいのがターゲットでmouseDown:を呼び出すことだけであるかどうかはわかりません。しかし、そうすると、実際のマウスクリックで発生することとほぼ同じになります。

これは、ライブクリックの配信に使用されるメッセージです。ビューの階層をたどり、オーバーラップや非表示のメッセージなどを自動的に処理し、必要に応じてビューのチェーンの各ステップを干渉させます。ビューが子ビューのクリックを防ぎたい場合は、hitTest:を使用してそれを行います。これは、実際のクリックとまったく同じようにコードに影響を与えることを意味します。クリックが配信される場合、このメソッドは常にクリックが配信される場所を通知します。

ただし、クリックが配信されない可能性のあるすべての理由(FirstMouse、モーダルダイアログなどを受け入れる)を必ずしも処理できるわけではありません。また、ウィンドウとポイント(適切な座標系)を知っている必要がありますが、それはあなたが始めているもののように聞こえます。

于 2012-06-15T22:50:46.373 に答える
1

mouseDown:次のように呼び出すことで、マウスクリックをシミュレートできます。

[self mouseDown: nil];

そして、画面内のマウスの位置を取得するには:

-(void)mouseDown:(NSEvent *)theEvent {

    NSPoint mouseLocation = [NSEvent mouseLocation];

    NSLog(@"x:  %f", mouseLocation.x);
    NSLog(@"y:  %f", mouseLocation.y);
}
于 2012-06-15T20:26:47.147 に答える