【问题标题】:Check if main window of application is open and loaded检查应用程序的主窗口是否打开并加载
【发布时间】:2016-03-18 18:28:57
【问题描述】:
我的应用程序的一部分是打开应用程序并保留它们打开的工作空间。我的问题是检查主应用程序窗口是否已打开,以便我可以转到下一个工作空间。通常,我可以检查 A 窗口是否打开了该应用程序,但对于某些应用程序(例如 IntelliJ IDEA),有一个加载窗口不是主窗口,但仍显示在 CGWindowListCopyWindowInfo() 中。我检查应用程序的窗口是否打开,然后检查它是否有标题。这适用于 IntelliJ IDEA 应用程序,但是像计算器这样的应用程序具有应用程序的主窗口而没有窗口标题,代码会进入无限等待循环。我用谷歌搜索并没有想出任何东西,这是我的应用程序中需要修复的最后一件事。
稍后会添加代码(当我有我的电脑时)
TL;DR:
我需要检查应用程序的主窗口是否打开。 (像 INtelliJ IDEA 这样的应用有一个加载窗口,这个窗口需要保存在一个工作空间中。
【问题讨论】:
标签:
objective-c
macos
cocoa
window
mainwindow
【解决方案1】:
经过大量测试,如果其他人需要,我已经想出了一个答案。
我使用了无障碍框架,代码如下:
- (NSInteger)numberOfWindowsOpenFromApplicationWithPID:(NSInteger)PID
{
NSInteger count = 0; // For return.
AXUIElementRef anApp = AXUIElementCreateApplication((pid_t)PID);
CFTypeRef aChildren;
AXUIElementCopyAttributeValue(anApp, kAXChildrenAttribute, &aChildren);
SafeCFRelease(anApp);
if (aChildren) {
for (NSInteger i = 0; i < CFArrayGetCount(aChildren); i++) {
AXUIElementRef aChild = CFArrayGetValueAtIndex(aChildren, i);
// Get subrole
CFTypeRef aSubrole;
AXUIElementCopyAttributeValue(aChild, kAXSubroleAttribute, &aSubrole);
NSString *aSubroleString = CFBridgingRelease(aSubrole);
if (aSubroleString) {
// Not a menu :3
if ([aSubroleString isEqualToString:@"AXStandardWindow"]) {
count++;
}
}
}
SafeCFRelease(aChildren);
} else {
return 0;
}
return count;
}
此代码返回在当前工作区中为具有 PID 的应用打开的(主)窗口数。然后我从 PID 中获取 AXApplication,然后从中获取孩子。如可访问性检查器中所见:
子项是窗口和菜单栏。主窗口有一个子角色AXStandardWindow。我的代码循环遍历子角色,然后检查子角色。