2009-05-12 8 views

답변

41

ApplicationServices 프레임 워크 내에있는 Accessibility API (plain-C)를 사용해야합니다. 예를 들어 :

먼저 응용 프로그램 객체를 생성 :

AXUIElementRef app = AXUIElementCreateApplication(targetApplicationProcessID); 

그런 다음이에서 창을 얻을. 창 목록을 열거하고 열거 할 수도 있고 가장 앞쪽에있는 창을 가져올 수도 있습니다 (사용하려는 모든 특성 이름은 AXAttributeConstants.h를 참조하십시오).

AXUIElementRef frontWindow = NULL; 
AXError err = AXUIElementCopyAttributeValue(app, kAXMainWindowAttribute, &frontWindow); 
if (err != kAXErrorSuccess) 
    // it failed -- maybe no main window (yet) 

이제이 윈도우의 속성이 변경되면 C 콜백 기능을 통해 알림을 요청할 수 있습니다.

먼저 당신이 알림을받을 콜백 함수가 필요합니다 :

void MyAXObserverCallback(AXObserverRef observer, AXUIElementRef element, 
          CFStringRef notificationName, void * contextData) 
{ 
    // handle the notification appropriately 
    // when using ObjC, your contextData might be an object, therefore you can do: 
    SomeObject * obj = (SomeObject *) contextData; 
    // now do something with obj 
} 

다음은 콜백 루틴을 관리하는 AXObserverRef가 필요이 4 단계 프로세스입니다. 이것은 위의 '응용 프로그램'요소를 만드는 데 사용되는 동일한 프로세스 ID가 필요합니다

AXObserverRef observer = NULL; 
AXError err = AXObserverCreate(applicationProcessID, MyObserverCallback, &observer); 
if (err != kAXErrorSuccess) 
    // handle the error 

것은 당신의 관찰자를 가지고하는 데, 다음 단계는 어떤 일의 통지를 요청하는 것입니다. 전체 목록은 AXNotificationConstants.h을 볼 수 있지만, 윈도우가 변경 당신은 아마 단지이 두 가지가 필요합니다 다음 contextData로 가정 된 '자기'개체가 전달 된 마지막 매개 변수 것을

AXObserverAddNotification(observer, frontWindow, kAXMovedNotification, self); 
AXObserverAddNotification(observer, frontWindow, kAXResizedNotification, self); 

참고. 이것은 유지되지 않으므로이 객체가 사라질 때 AXObserverRemoveNotification에 전화하는 것이 중요합니다.

CFRunLoopAddSource([[NSRunLoop currentRunLoop] getCFRunLoop], 
        AXObserverGetRunLoopSource(observer), 
        kCFRunLoopDefaultMode); 

AXUIElementRef들 :

는 이제 (실제로 전혀 이상) 비동기 방식으로 이러한 알림을 보낼 수 있도록 runloop에 관찰자를 첨부 할, 당신의 관찰자를 가지고 및 알림 요청을 추가 한 데 CoreFoundation 스타일의 객체이므로 CFRelease()을 사용하여 깨끗하게 처리해야합니다. 예를 들어 청결을 위해 frontWindow 요소를 얻은 후에는 CFRelease(app)을 사용하게됩니다. 더 이상 응용 프로그램이 필요 없기 때문입니다.

가비지 컬렉션에 관한 참고

는 :

__strong AXUIElementRef frontWindow; 

이가이 기준을 추적하는 가비지 수집기 지시 그래서처럼 선언 멤버 변수로서 AXUIElementRef 유지. 할당 할 때 GC 및 비 GC와의 호환성을 위해 다음을 사용하십시오.

frontWindow = (AXUIElementRef) CFMakeCollectable(CFRetain(theElement)); 
+0

매우 흥미롭고 흥미로운 답변입니다. 감사! –

+1

위대한 출발점! 문서 https://developer.apple을 살펴 보는 것을 잊지 마십시오.co.kr/library/mac/documentation/Accessibility/Reference/AccessibilityLowlevel/AccessibilityLowlevel.pdf 및 샘플 응용 프로그램 https://developer.apple.com/library/mac/#samplecode/iChatStatusFromApplication/Introduction/Intro.html – vinzenzweber

+2

또한 UIElementInspector 샘플 프로젝트가 매우 도움이되는 것 같습니다. https://developer.apple.com/library/mac/#samplecode/UIElementInspector/Introduction/Intro.html – vinzenzweber

3

더 많은 연구가 "석영 표시 서비스"내 요구에 대한

흥미로운 기능은 CGRegisterScreenRefreshCallback되어 켜져.

관련 문제