しつこく CGWindowListCopyWindowInfoの話題を。現在表示中のウィンドウリストをNSTableViewで表示させる。
ADCのサンプルがまさにそういうアプリなのだが、作成中のアプリで必要なので自分で組み立ててみる。
こんな感じ。
ソース:WindowList.zip
バインディングを使うとあっと言う間?にできる。組み立ては下のようになる。
注意点としては NSArrayController を介している為、直接 windowList(NSMutableArray)を変更しても NSTableViewに反映されないこと。NSArrayControllerのメソッド(addObject:など)を使うか、変更後に rearrangeObjectsを呼出す必要がある。NSTableViewの reloadData や setNeedDisplay: を使ってもダメ。
メイン部分のコードを掲載しておく。
MyController.m
-(void)reloadList
{
[windowList removeAllObjects];
CFArrayRef list =CGWindowListCopyWindowInfo(
(kCGWindowListOptionAll|kCGWindowListOptionOnScreenOnly|kCGWindowListExcludeDesktopElements), kCGNullWindowID);
CFDictionaryRef w;
CFIndex i;
CGWindowID windowID;
CFStringRef name;
CFStringRef owner;
CGRect rect;
for (i=0; i < CFArrayGetCount(list); i++) {
w = CFArrayGetValueAtIndex(list, i);
CFNumberGetValue(CFDictionaryGetValue(w, kCGWindowNumber),
kCGWindowIDCFNumberType, &windowID);
name = CFDictionaryGetValue(w, kCGWindowName);
owner = CFDictionaryGetValue(w, kCGWindowOwnerName);
CGRectMakeWithDictionaryRepresentation(CFDictionaryGetValue(w, kCGWindowBounds), &rect);
WindowItem* item = [[[WindowItem alloc] init] autorelease];
[item setValue:[NSNumber numberWithInt:windowID] forKey:@"windowID"];
[item setValue:(NSString*)name forKey:@"name"];
[item setValue:(NSString*)owner forKey:@"owner"];
NSRect rect2 = NSRectFromCGRect(rect);
[item setValue:NSStringFromRect(rect2) forKey:@"frame"];
[windowList addObject:item];
}
[arrayController rearrangeObjects];
}
- - - -
作ってはみたものの、表示情報が足りないな。
全情報を表示するよう手を加えよう。