ページ

2008年6月17日火曜日

メニューのキャプチャ(その9)ステータスバー

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

前回までのサンプルでステータスバーのメニューをキャプチャするとメニュー全体が含まれてしまう。


この場合は右上のステータスバーだけをキャプチャに含めたい。さてどうするか。

下図のようにステータスバーのメニューを出した状態で WindowListを調べてみた。



上2つが開いているメニューとサブメニューを表す。ステータスバーは Layer=25 ( kCGStatusWindowLevel ) で表される、ここでは4つのウィンドウが該当する。上から順番に次のようになる(名称は OwnerName)。

 SystemUIServer ステータスバーのアイコン群を表す(図では Spaces から「湖」※ユーザ名までが範囲)
 SimpleCap  これはステータスバー左のカメラのアイコンを表す
 Spotlight   これは一番右の Spotlightアイコンを表す
 SystemUIServer  最後のものは透明なウィンドウでキャプチャには無関係。 

開いているウィンドウがステータスバーに所属するかどうかを判断する材料がないか、WindowListをじっと眺めて共通項を探してみる。

すると OwnerPIDが使えそうなのがわかった。今回の場合、メニュー2つと、ステータスバー(SystemUIServer)の OwnerPID が一致しているのがわかる。これを判断に使ってみよう。

で、結果から先に話すとうまくいった。こんな感じ。


悪くない。

サンプル:MenuCapture-06.zip

コードが長いので今回は細かい解説を割愛するが、アルゴリズムは次のようになっている。番号はソースコード上のコメントに対応している。

 (1) ステータスーバーのウィンドウ情報を最初に専用の配列へ保管しておく。
 (2) メニューウィンドウをすべて配列に保管する。
   この時、(1)のウィンドウと OnwerPIDが同じものがあるかどうか調べておく。
 (3) 次の3通りのケースについてキャプチャ範囲を調整する
   [a] Context Menu
   [b] ステータスバーのメニュー
   [c] 通常のメニュー
 (4) (3)のサイズがスクリーンをはみ出した場合、スクリーンに収まるように補正する

 最後にキャプチャ画像を作成する。

アルゴリズムが泥臭いせいもあってコードはわかりづらいかもしれない。



念のため通常メニューの動作確認。問題なし。


コンテキストメニューも大丈夫。



- - - -
それにしても WindowListは役に立つ。これはこれでちゃんとしたツールに仕上げておきたいな。