ページ

2008年4月8日火曜日

WindowList(その1) - しつこく CGWindowListCopyWindowInfo

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

しつこく 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];
}



- - - -
作ってはみたものの、表示情報が足りないな。
全情報を表示するよう手を加えよう。