So-net無料ブログ作成
検索選択

Windows - 5 SetWindowsHookEx [Programming]

Win32 API のなかで、怪しそうな仕様の筆頭って言ったらやっぱりコレ。知らなければ知らないで済むだろうけど、一度知ってしまうと全てコレで賄えちゃうんじゃないかって思うほど。Windows Hook と呼ばれるこの機能を要約すると、「スレッドに投げられたメッセージを、そっと抜き取る」盗聴器のようなものということになる。

Windows Hook の形態は 2 つあり、自分自身に仕掛けるもの(スレッドフック)と、システム全体に仕掛けるもの(グローバルフック)に分類される。 特定のスレッドに仕掛けるものがあったら便利そうだとも思うのだけど、残念ながらその選択肢は認められていない。

Windows Hook を利用するためには、知らなければならないものがいくつかある。 ひとつはコールバック関数。Windows のプログラミンをしていると結構出てくるのでご存知の方も多いとは思うけど、Windows Hook でも利用することになる。このコールバック関数で抜き取ったメッセージに対する処理を記述する。もうひとつは、DLL の作成方法。前述のスレッドフックの場合には不要なのだけど、グローバルフックを利用したいなら必須のスキルになる。できれば共有セクションのことも知っておくと便利に使えるようになる。DLL に上述のコールバック関数を仕込んで、稼働中のスレッドのメッセージキューに仕掛けるという事を行う。

今回は、簡単なスレッドフックの使い方。メッセージボックスの出現位置を変更してみる。元ネタはこちらVisual Basic のコードを C++ で書き換えてみた。

    static HHOOK Hook = ::SetWindowsHookEx(
WH_CBT,
[](int nCode, WPARAM wParam, LPARAM lParam)->LRESULT {
if (nCode==HCBT_ACTIVATE) {
CRect desktop, rect;
::SystemParametersInfo(SPI_GETWORKAREA, 0, &desktop, 0);
::GetWindowRect((HWND)wParam, &rect);
::SetWindowPos(
(HWND)wParam,
NULL,
(desktop.Width()-rect.Width())/2,
(desktop.Height()-rect.Height())/2,
0,
0,
SWP_NOZORDER|SWP_NOSIZE
);
::UnhookWindowsHookEx(Hook);
}
return ::CallNextHookEx(Hook, nCode, wParam, lParam);
},
NULL,
::GetCurrentThreadId()
);
::MessageBox(NULL, _T("Information"), _T("テスト"), MB_OK|MB_ICONINFORMATION);

最近の C++ ではラムダが使えるようになっているので、コールバック関数の部分に使ってみた。このコード片をコマンドハンドラにでも仕込んでやれば、メッセージボックスの出現位置を変更することができる。ココの表示エリアの制限があるので縦長になってしまっているけど、実際の処理は見た目ほど長くはない。


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この記事のトラックバックURL: