我想获取当前正在运行的应用程序的窗口标题列表。
在Windows上,我可以使用EnumWndProc和GetWindowText函数。
在Linux上,我可以使用XGetWindowProperty和XFetchName函数。
那么,在Mac系统中有什么本地等价的函数吗?
我想获取当前正在运行的应用程序的窗口标题列表。
在Windows上,我可以使用EnumWndProc和GetWindowText函数。
在Linux上,我可以使用XGetWindowProperty和XFetchName函数。
那么,在Mac系统中有什么本地等价的函数吗?
以下是一些可能有用的参考资料:
NSWindowList()
-launchedApplications
和 +runningApplications
CGWindowListCreate()
和 CGWindowListCopyWindowInfo()
(需要10.5)CGSGetWindowProperty()
CGSGetWindowProperty
没有官方文档记录, 但我认为你可以按照以下方式(完全未经测试)使用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);
}
tell application "System Events" to get the title of every window of every process
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]
。CGSPrivate.h这个头文件并不直接兼容OS X 10.8,因为CGSGetWindowProperty()已经不存在了(实际上仍然存在,但你不能再链接它了)。所以请在CGSPrivate.h文件中添加以下两行代码 - 经过我多次搜索谷歌后,我自己找到了解决办法 - 就可以让它正常工作:
extern CGSConnection CGSDefaultConnectionForThread(void);
extern CGError CGSCopyWindowProperty(const CGSConnection cid, NSInteger wid, CFStringRef key, CFStringRef *output);
参考outis的代码,这里有一种遍历每个窗口标题的方法。我已在Mountain Lion上使用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);
个人而言,我建议这样做,因为辅助功能API非常麻烦,需要额外的权限。
希望这能帮到某些人!干杯!
CGS_xx
无法找到或已被10.6
弃用。我编写的是适用于10.8.2 ML的代码,肯定不能依赖于已弃用的东西。 - user1299518CGS_xx
来解决这个特定的问题。我只尝试了窗口标题,没有尝试其他任何东西。如果你觉得需要使用它,你应该发布多个版本的软件包(例如,针对10.6及以下或10.7+)。 - Alex Reinking