通过OSX Accessibility API获取窗口号

我正在研究一个应用程序,它可以在屏幕上移动第三方应用程序的窗口。

为了获得所有当前打开的窗口的概述,我使用

CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);

这将返回一个定义每个打开窗口的字典数组。 以下是返回的示例性字典:

{
    kCGWindowAlpha = 1;
    kCGWindowBounds =         {
        Height = 442;
        Width = 475;
        X = 3123;
        Y = "-118";
    };
    kCGWindowIsOnscreen = 1;
    kCGWindowLayer = 0;
    kCGWindowMemoryUsage = 907184;
    kCGWindowName = Untitled;
    kCGWindowNumber = 7328;
    kCGWindowOwnerName = TextEdit;
    kCGWindowOwnerPID = 20706;
    kCGWindowSharingState = 1;
    kCGWindowStoreType = 2;
    kCGWindowWorkspace = 3;
},

该字典充满了其他地方使用的良好信息,但缺少可用于修改窗口位置的可访问性对象。 窗口号码清楚地标识了Windows。

我现在使用PID(kCGWindowOwnerPID)为窗口应用程序创建一个辅助功能对象:

AXUIElementRef app = AXUIElementCreateApplication(pid);

接着检索应用程序使用AXUIElementCopyAttributeValues打开的​​所有窗口的列表:

NSArray *result;

AXUIElementCopyAttributeValues(
                               (AXUIElementRef) app, 
                               kAXWindowsAttribute,
                               0,
                               99999,
                               (CFArrayRef *) &result
                               );

这工作并返回一个AXUIElements数组。 这是我卡住的地方。 似乎没有API调用来检索辅助功能对象的窗口号。 有没有办法

a)找到辅助对象的窗口号(最终遍历数组并找到正确的窗口)

要么

b)否则明确地将CGWindowListCopyWindowInfo返回的数组中描述的窗口与AXUIElementCopyAttributeValues返回的辅助功能对象进行匹配?


我们最终聘请了专门的可访问性开发人员来完成这项任务。

事实证明,如果不使用未记录的API(在我们的情况下不行),则无法做到这一点。

幸运的是,有一个实用的解决方法:

在应用的所有打开的窗口中循环。 获取他们的位置,大小和标题:

AXUIElementCopyAttributeValue(target, kAXPositionAttribute, CFTypeRef*)&posValue);
AXUIElementCopyAttributeValue(target, kAXSizeAttribute, (CFTypeRef*)&sizeValue);
AXUIElementCopyAttributeValue(target, kAXTitleAttribute, (CFTypeRef*)&titleValue);

接下来,将位置和大小转换为实际的CGPointCGSize值:

AXValueGetValue(posValue, kAXValueCGPointType, &point);
AXValueGetValue(sizeValue, kAXValueCGSizeType, &size);

将大小,位置和标题与CGWindowListCopyWindowInfo()对象返回的值进行比较。 如果它们匹配,则可以安全地假定它是您正在查找的窗口,并使用已打开的AXUIElement(我们的target )来处理它。

在OSX上循环浏览所有打开的窗口的开销可以忽略不计。 有多少个窗户同时打开的数量相当低。

另外,尽管这不是100%准确的(可能两个窗口具有相同的位置,大小和标题),但在迄今为止发生这种情况时,我们还没有遇到实际使用中的任何情况。


有一个私有函数用于为给定窗口的AX对象获取CG窗口号: _AXUIElementGetWindow 。 SO讨论中的更多细节在OS X上唯一标识活动窗口看起来好像没有公共API以100%的概率完成任务。 通过标题和框架标识窗口(如上面的答案中所述)将适用于99.9%的案例。

链接地址: http://www.djcxy.com/p/49955.html

上一篇: Getting Window Number through OSX Accessibility API

下一篇: Window move and resize APIs in OS X