2012-06-15 13 views
2

실제로 마우스를 클릭하지 않고 Cocoa 응용 프로그램에서 마우스 클릭을 시뮬레이션하고 싶습니다. 현재 마우스 위치에서 클릭에 응답해야하는보기를 파악할 필요가 없습니다.NSWindow에서 마우스 클릭 시뮬레이션

나는 코코아 프레임 워크가 어떤 뷰가 응답해야하는지 파악할 수 있기를 원하므로 NSView 객체의 메소드 호출이 내가 찾고있는 것이라고 생각하지 않는다. 즉,이 메서드를 호출하게 될 메서드 호출이 필요하다고 생각합니다.

현재 CGEventCreateMouseEvent 및 CGEventPost를 사용하여 특정 전역 위치에서 마우스를 클릭하여이 작업을 수행 할 수 있습니다. 그러나이 기술은 실제로 마우스를 클릭합니다. 그래서 이것은 작동하지만, 나는 그 행동에 완전히 만족하지 않습니다. 예를 들어, CGEventPost가 호출되는 동안 키보드의 키를 누르고 있으면 해당 키가 이벤트로 랩핑됩니다. 또한, 다른 프로세스의 창을 클릭하여 시뮬레이션 할 창 위로 이동하면 CGEventPost 메서드가 해당 창에서 마우스를 클릭합니다. 즉, 프로세스 전반에 걸쳐 전 세계적으로 활동하고 있습니다. 하나의 창에서 작동하는 기술을 원합니다. NSWindow 객체의 어떤 것?

코코아 문서에서 "마우스 이벤트가 NSWindow 객체에 의해 NSView 객체에 전달되었습니다"라는 내용을 읽었습니다.

확인. 그래서 파견을하는 방법을 알고 싶습니다. 창에서이 메서드를 호출 한 다음 현재 마우스 위치가 주어지면 NSView에서 호출 할 프레임 워크를 파악하도록합니다.

도움을 주시면 감사하겠습니다. Cocoa 프레임 워크를 배우기 시작한 것이므로 여기에있는 용어 나 verbage가 맞지 않다면 사과드립니다.

[self mouseDown: nil]; 

을 그리고 화면에 마우스 위치를 얻을 :

+2

['- [NSApplication sendEvent :]'] (http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/Reference/Reference.html)은 기본적으로 입력 이벤트에 대한 엔트리 포인트; 거기에서 (일반적으로) 창으로 넘어갑니다. 즉, "시뮬레이션"과 "실제로"마우스를 클릭하는 것 사이의 구분은 명확하지 않습니다. 당신이 피하려고하는'CGEvent' 과정의 특징은 무엇입니까? 예를 들어 물리적 마우스 장치에는 서보가 없으므로 버튼을 움직이게됩니다 (실제로는 클릭하는 것입니다). –

+0

편집 됨. Thx 귀하의 의견을. –

+0

@JoshCaswell 이것은 좋은 접근 방법 인 것처럼 보이지만 작동시키지 못합니다. 코드를 게시 하겠지만 Objective C 브릿지를 사용하여 Clozure로 작성되었으므로 구문 분석에 약간 과중 할 수 있습니다. sendEvent를 사용하여 시뮬레이션 된 마우스 클릭의 예제를 온라인으로 찾을 수 없습니다. 우연히 할 수 있니? –

답변

4

실제 클릭에 대해 얼마나 충실하게 하는지를 아는 것은 어렵습니다. 예를 들어 클릭으로 앱을 활성화 하시겠습니까? 클릭하여 창을 맨 위로 가져 오시겠습니까? 열쇠 또는 ​​주요하게하기 위하여? 위치가 제목 표시 줄에있는 경우 잠재적으로 창이 닫히거나, 최소화하거나, 확대/축소하거나, 이동하려고합니까?

