2013-02-02 49 views

回答

3

下面是一些示例代碼,它只是在桌面上進行截圖。

CFArrayRef onScreenWindows = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID); 
CFArrayRef nonDesktopElements = CGWindowListCreate(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID); 
CFRange range = CFRangeMake(0, CFArrayGetCount(nonDesktopElements)); 
CFMutableArrayRef desktopElements = CFArrayCreateMutableCopy(NULL, 0, onScreenWindows); 
for (int i = CFArrayGetCount(desktopElements) - 1; i >= 0; i--) 
{ 
    CGWindowID window = (CGWindowID)(uintptr_t)CFArrayGetValueAtIndex(desktopElements, i); 
    if (CFArrayContainsValue(nonDesktopElements, range, (void*)(uintptr_t)window)) 
     CFArrayRemoveValueAtIndex(desktopElements, i); 
} 

CGImageRef cgimage = CGWindowListCreateImageFromArray(CGRectInfinite, desktopElements, kCGWindowListOptionAll); 
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithCGImage:cgimage]; 
NSData* data = [rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]]; 
[data writeToFile:@"/tmp/foo.png" atomically:YES]; 

你應該能夠擴展一般的方法來獲取Dock和菜單欄。您構建您感興趣的窗口ID列表,然後致電CGWindowListCreateImageFromArray()。我通過請求所有的屏幕窗口,然後除了桌面元素之外的所有屏幕窗口來計算桌面元素的窗口ID。桌面元素是第一個列表中不在第二個列表中的元素。

獲取菜單欄和Dock的窗口ID並不像那樣直接,因爲在CGWindowList API中沒有與其直接對應的選項。您需要使用CGWindowListCopyWindowInfo()CGWindowListCreateDescriptionFromArray()來獲取屏幕窗口的描述字典數組,並檢查其內容。最有用的密鑰可能是kCGWindowLayer。除了使用我的示例代碼中的技術獲得的桌面元素外,我認爲您還需要CGWindowLevelForKey(kCGDockWindowLevelKey)以上的任何內容。

+0

非常感謝!它像手套一樣安裝! –

+1

不客氣。我應該提到我的示例代碼沒有包含適當的內存管理。當你完成它們的時候,不要忘記'CFRelease()'數組和CGImage。如果你不使用ARC,你也應該釋放'NSBitmapImageRep'。 –

+0

我會記得正確地衝洗一切在那裏創建:D這是一個很好的建議! –