ページ

2008年6月15日日曜日

メニューのキャプチャ(その7)メニューバーを含める

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

メニューのキャプチャはできたが、画面一番上のメニューバー部分が入っていない。せっかくなのでメニューバーもキャプチャ画像へ入れたい。やてみよう。


まずメニューバーがどんなウィンドウかを 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