サブメニューのキャプチャ画像を作ってみる。複数のウィンドウのキャプチャには 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