はじめに
デスクトップに複数のウィンドウを並べて作業することがありますが、マウス操作では、なかなかぴったりの幅に合わせることができません。几帳面な性格を持つ多くの人は、これを非常に気持ち悪く感じるはずです。そこで、ウィンドウ同士を気持ちよくぴったり合わせるツールを作成します。このためには、ウィンドウメッセージをフックして、マウス操作が起きた場合に、強制的にウィンドウをグリッドに合わせるようにします。
Windowsで多くのデスクトップユーティリティが公開されています。ダイアログが表示されると自動的にマウスをダイアログの上に移動させたり、ウィンドウのタイトルをクリックするとウィンドウが透明になったりします。こうしたツールはどうやってデスクトップにあるウィンドウを監視しているのだろうと不思議に思ったことはありませんか。
これらの動作は、ウィンドウメッセージをフックすることにより実現しています。本稿では、メッセージフックの仕組みを紹介します。デスクトップ操作を改善するユーティリティツール作成のヒントになると思います。
対象読者
- デスクトップ・ユーティリティを作りたい人
- イベントフックの仕組みを知りたい人
- Delphiでオンラインソフトを開発している人
必要な環境
本稿の開発には、基本的に、Delphi 7を利用します。ただし、Delphi 2005のWin32モードで開いて、問題なくコンパイルできることを確認しています。
今回作成するツールの概要
今回作成するソフトの原型は、筆者が「窓グリッド」という名前で公開しているフリーソフトです。窓グリッドは以下のURLで公開しています。ウィンドウ同士をぴったりグリッドに沿って並べるツールです。
- 窓グリッド
窓グリッドから以下のポイントについて解説します。
- 自分のウィンドウメッセージをフックする方法
- すべてのウィンドウメッセージをフックする方法
- ウィンドウのリサイズを検出する方法
イベントのフックについて
Windowsは、さまざまなメッセージをやりとりしながら動いています。例えば、ユーザーがタスクバーをクリックするなどして、別のアプリケーションに切り替えた場合には、Windowsから対象のウィンドウに対して、WM_ACTIVATEAPP
というメッセージが送られます。
本稿で扱うフックとは、このイベントメッセージを横取りする仕組みです。フック(Hook)とは鉤型の引っ掛けるものを表します。つまり、さまざまなイベントをひっかけて横取りするという意味で使われます。
では、イベントをフックすると、どんなことができるのでしょうか。フックを利用するには、「SetWindowsHookEx()
」という関数を利用して、フック関数をインストールします。MSDNからこの関数のヘルプを調べると、どんなイベントがフックできるのか分かります。以下は、MSDNから引用したC言語の宣言です。
HHOOK SetWindowsHookEx( int idHook,// インストールするフックの種類 HOOKPROC lpfn,// フックプロシージャのアドレス HINSTANCE hMod,// アプリケーションインスタンスのハンドル DWORD dwThreadId// フックをインストールするスレッドのID );
この1つ目の引数idHook
に、フックするイベントの種類を指定します。ウィンドウプロシージャに送られたメッセージを監視する「WH_CALLWNDPROC
」や、メッセージキューにポストされたメッセージを監視する「WH_GETMESSAGE
」、キーストロークメッセージを監視する「WH_KEYBOARD
」など、さまざまな種類のフックができるようになっています。
今回、ウィンドウの幅をぴったり合わせるのに使うのは、マウスイベントを監視する「WH_MOUSE
」です。WH_MOUSE
を指定してフック関数をインストールすると、ユーザーがマウスを操作した時のメッセージを取得することができます。