メニューのキャプチャはできたが、画面一番上のメニューバー部分が入っていない。せっかくなのでメニューバーもキャプチャ画像へ入れたい。やてみよう。
まずメニューバーがどんなウィンドウかを WindowList で調べる。
この中の "Shared Menubar" が目的のウィンドウのようだ。layer=24を CGWindowLevel.h で調べると定義が見つかった。
CGWindowLevel.h
#define kCGMainMenuWindowLevel CGWindowLevelForKey(kCGMainMenuWindowLevelKey) /* 24 */
これを狙い撃ちしてキャプチャ画像へ入れてみる。前回のコードに kCGMainMenuWindowLevel のケースも window_id に含めるコードを加える。
AppController.m
if (layer == kCGMainMenuWindowLevel) {
windowIDs[widx++] = window_id;
}
ただメニューバーはスクリーンと同じ横幅を持っているので大きすぎる。できれば目的のメニューの幅だけ切り取れるようにしたい。そこでメニューの大きさを取っておく。サブメニューを含めることを考えてメニューの大きさを CGRectUnion で加えてすべて含む領域を作成する。
CGRect rect = CGRectZero;
CGRect rect_all = CGRectZero;
:
if (layer == kCGPopUpMenuWindowLevel) {
CGRectMakeWithDictionaryRepresentation(CFDictionaryGetValue(w, kCGWindowBounds), &rect);
rect_all = CGRectUnion(rect, rect_all);
windowIDs[widx++] = window_id;
}
初期値を CGRectZero にしておくとうまい具合にメニューバーも含まれる。
結果はこう。うまくいった。
深いサブメニューもこの通り。
なお kCGWindowBounds で取得できる CGRect はメニューの影を含んでいない。この為、サイズを最後に補正してある。
rect_all.size.width += 20;
rect_all.size.height += 25;
安易な方法だが実用上はこれで十分だろう。
ソース:MenuCapture-04.zip