我想获取当前正在运行的应用程序的窗口标题列表。
在Windows上我有EnumWndProc和GetWindowText。
在Linux上我有XGetWindowProperty和XFetchName。
什么是Native Mac等价物?
答案 0 :(得分:12)
一些可能有用的参考资料:
NSWindowList()
-launchedApplications
和+runningApplications
CGWindowListCreate()
和CGWindowListCopyWindowInfo()
(需要10.5)CGSGetWindowProperty()
CGSGetWindowProperty
是not officially documented,但我相信您可以将其与NSWindowList()
项目一起使用,如下所示(完全未经测试):
OSErr err;
CGSValue titleValue;
char *title;
CGSConnection connection = _CGSDefaultConnection();
int windowCount, *windows, i;
NSCountWindows(&windowCount);
windows = malloc(windowCount * sizeof(*windows));
if (windows) {
NSWindowList(windowCount, windows);
for (i=0; i < windowCount; ++i) {
err = CGSGetWindowProperty(connection, windows[i],
CGSCreateCStringNoCopy("kCGSWindowTitle"),
&titleValue);
title = CGSCStringValue(titleValue);
}
free(windows);
}
在AppleScript中,它非常简单:
tell application "System Events" to get the title of every window of every process
您可以使用NSAppleScript从应用程序中调用applescript,或使用appscript作为ObjC-AppleScript桥。使用Leopard,您可以使用Scripting Bridge(更多未经测试的代码):
SystemEventsApplication *systemEvents = [SBApplication applicationWithBundleIdentifier:@"com.apple.systemevents"];
SBElementArray *processes = [systemEvents processes];
for (SystemEventsProcess* process in processes) {
NSArray *titles = [[process windows] arrayByApplyingSelector:@selector(title)];
}
如果你不在乎可读性,你甚至可以在长时间的通话中试一试。
SystemEventsApplication *systemEvents = [SBApplication applicationWithBundleIdentifier:@"com.apple.systemevents"];
NSArray *titles = [[[systemEvents processes]
arrayByApplyingSelector:@selector(windows)]
arrayByApplyingSelector:@selector(arrayByApplyingSelector:)
withObject:@selector(title)];
编译器会抱怨@selector(title)
类型错误,但它应该有效。手动转动一些代表团,您可以将通话转为[[[systemEvents processes] windows] title]
。
答案 1 :(得分:8)
浮动的CGSPrivate.h标题与OS X 10.8不直接兼容,因为CGSGetWindowProperty()不再存在(嗯,确实如此,但你不能再链接到它)。所以将这两行添加到CGSPrivate.h文件中 - 我在搜索Google几个小时之后继续自己想出来 - 让它工作:
extern CGSConnection CGSDefaultConnectionForThread(void);
extern CGError CGSCopyWindowProperty(const CGSConnection cid, NSInteger wid, CFStringRef key, CFStringRef *output);
调整outis的代码,这是一种迭代每个窗口标题的方法。我用山狮上的clang 4.2对此进行了测试:
CFStringRef titleValue;
CGSConnection connection = CGSDefaultConnectionForThread();
NSInteger windowCount, *windows;
NSCountWindows(&windowCount);
windows = (NSInteger*) malloc(windowCount * sizeof(NSInteger));
if (windows) {
NSWindowList(windowCount, windows);
for (int i = 0; i < windowCount; ++i)
{
CGSCopyWindowProperty(connection, windows[i], CFSTR("kCGSWindowTitle"), &titleValue);
if(!titleValue) //Not every window has a title
continue;
//Do something with titleValue here
}
free(windows);
}
我发现的其他一些内容包括以下内容:
所以,如果你想把它作为一个C字符串,写下这样的东西:
char *cTitle[127] = {0};
CFStringGetCString(titleValue,cTitle,127,kCFStringEncodingMacRoman);
就个人而言,我建议这样做,因为Accessibility API总是很痛苦,需要额外的权限。
希望这有助于某人!干杯!