获取我的申请职位';使用Cocoa';s易访问性API

获取我的申请职位';使用Cocoa';s易访问性API,cocoa,accessibility,dock,Cocoa,Accessibility,Dock,如何使用可访问性API获取应用程序停靠图标的位置?找到了!使用作为参考,我能够根据我的需要塑造给定的示例代码: - (NSArray *)subelementsFromElement:(AXUIElementRef)element forAttribute:(NSString *)attribute { NSArray *subElements = nil; CFIndex count = 0; AXError result; result = AXUIElem

如何使用可访问性API获取应用程序停靠图标的位置?

找到了!使用作为参考,我能够根据我的需要塑造给定的示例代码:

- (NSArray *)subelementsFromElement:(AXUIElementRef)element forAttribute:(NSString *)attribute
{
    NSArray *subElements = nil;
    CFIndex count = 0;
    AXError result;

    result = AXUIElementGetAttributeValueCount(element, (CFStringRef)attribute, &count);
    if (result != kAXErrorSuccess) return nil;
    result = AXUIElementCopyAttributeValues(element, (CFStringRef)attribute, 0, count, (CFArrayRef *)&subElements);
    if (result != kAXErrorSuccess) return nil;

    return [subElements autorelease];
}

- (AXUIElementRef)appDockIconByName:(NSString *)appName
{
    AXUIElementRef appElement = NULL;

    appElement = AXUIElementCreateApplication([[[NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"] lastObject] processIdentifier]);
    if (appElement != NULL)
    {
        AXUIElementRef firstChild = (__bridge AXUIElementRef)[[self subelementsFromElement:appElement forAttribute:@"AXChildren"] objectAtIndex:0];
        NSArray *children = [self subelementsFromElement:firstChild forAttribute:@"AXChildren"];
        NSEnumerator *e = [children objectEnumerator];
        AXUIElementRef axElement;
        while (axElement = (__bridge AXUIElementRef)[e nextObject])
        {
            CFTypeRef value;
            id titleValue;
            AXError result = AXUIElementCopyAttributeValue(axElement, kAXTitleAttribute, &value);
            if (result == kAXErrorSuccess)
            {
                if (AXValueGetType(value) != kAXValueIllegalType)
                    titleValue = [NSValue valueWithPointer:value];
                else
                    titleValue = (__bridge id)value; // assume toll-free bridging
                if ([titleValue isEqual:appName]) {
                    return axElement;
                }
            }
        }
    }

    return nil;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    AXUIElementRef dockIcon = [self appDockIconByName:@"MYAPPNAME"];
    if (dockIcon) {
        CFTypeRef value;
        CGPoint iconPosition;
        AXError result = AXUIElementCopyAttributeValue(dockIcon, kAXPositionAttribute, &value);
        if (result == kAXErrorSuccess)
        {
            if (AXValueGetValue(value, kAXValueCGPointType, &iconPosition)) {
                NSLog(@"position: (%f, %f)", iconPosition.x, iconPosition.y);
            }
        }
    }
}

至于Mac OS El Capitan,看起来您不应该使用可访问性API获得图标的位置。问题是,图标不在应用程序的可访问性对象层次结构中,它可以在system Dock应用程序的层次结构中找到。沙盒应用程序不应访问其他应用程序的可访问性对象

approved Response中的代码不会对控制台中的
sandboxd
守护进程产生任何警告,看起来它没有违反任何规则。它使用函数
AXUIElementCreateApplication
创建顶级可访问性对象。文件指出,它:

Creates and returns the top-level accessibility object for the
application with the specified process ID.
不幸的是,这个顶级对象不是Dock图标的祖先。 我尝试运行代码,它计算第一个应用程序主菜单项的位置(与应用程序本身标题相同)。比较发生在这一行:

if ([titleValue isEqual:appName]) {
因此,我的应用程序的输出总是相同的:

position: (45.000000, 0.000000)

试图访问其他应用程序的可访问性对象时,控制台中出现警告。我想必须找到另一种计算图标位置的方法。

如果您的目标是10.6,那么获取Dock进程标识符要容易得多:
[[NSRunningApplication runningApplicationsWithBundleIdentifier:@“com.apple.Dock”]lastObject]processIdentifier]
@0xced:谢谢!根据您的建议,我对代码进行了一些清理。注意:建议的代码不适用于ARC。我的石膏有问题。。。