Inside 窓の調べ |
窓の調べは、Windowsのウィンドウ関連APIの調査目的で作成したツールです。
使用目的は2つあり調査対象のWindowの状態に関する情報をする事と、Windowに対する操作に対して実際の振る舞いを確認する事です。
この資料は、窓の調べの操作マニュアルでなく実際の表示内容とそれを取得するAPIの関連をドキュメントとして整理する目的で作成します。
窓の調べのダウンロードは、窓の調べサポートページから行えます。
メインパルは一覧で選択した主ウィンドウに関する情報表示と操作を行います。
画面左下の一覧表示を行います。一覧は3秒周期で現在のWindows管理下のウィンドウを列挙します。
A)一覧更新 自動更新出ないときに手動で一覧を更新します。 B)自動更新 チェックを入れると一覧を3秒周期で自動的に更新します。 C)Visibleのみ チェックを入れると表示中のウィンドウのみ一覧表示します。 D)Title付き ウィンドウタイトルを持つウィンドウのみ一覧表示します。 E)子ウィンドウ情報 子ウィンドウ情報ウィンドウを表示します。 (->後方参照) |
ここで使用しているウィンドウ情報を取得するAPIは以下を参照
ウィンドウの列挙 | EnumWindow() | 引数でコールバックモジュールを登録します。 |
コールバック関数 | BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) | TRUEを返すと処理続行します。 今回は全て列挙するので常にTRUEを返します |
ウィンドウタイトルの取得 | GetWindowText() | |
プロセスIDの取得 | GetWindowThreadProcessId() | |
プロセス名の取得 | OpneProcess(),EnumProcessModules(),GetModuleBaseName() | Pid->プロセンスハンドル->モジュールハンドルと変換して最終的にGetModuleBaseName()でプロセス名を取得する |
メイン画面上段のウィンドウ状態の表示とウィンドウ操作のパネルについて説明します。
このパネル表示は一覧で選択したウィンドウに関する情報を0.5秒周期で更新します。
SHGetFileInfo()で取得したアイコンを表示する | |
GetWindowRect()で取得したウィンドウ矩形の情報を表示 | |
GetWindowLong()で取得したウィンドウスタイルビットの情報を表示します。 WinStyle,ExStyleボタンを押下するとそれぞれのウィンドウスタイルビットの詳細表示およびスタイルビットの変更が行えます。ウィンドウのスタイルビットの変更はSetWindowLong()関数で行います。ウィンドウスタイルの変更はSetWindowLong()で変更即有効となるもの、再描画したときに有効になるもの、他プロセスからは操作できないのもなど様々な挙動となります。窓の調べではSetWindowLong()でスタイルビットを変更した場合Redraw()関数を実行しています。 |
|
レイヤードウィンドウの情報表示と設定を行います。レイヤード情報はGetLayeredWindow()で取得しますが、この関数は基本的に他プロセスの情報を正確取得できません。(設定直後のみ取得できます)設定ボタンを押下するとレイヤードウィンドウに関する設定が行えます。この時に拡張ウィンドウスタイルビットでWS_EX_LAYEREDが設定されていない場合は自動で設定を行います。Layeredウィンドウにすると透過色と透明度の設定が行えます。 | |
ウィンドウの移動操作をMoveWindow()関数を使用して行います。矢印キーを1回押下すると現在位置に対して矢印の方向に1px分移動します。中央のJumpボタンを押下すると移動ダイアログを表示し任意に座標にウィンドウの移動ができます。 |
|
表示しているAPIで取得した状態を色で表示しています。TRUEの場合は緑、FALSEの場合は赤で表示します。 | |
GetWindowPlacement()で取得できるWINDOWPLACEMENT構造体の内容を表示しています。 | |
SetWindowPos()でZ-Orderの指定をTOPMOST指定と解除を行います。 | |
ウィンドウ操作APIの発行を行います。 SW_SHOW,SW_HIDEはShowWindow()APIのボタン名の引数で実行します。 最小化、最大化ボタンはウィンドウの最小化ボタン、最大化ボタンをシュミレートします。 ShowWindow(hWnd, SW_SHOWMINIMIZED) ShowWindow(hWnd, SW_SHOWMAXIMIZED) でそれぞれ実装しています。 元のサイズボタンは、元のサイズボタンをシュミレートします。 これもShowWindow(hWnd, SW_SHOWNOMAL)でも可能ですが、窓の調べでは、 SendMessage(m_hTgtWin, WM_SYSCOMMAND,(WPARAM)SC_RESTORE, (LPARAM)0) にて実装しています。 |
|
SendMessage()WM_CLOSEを送信します。 | |
サスペンド、サスペンド解除メッセージを送信します。 それぞれ、次の書式で送信します。 SendMessage(hWnd, WM_POWERBROADCAST,(WPARAM)PBT_APMSUSPEND, (LPARAM)0) SendMessage(hWnd, WM_POWERBROADCAST,(WPARAM)PBT_APMRESUMESUSPEND, (LPARAM)0) |
|
QueryEndSession,及びEndSessionメッセージを送信します。 それぞれ、次の書式で送信します。 ret = SendMessage(hWnd, WM_QUERYENDSESSION ,(WPARAM)0, (LPARAM)ENDSESSION_LOGOFF) SendMessage(hWnd, WM_ENDSESSION ,(WPARAM)ret, (LPARAM)ENDSESSION_LOGOFF); ※QueryEndSessionの戻り値はEndSessionメッセージのWPARAMに引き継ぎます。 |
|
PostMessage()でF5キーメッセージを送信します。 書式は次の通りです。 PostMessage(hWnd, WM_KEYDOWN, VK_F5, 0) 通常F5キーは再表示のアクションとなります。 |
|
タスクバーへの登録・削除をCOMインターフェースで行います。 -登録(初期化とオブジェクト解放省略) hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (void**)&pTaskbarList); pTaskbarList->HrInit(); hr = pTaskbarList->AddTab(hWnd); -削除(初期化とオブジェクト解放省略) hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (void**)&pTaskbarList); pTaskbarList->HrInit(); hr = pTaskbarList->DeleteTab(hWnd); |
画面右下にウィンドウイメージの表示を行います。
1)PrintWindowボタン 単純にPrintWindow()APIを使用してイメージを取得します。 2)SufaceCaptureボタン デスクトップイメージとしてイメージを取得します。この場合ウィンドウの重なりがあった場合重なったウィンドウ部分がそのままイメージ取得されます 3)IconicCaptureボタン(デフォルトキャプチャ方法) 最小化状態のウィンドウを判定して最小化されていれば一旦最小化を解除してキャプチャををおこないます。 この方法は、ウィンドウ状態に関係なくウィンドウイメージの取得が可能です。(ただし、非表示のウィンドウはキャプチャできません。) 4)HideCaptureボタン 非表示のウィンドウを一旦ウィンドウ状態を表示状態に変更してキャプチャします。(キャプチャ後元の状態に戻します。) 5)Copy Clipboadボタン 現在保持しているイメージデータをクリップボードに転送します。 |
各キャプチャボタンはキャプチャのアルゴリズムを変えてキャプチャします。
イメージの表示は実際のサイズから表示サイズにスレトッチして表示しています。
メインウィンドウの子ウィンドウ情報ボタンを押下すると子ウィンドウ情報画面を表示します。
画面上段に子ウィンドウの一覧を表示します。
一覧は、子ウィンドウのウィンドウハンドル、ウィンドウクラス名、ウィンドウテキスト、親ウィンドウハンドル、コントロールID、ウィンドウの表示状態、Enable状態(入力可能状態)をそれぞれ表示します。
子ウィンドウを一覧で選択すると画面下段左のイメージ領域で該当の子ウィンドウの領域を赤枠で表示します。逆にイメージの任意の位置をクリックするとその位置に該当する子ウィンドウを選択状態にします。
(ウィンドウ位置が重なっている場合は最初に見つけたウィンドウを選択状態にします。ただし親ウィンドウから順に階層構造を考慮して検索するので同じ階層で重なって表示してるケースを除いて正しく検索されます。)
ここで使用する子ウィンドウ情報を取得するAPIは以下の通り。
ウィンドウの列挙 | EnumChildWndows() | ウィンドウを列挙します。 |
コールバック関数 | BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) | TRUEを返すと処理続行します。 今回は全て列挙するので常にTRUEを返します |
ウィンドウクラス名 | GetClassName() | |
親ウィンドウハンドル | GetParent() | |
コントロールID | GetDlgID() | |
ウィンドウ表示状態 | IsWindowVisible() | |
ウィンドウEnable状態 | IsWindowEnable() |
画面下部は子ウィンドウの状態及び操作用ボタンが配置されています。
情報更新ボタンは一覧とイメージを更新します。情報の取得方法は前述の一覧表示を参照 | |
マウス左ボタンのクリックイベントを送信します。ボタン右の座標はイベントの引数として渡されるマウス座標です。(子ウィンドウ原点からの相対値)マウスでイメージ画像をクリックすると該当の座標が自動で入ります。 イベント送信APIは以下の書式を送信します。(LPARAMはマウス座標) -BUTONDOWN PostMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, (LPARAM)lparam); -BUTONUP PostMessage(hWnd, WM_LBUTTONUP, 0, (LPARAM)lparam); |
|
Enterキー、F5キーを子ウィンドウに送信します。 書式は次の通り -EnterKey PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0); -F5Key PostMessage(hWnd, WM_KEYDOWN, VK_F5, 0); |
|
Simulate-CtrCキーはCtrl-Cによるコピー動作をシュミレートします。 -シュミレート方法 以下の手順でコピー動作を分解してイベントを生成します。 ::SetForegroundWindow(hWnd); keybd_event(VK_CONTROL,0,0,0); keybd_event (0x43, 0, 0, 0 ); //Send the C key (43 is "C") keybd_event (0x43, 0, KEYEVENTF_KEYUP, 0); keybd_event (VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);// 'Left Control Up WM_COPYキーは子ウィンドウにWM_COPYメッセージを送信します。 書式は以下の通りです。 SendMessage(inf.m_hWnd, WM_COPY, 0, 0); |
|
子ウィンドウのスタイルビット、及び拡張ウィンドウスタイルビットの表示を変更を行います。 この機能はメイン画面のウィンドウスタイルビットと同じです。 |
|
選択した子ウィンドウにSetFocusを行います。 書式は以下の通り SendMessage(hWnd, WM_SETFOCUS, 0,0); |
|
GetWindowRect()で取得したウィンドウ矩形の座標を表示します。 (スクリーン座標) |
|
GetClientRect()で取得したウィンドウサイズを表示します。 ※GetClientRect()のTop,Leftは常に0のためW=Right,H=Bottomとなる。 |
|
選択した子ウィンドウの親ウィンドウ原点からの相対座標での矩形位置を表示します。 | |
矩形抜きリージョン設定は、親ウィンドウのリージョン、またはウィンドウ矩形子ウィンドウの矩形を除いた形状のリージョン指定を行う。(つまり指定した子ウィンドウが抜けた(透過状態)のウィンドウとなる) 矩形リージョン設定、子ウィンドウの矩形でリージョン指定を行う。(つまり指定した子ウィンドウのみ表示するウィンドウとなる) リージョン設定解除は、リージョン指定を元の状態にに戻します。 補足: XPのテーマ設定がある場合はウィンドウ全体にリージョン設定があります。(つまりウィンドウ上部の丸みはリージョン設定されています。) VISTAの場合は、初期状態でリージョン設定なしの状態です。) |