ページ

2008年6月14日土曜日

メニューのキャプチャ(その6)サブメニュー(2)

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

サブメニューのキャプチャ画像を作ってみる。複数のウィンドウのキャプチャには CGWindowListCreateImageFromArray( ) が使える。使い方は以前画面キャプチャその18で紹介した。

主要なコードを下記へ示す。

AppController.m

  CGWindowID *windowIDs = calloc(20, sizeof(CGWindowID));

for (i=0; i < CFArrayGetCount(list); i++) {
w = CFArrayGetValueAtIndex(list, i);
CFNumberGetValue(CFDictionaryGetValue(w, kCGWindowLayer),
kCFNumberIntType, &layer);
CFNumberGetValue(CFDictionaryGetValue(w, kCGWindowNumber),
kCGWindowIDCFNumberType, &window_id);

if (layer == kCGPopUpMenuWindowLevel) {
windowIDs[widx++] = window_id;
}
}

if (widx > 0) {
NSString* path = [NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* filename = [path stringByAppendingPathComponent:@"cocoa_days_menu.png"];

CFArrayRef windowIDsArray = CFArrayCreate(kCFAllocatorDefault, (const void**)windowIDs, widx, NULL);
CGImageRef cgimage = CGWindowListCreateImageFromArray(CGRectNull, windowIDsArray, kCGWindowImageDefault);

NSBitmapImageRep *bitmap_rep = [[[NSBitmapImageRep alloc] initWithCGImage:cgimage] autorelease];
NSImage *image = [[[NSImage alloc] init] autorelease];
[image addRepresentation:bitmap_rep];

NSData* data = [bitmap_rep representationUsingType:NSPNGFileType
properties:[NSDictionary dictionary]];
[data writeToFile:filename atomically:YES];
}

free(windowIDs);


タイマー発火直後に layer==kCGPopUpMenuWindowLevel (101) のウィンドウを探し配列 windowIDs へ格納しておく。そしてこの配列を CFArrayRef に変換し、CGWindowListCreateImageFromArray ( )へ渡す。

実行結果。うまくいった。



3階層でもOK。


ソース:MenuCapture-03.zip