首先创建一个应用程序对象:
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.这需要您用来创建上面“app”元素的进程ID相同:
AXObserverRef observer = NulL;AXError err = AXObserverCreate( applicationProcessID,MyObserverCallback,&observer );if ( err != kAXErrorSuccess ) // handle the error
看到你的观察者,下一步是要求通知某些事情.请参阅AXNotificationConstants.h的完整列表,但是对于窗口更改,您可能只需要这两个:
AXObserverAddNotification( observer,frontwindow,kAXMovednotification,self );AXObserverAddNotification( observer,kAXResizednotification,self );
请注意,最后一个参数是将假定的“self”对象作为contextData传递.这不保留,所以当这个对象消失时,调用AXObserverRemoveNotification是非常重要的.
看到您的观察员并添加了通知请求后,您现在要将观察器附加到您的跑马圈,以便您可以以异步方式(或者根本不用)发送这些通知:
CFRunLoopAddSource( [[NSRunLoop currentRunLoop] getCFRunLoop],AXObserverGetRunLoopSource(observer),kcfRunLoopDefaultMode );
AXUIElementRefs是CoreFoundation样式的对象,因此您需要使用CFRelease()来清理它们.为了清洁,例如,一旦您获得了frontwindow元素,您就可以使用CFRelease(应用程序),因为您将不再需要该应用程序.
关于垃圾收集的注意事项:要保持AXUIElementRef作为成员变量,请如下声明:
__strong AXUIElementRef frontwindow;
这指示垃圾收集器跟踪这个引用.分配时,为了与GC和非GC兼容,请使用以下命令:
frontwindow = (AXUIElementRef) CFMakeCollectable( CFRetain(theElement) );总结
以上是内存溢出为你收集整理的objective-c – 我的应用程序如何检测到另一个应用程序的窗口的更改?全部内容,希望文章能够帮你解决objective-c – 我的应用程序如何检测到另一个应用程序的窗口的更改?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)