John Caswell이 지적했듯이 NSEvent에서 -[NSApplication sendEvent:]으로 전달하면 실제 이벤트의 처리를 거의 시뮬레이트합니다. 대부분의 경우 NSApplication은 이벤트를 이벤트 창과 해당 -[NSWindow sendEvent:] 메소드로 전달합니다. NSApplication 다른 작업을하지 않으려면 직접 창 -sendEvent: 메서드로 전달할 수 있습니다. 그러나 그것은 당신이 원하는 바에 따라 바람직한 행동을 무효화시킬 수 있습니다.

클릭 한 창 또는보기의 응답이 내부 이벤트 추적 루프를 실행하는 경우 어떻게됩니까? 그것은 동기가 될 것입니다; 즉, -sendEvent:을 호출하는 코드는 해당 루프가 완료 될 때까지 제어권을 다시 얻지 않으며 후속 이벤트를 전달할 수없는 경우 완료되지 않을 수 있습니다. 사실 이러한 루프는 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]을 통해 후속 이벤트를 검색하므로 합성 이벤트가 대기열에 없으면 볼 수 없습니다. 따라서 실제 이벤트를보다 효과적으로 시뮬레이션하려면 -[NSApplication postEvent:atStart:]을 사용하여 큐에 이벤트 (마우스 다운, 마우스 끌기, 마우스 업)를 게시해야 할 수 있습니다.

당신의 첫 번째 임무는 당신이 달성하고자하는 것에 대해 깊이 생각하고 잠재적 인 모든 함정과 모서리의 경우를 생각하고이를 어떻게 처리할지 결정하는 것입니다.

CGEvent... 항목의 경우 CGEventPostToPSN()을 사용하여 특정 프로세스에 일정을 게시 할 수 있으며 대상 창이 앞에있는 경우에도 다른 앱의 창을 클릭하지 않습니다. 그러나 대상 응용 프로그램 내에서 다른 창을 계속 클릭 할 수 있습니다.

1

이 같은 mouseDown:를 호출하여 마우스 클릭을 시뮬레이션 할 수

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

    NSPoint mouseLocation = [NSEvent mouseLocation]; 

    NSLog(@"x: %f", mouseLocation.x); 
    NSLog(@"y: %f", mouseLocation.y); 
} 
+0

올바른 마우스 이벤트 대상을 이미 알고 있어야합니다. –

+0

@ JoshCaswell 마우스 이벤트의 올바른 대상을 아는 것은 무엇을 의미합니까? –

+0

이것은 올바른 방향처럼 보이지만 마우스 클릭에 적절한 NSEvent 객체를 만들어야한다고 생각합니다. 그리고 그 코드에는 마우스 위치가 있어야합니다. 그렇습니까? –

2

확인을 클릭합니다. 그래서 파견을하는 방법을 알고 싶습니다. 창에서이 메서드를 호출 한 다음 현재 마우스 위치가 주어지면 NSView에서 호출 할 프레임 워크를 파악하도록합니다. 대상에 :

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

나는 당신이 원하는 모든이 다음 mouseDown를 호출하는 경우 그래서 모르는 문제에 완전히 명확하지 않다. 그러나 그렇게했다면 실제 마우스 클릭과 거의 똑같은 일이 될 것입니다.

이것은 실시간 클릭을 전달하는 데 사용되는 메시지입니다. 뷰 계층 구조를 탐색하고 자동으로 겹침, 숨겨진 메시지 등을 처리하고 원하는 경우보기 체인에서 각 단계를 방해하도록합니다. 보기가 자식보기에 클릭이 발생하지 않도록하려면 hitTest :를 먹으면됩니다. 즉, 실제 클릭에 영향을주는 것과 똑같은 방식으로 코드에 영향을 미칩니다. 클릭이 전달되면이 메소드는 항상 을 알려주며이 전달됩니다.

그러나 클릭이 전달되지 않을 수도있는 모든 이유를 처리하지는 않습니다 (첫 번째 모달, 모달 대화 상자 등을 허용). 또한 창과 점 (적절한 좌표계에서)을 알아야하지만, 시작하는 것처럼 들릴 것입니다.

+0

감사합니다. 이것은 간단한 접근처럼 보입니다. 가장 빨리 테스트하고 결과를 게시 할 것입니다. –

관련 문제