レガシー Windows API(概要)について

ここで紹介しているAPIは、Windows95、Windows NT3.5時代のAPI群であり、最新のAPIは含まれていないことに注しして欲しい。なお、当時の解説書は現在よりもより詳細に解説しているため、参考になるはずである。

  • レイアウトを変換する際、崩れているページがあります。
  • 概要およびSampleコードはありますが、APIの解説はありません。

ご要望があれば旧版のWin32 API(HELP形式)をお譲りします。問い合わせフォームより申し込みください。

Windows API フックの概要

「フック」とは、 アプリケーションがシステムのメッセージの流れを監視して特定のメッセージがウィンドウ プロシージャに届く前にそのメッセージを処理するためのサブルーチンがインストールされる、 Microsoft(R) Windows(TM) メッセージ処理機構内のポイントです。このトピックでは、 Windowsのフックと、 Windows用アプリケーションでフックを使う方法を説明します。[>>]ボタンを使って以下に示すトピックを順番に読んでください。または、 各トピックをクリックすると、 そのトピックの内容を表示できます。

フック チェイン

フック プロシージャ

フックの種類

フック プロシージャのインストールと解放

システム イベントの監視の例

フック関数

フック チェイン

Windowsにはさまざまな種類のフックがあり、 Windowsのメッセージ処理機構のさまざまな部分をアクセスできます。たとえば、 アプリケーションは、 WH_MOUSEフックを使って、 マウス メッセージの流れを監視できます。

Windowsは、 各種類のフックそれぞれについて個別のフック チェインを管理しています。「フック チェイン」は、 「フック プロシージャ」と呼ばれるアプリケーション定義の特別なコールバック関数を指すポインタのリストです。特定のフックに関するメッセージが発生すると、 Windowsは、 フック チェインで参照される各フック プロシージャにそのメッセージを順番に渡します。フック プロシージャが行う動作は、 フックの種類によって異なります。たとえば、 メッセージを監視するだけのものや、 メッセージを修正したりチェインによるメッセージの処理を中止して、 メッセージが次のフック プロシージャや送り先ウィンドウに届かないようにするものなどがあります。

フックによって各メッセージに対するシステムの処理量が増加するため、 フックを使うとシステムの動作が低速になる傾向があります。フックは必要なときだけインストールし、 できるだけ早く削除してください。

フック プロシージャ

特定の種類のフックを利用するには、 フック プロシージャを用意し、 SetWindowsHookEx関数を使ってそのプロシージャをフックに関連付けられているチェインにインストールします。フック プロシージャの構文を次に示します。

LRESULT CALLBACK HookProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;
 

HookProcは、 アプリケーション定義の名前のプレースホルダです。Windowsがフック プロシージャを呼び出さなければならないため、 実際の名前は、 アプリケーションのモジュール定義ファイルのEXPORTS文で (オプションの序数値とともに) エクスポートしてください。

nCodeパラメータは、 フック プロシージャが実行する動作を判断するために使うフック コードです。フック コードの値は、 フックの種類によって異なります。各種類のフックには、 それぞれ、 固有のフック コードのセットがあります。wParamパラメータとlParamパラメータの値はフック コードによって異なりますが、 通常は、 送られたりポストされたメッセージに関する情報を示します。

SetWindowsHookExは、 フック プロシージャを常にフックの先頭にインストールします。特定の種類のフックで監視されているイベントが発生すると、 Windowsは、 そのフックに関連付けられているフック チェインの先頭のプロシージャを呼び出します。チェインの各プロシージャは、 イベントを次のプロシージャに渡すかどうかを判断します。フック プロシージャは、 CallNextHookEx関数を呼び出して、 イベントを次のプロシージャに渡します。

一部の種類のフックのフック プロシージャは、 メッセージの監視しかできません。この場合、 Windowsは、 特定のプロシージャがCallNextHookExを呼び出すかどうかにかかわらず、 各フック プロシージャにメッセージを渡します。

フック プロシージャは、 グローバルにして、 システム内のすべてのスレッドのメッセージを監視できます。また、 スレッド固有にして、 あるスレッドのメッセージだけを監視することもできます。グローバル フック プロシージャはどのアプリケーションのコンテキストからでも呼び出されるため、 フック プロシージャは独立したダイナミック リンク ライブラリ (DLL) モジュールになければなりません。スレッド固有フック プロシージャは関連付けられているスレッドのコンテキストでしか呼び出されません。自分自身のスレッドのいずれかを監視するフック プロシージャをインストールする場合、 アプリケーションは、 アプリケーションのコードと同じモジュールかDLLにフック プロシージャを置くことができます。ほかのアプリケーションのスレッドを監視するフック プロシージャは、 DLLに置かなければなりません。DLLについて詳しくは、 ダイナミック リンク ライブラリの概要を参照してください。

フックの種類

アプリケーションは、 各種のフックを使って、 Windowsのメッセージ処理機構のさまざまな部分を監視できます。ここでは、 Windowsで利用可能なフックの種類について説明します。各トピックをクリックすると、 そのトピックの内容を表示できます。

WH_CALLWNDPROCフック

WH_CBTフック

WH_DEBUGフック

WH_GETMESSAGEフック

WH_JOURNALRECORDフック

WH_JOURNALPLAYBACKフック

WH_KEYBOARDフック

WH_MOUSEフック

WH_MSGFILTERフックとWH_SYSMSGFILTERWH_SYSMSGFILTERフック

WH_SHELLフック

WH_CALLWNDPROCフック

アプリケーションは、 WH_CALLWNDPROCフックを使って、 SendMessage関数でウィンドウ プロシージャに送られるメッセージを監視できます。Windowsは、 送り先のウィンドウ プロシージャにメッセージを渡す前にWH_CALLWNDPROCフック プロシージャを呼び出します。

WH_CBTフック

Windowsは、 次に示す処理を行う前に、 WH_CBTフック プロシージャを呼び出します。

ウィンドウのアクティブ化、 作成、 破棄、 最大化、 アイコン化、 移動、 サイズ変更

システム メッセージ キューからのマウス イベントやキーボード イベントの削除

入力フォーカスの設定

システム メッセージ キューの同期化

Windowsは、 フック プロシージャが返す値によって、 上記の処理を行うかどうかを判断します。WH_CBTフックは、 Windowsコンピュータ ベースのトレーニング (CBT) アプリケーションを主に想定しています。

WH_DEBUGフック

Windowsは、 システムのほかのフックに関連付けられているフック プロシージャを呼び出す前に、 WH_DEBUGフック プロシージャを呼び出します。アプリケーションは、 このフックを使って、 ほかの種類に関連付けられているフック プロシージャをシステムが呼び出せるようにするかどうかを決定できます。

WH_GETMESSAGEフック

アプリケーションは、 WH_GETMESSAGEフックを使って、 GetMessage関数やPeekMessage関数が返そうとしているメッセージを監視できます。アプリケーションは、 WH_GETMESSAGEフックを使って、 キューにポストされたマウス 入力やキーボード入力などのメッセージを監視できます。

WH_JOURNALRECORDフック

アプリケーションは、 WH_JOURNALRECORDフックを使って、 入力イベントを監視、 記録できます。通常、 アプリケーションは、 このフックを使ってマウス イベントやキーボード イベントのシーケンスを記録し、 後でWH_JOURNALPLAYBACKフックを使って再生します。WH_JOURNALRECORDフックはグローバル フックであり、 スレッド固有フックとして使うことはできません。

WH_JOURNALPLAYBACKフック

アプリケーションは、 WH_JOURNALPLAYBACKフックを使って、 システム メッセージ キューにメッセージを挿入できます。アプリケーションは、 WH_JOURNALRECORDフックで記録しておいた一連のマウス イベントやキーボード イベントを、 このフックを使って再生できます。WH_JOURNALPLAYBACKフックがインストールされているときは、 通常のマウス入力やキーボード入力は使用不能になります。WH_JOURNALPLAYBACKフックはグローバル フックであり、 スレッド固有フックとして使うことはできません。

WH_JOURNALPLAYBACKフックは、 タイムアウト値を返します。この値は、 再生フックが現在のメッセージを処理するのにかかる秒数をシステムに知らせるためのものです。これによって、 フックは、 自分が再生するイベントのタイミングを制御できます。

WH_KEYBOARDフック

アプリケーションは、 WH_KEYBOARDフックを使って、 GetMessage関数やPeekMessage関数が返そうとしているWM_KEYDOWNメッセージやWM_KEYUPメッセージの流れを監視できます。アプリケーションは、 WH_KEYBOARDフックを使って、 メッセージ キューにポストされるキーボード入力を監視できます。

WH_MOUSEフック

アプリケーションは、 WH_MOUSEフックを使って、 GetMessage関数やPeekMessage関数が返そうとしているマウス メッセージを監視できます。アプリケーションは、 WH_MOUSEフックを使って、 メッセージ キューにポストされるマウス入力を監視できます。

WH_MSGFILTERフックとWH_SYSMSGFILTERフック

アプリケーションは、 WH_MSGFILTERフックとWH_SYSMSGFILTERフックを使って、 メニューやスクロール バー、 メッセージ ボックス、 ダイアログ ボックスが処理しようとしているメッセージを監視したり、 ユーザーがAlt+TabキーやAlt+Escキーを押したときに別のウィンドウがアクティブ化されようとするのを検出できます。WH_MSGFILTERフックは、 フック プロシージャをインストールしたアプリケーションが作成したメニューやスクロール バー、 メッセージ ボックス、 ダイアログ ボックスに渡されるメッセージしか監視できません。WH_SYSMSGFILTERフックは、 すべてのアプリケーションについてこのようなメッセージを監視できます。

アプリケーションは、 WH_MSGFILTERフックやWH_SYSMSGFILTERフックを使って、 メイン メッセージ ループで行うメッセージのフィルタ処理と同じフィルタ処理をモーダル ループでも行うことができます。たとえば、 アプリケーションは、 キューからメッセージを取り出してからディスパッチするまでの間に新しいメッセージを調べて、 必要に応じて特別な処理を行うことができます。しかし、 モーダル ループでは、 システムは、 アプリケーションがメイン メッセージ ループでメッセージをフィルタする機会を与えずに、 自動的にメッセージを取得してディスパッチします。アプリケーションがWH_MSGFILTERフック プロシージャかWH_SYSMSGFILTERフック プロシージャをインストールしていれば、 システムは、 モーダル ループでもそのプロシージャを呼び出します。モーダル ループについて詳しくは、 ウィンドウの概要を参照してください。

アプリケーションは、 CallMsgFilter関数を呼び出すことによって、 WH_MSGFILTERフックを直接呼び出すことができます。アプリケーションは、 この関数を使って、 モーダル ループのメッセージのフィルタ処理とメイン ループのメッセージのフィルタ処理に同じコードを利用できます。同じコードを流用するには、 フィルタ処理操作をWH_MSGFILTERフック プロシージャにカプセル化し、 GetMessage関数を呼び出してからDispatchMessage関数を呼び出すまでの間にCallMsgFilterを呼び出します。

while (GetMessage(&msg, (HWND) NULL, 0, 0)) {
if (!CallMsgFilter(&qmsg, 0))
DispatchMessage(&qmsg);
}
 

CallMsgFilterの最後の引数は、 そのままフック プロシージャに渡されます。アプリケーションは、 任意の値を指定できます。MSGF_MAINLOOPなどの定数で定義されているフック プロシージャは、 この値を使って、 プロシージャの呼び出し元を判断できます。

WH_SHELLフック

Windowsシェル アプリケーションは、 WH_SHELLフックを使って、 重要な通知を取得できます。Windowsは、 シェル アプリケーションがアクティブ化されようとしているときや、 トップ レベル ウィンドウが作成または破棄されるときに、 WH_SHELLフック プロシージャを呼び出します。

フックの使用

以下に示すトピックで、 フック プロシージャのインストールおよび解放の方法を説明します。また、 これらのトピックでは、 種々のイベントに関してシステムを監視するためにフックを使う方法も示されています。[>>]ボタンを使って以下に示すトピックを順番に読んでください。または、 各トピックをクリックすると、 そのトピックの内容を表示できます。

フック プロシージャのインストールと解放

システム イベントの監視

フック プロシージャのインストールと解放

フック プロシージャをインストールするには、 フックの種類、 プロシージャをすべてのスレッドに関連付けるかそれとも特定のスレッドに関連付けるか、 プロシージャのエントリ ポイントを指すポインタを指定して、 SetWindowsHookEx関数を呼び出します。

グローバル フック プロシージャは、 フック プロシージャをインストールするアプリケーション内ではなく、 独立したDLLに置いてください。フックをインストールするアプリケーションは、 フック プロシージャをインストールする前に、 DLLモジュールのハンドルを取得しておかなければなりません。LoadLibrary関数は、 DLLの名前を受け取って、 DLLモジュールのハンドルを返します。ハンドルを取得したら、 GetProcAddress関数を呼び出して、 フック プロシージャのアドレスを取得してください。最後に、 SetWindowsHookExを使って、 フック プロシージャ アドレスを適切なフック チェインにインストールします。SetWindowsHookExには、 モジュール ハンドル、 フック プロシージャのエントリ ポイントを指すポインタ、 スレッド識別子を渡します。スレッド識別子に0を指定することによって、 フック プロシージャをシステムのすべてのスレッドに関連付けることを示します。この手順を次の例に示します。

HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;
.
.
.

hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll");
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc");
hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,
hkprcSysMsg, hinstDLL, 0);
.
.
.
 

スレッド固有フック プロシージャを解放する (プロシージャのアドレスをフック チェインから削除する) には、 解放するフック プロシージャのハンドルを指定して、 UnhookWindowsHookEx関数を呼び出します。フック プロシージャは、 不要になったらすぐに削除してください。

グローバル フック プロシージャを解放するにはUnhookWindowsHookExを使いますが、 この関数は、 フック関数を含むDLLは解放しません。これは、 フック プロシージャはシステムのすべてのWindows用アプリケーションのプロセス コンテキストから呼び出される可能性があり、 プロセスすべてについてLoadLibrary関数が暗黙に呼び出されることになるためです。ほかのプロセスでFreeLibrary関数を呼び出すことはできないため、 DLLを解放することはできません。Windowsは、 DLLに明示的にリンクされているすべてのプロセスが終了するかFreeLibraryを呼び出し、 フック プロシージャを呼び出したすべてのプロセスがDLL外での処理を再開すると、 DLLを解放します。

グローバル フック プロシージャをインストールするもう1つの方法は、 DLL内にフック プロシージャとともにインストール関数を用意する方法です。この方法では、 フックをインストールするアプリケーションは、 DLLモジュールのハンドルを取得する必要はありません。アプリケーションは、 DLLにリンクすることによって、 インストール関数にアクセスできます。インストール関数は、 SetWindowsHookExを呼び出すときに、 DLLモジュール ハンドルなどの情報を供給します。また、 DLLには、 グローバル フック プロシージャを解放する関数を入れることもできます。アプリケーションは、 終了するときにこのフック解放関数を呼び出します。

システム イベントの監視の例

このトピックの例では、 さまざまなスレッド固有フック プロシージャを使って、 スレッドに影響するイベントを監視します。ここでは、 次に示す種類のフック プロシージャでイベントを処理する方法を示します。

WH_CALLWNDPROC

WH_CBT

WH_DEBUG

WH_GETMESSAGE

WH_KEYBOARD

WH_MOUSE

WH_MSGFILTER

この例では、 ユーザーはメニューを使ってフック プロシージャをインストールまたは削除できます。フック プロシージャをインストールし、 プロシージャが監視するイベントが発生すると、 プロシージャは、 イベントに関する情報をアプリケーションのメイン ウィンドウのクライアント領域に書き込みます。

#define NUMHOOKS 7

/* Global variables */

typedef struct _MYHOOKDATA {
int nType;
HOOKPROC hkprc;
HHOOK hhook;
} MYHOOKDATA;

MYHOOKDATA myhookdata[NUMHOOKS];

LONG APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)
HWND hwndMain;
UINT uMsg;
UINT wParam;
LONG lParam;
{
static BOOL afHooks[NUMHOOKS];
int index;
static HMENU hmenu;

switch (uMsg) {
case WM_CREATE:

/* Save the menu handle. */

hmenu = GetMenu(hwndMain);

/*
* Initialize structures with hook data. The menu-item
* identifiers are defined as 0 through 6 in the
* header file. They can be used to identify array
* elements both here and during the WM_COMMAND
* message.
*/

myhookdata[IDM_CALLWNDPROC].nType = WH_CALLWNDPROC;
myhookdata[IDM_CALLWNDPROC].hkprc = CallWndProc;
myhookdata[IDM_CBT].nType = WH_CBT;
myhookdata[IDM_CBT].hkprc = CBTProc;
myhookdata[IDM_DEBUG].nType = WH_DEBUG;
myhookdata[IDM_DEBUG].hkprc = DebugProc;
myhookdata[IDM_GETMESSAGE].nType = WH_GETMESSAGE;
myhookdata[IDM_GETMESSAGE].hkprc = GetMsgProc;
myhookdata[IDM_KEYBOARD].nType = WH_KEYBOARD;
myhookdata[IDM_KEYBOARD].hkprc = KeyboardProc;
myhookdata[IDM_MOUSE].nType = WH_MOUSE;
myhookdata[IDM_MOUSE].hkprc = MouseProc;
myhookdata[IDM_MSGFILTER].nType = WH_MSGFILTER;
myhookdata[IDM_MSGFILTER].hkprc = MessageProc;

/* Initialize all flags in the array to FALSE. */

memset(afHooks, FALSE, sizeof(afHooks));

return 0;

case WM_COMMAND:
switch (LOWORD(wParam)) {

/*
* The user selected a hook command from the menu.
*/

case IDM_CALLWNDPROC:
case IDM_CBT:
case IDM_DEBUG:
case IDM_GETMESSAGE:
case IDM_KEYBOARD:
case IDM_MOUSE:
case IDM_MSGFILTER:

/*
* Use the menu-item identifier as an index
* into the array of structures with hook data.
*/

index = LOWORD(wParam);

/*
* If the selected type of hook procedure isn't
* installed yet, install it and check the
* associated menu item.
*/

if (!afHooks[index]) {
myhookdata[index].hhook = SetWindowsHookEx(
myhookdata[index].nType,
myhookdata[index].hkprc,
(HINSTANCE) NULL, GetCurrentThreadId());
CheckMenuItem(hmenu, index,
MF_BYCOMMAND | MF_CHECKED);
afHooks[index] = TRUE;
}

/*
* If the selected type of hook procedure is
* already installed, remove it and remove the
* check mark from the associated menu item.
*/

else {
UnhookWindowsHookEx(myhookdata[index].hhook);
CheckMenuItem(hmenu, index,
MF_BYCOMMAND | MF_UNCHECKED);
afHooks[index] = FALSE;
}

default:
return (DefWindowProc(hwndMain, uMsg, wParam,
lParam));
}
break;

.
. /* Process other messages. */
.

default:
return DefWindowProc(hwndMain, uMsg, wParam, lParam);
}
return NULL;
}

/****************************************************************
WH_CALLWNDPROC hook procedure
****************************************************************/

LRESULT CALLBACK CallWndProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;
{
CHAR szCWPBuf[256];
CHAR szMsg[16];
HDC hdc;
static int c = 0;
int cch;

if (nCode < 0)/* do not process message */
return CallNextHookEx(myhookdata[CALLWNDPROC].hhook, nCode,
wParam, lParam);

/*
* Call an application-defined function that converts a message
* constant to a string and copies it to a buffer.
*/

LookUpTheMessage((PMSG) lParam, szMsg);

hdc = GetDC(hwndMain);

switch (nCode) {
case HC_ACTION:
cch = wsprintf(szCWPBuf,
"CALLWNDPROC - tsk: %ld, msg: %s, %d times",
wParam, szMsg, c++);
TextOut(hdc, 2, 15, szCWPBuf, cch);
break;

default:
break;
}

ReleaseDC(hwndMain, hdc);
return CallNextHookEx(myhookdata[CALLWNDPROC].hhook, nCode,
wParam, lParam);
}

/****************************************************************
WH_GETMESSAGE hook procedure
****************************************************************/

LRESULT CALLBACK GetMsgProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;
{
CHAR szMSGBuf[256];
CHAR szRem[16];
CHAR szMsg[16];
HDC hdc;
static int c = 0;
int cch;

if (nCode < 0) /* do not process message */
return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode,
wParam, lParam);

switch (nCode) {
case HC_ACTION:
switch k(wParam) {
case PM_REMOVE:
lstrcpy(szRem, "PM_REMOVE");
break;

case PM_NOREMOVE:
lstrcpy(szRem, "PM_NOREMOVE");
break;

default:
lstrcpy(szRem, "Unknown");
break;
}

/*
* Call an application-defined function that converts a
* message constant to a string and copies it to a
* buffer.
*/

LookUpTheMessage((PMSG) lParam, szMsg);

hdc = GetDC(hwndMain);
cch = wsprintf(szMSGBuf,
"GETMESSAGE - wParam: %s, msg: %s, %d times",
szRem, szMsg, c++);
TextOut(hdc, 2, 35, szMSGBuf, cch);
break;

default:
break;
}

ReleaseDC(hwndMain, hdc);
return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode,
wParam, lParam);
}

/****************************************************************
WH_DEBUG hook procedure
****************************************************************/

LRESULT CALLBACK DebugProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;
{
CHAR szBuf[128];
HDC hdc;
static int c = 0;
int cch;

if (nCode < 0)/* do not process message */
return CallNextHookEx(myhookdata[DEBUG].hhook, nCode,
wParam, lParam);

hdc = GetDC(hwndMain);

switch (nCode) {
case HC_ACTION:
cch = wsprintf(szBuf,
"DEBUG - nCode: %d, tsk: %ld, %d times",
nCode,wParam, c++);
TextOut(hdc, 2, 55, szBuf, cch);
break;

default:
break;
}

ReleaseDC(hwndMain, hdc);
return CallNextHookEx(myhookdata[DEBUG].hhook, nCode, wParam,
lParam);
}

/****************************************************************
WH_CBT hook procedure
****************************************************************/

LRESULT CALLBACK CBTProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;
{
CHAR szBuf[128];
CHAR szCode[128];
HDC hdc;
static int c = 0;
int cch;

if (nCode < 0)/* do not process message */
return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam,
lParam);

hdc = GetDC(hwndMain);

switch (nCode) {
case HCBT_ACTIVATE:
lstrcpy(szCode, "HCBT_ACTIVATE");
break;

case HCBT_CLICKSKIPPED:
lstrcpy(szCode, "HCBT_CLICKSKIPPED");
break;

case HCBT_CREATEWND:
lstrcpy(szCode, "HCBT_CREATEWND");
break;

case HCBT_DESTROYWND:
lstrcpy(szCode, "HCBT_DESTROYWND");
break;

case HCBT_KEYSKIPPED:
lstrcpy(szCode, "HCBT_KEYSKIPPED");
break;

case HCBT_MINMAX:
lstrcpy(szCode, "HCBT_MINMAX");
break;

case HCBT_MOVESIZE:
lstrcpy(szCode, "HCBT_MOVESIZE");
break;

case HCBT_QS:
lstrcpy(szCode, "HCBT_QS");
break;

case HCBT_SETFOCUS:
lstrcpy(szCode, "HCBT_SETFOCUS");
break;

case HCBT_SYSCOMMAND:
lstrcpy(szCode, "HCBT_SYSCOMMAND");
break;

default:
lstrcpy(szCode, "Unknown");
break;
}

cch = wsprintf(szBuf, "CBT - nCode: %s, tsk: %ld, %d times",
szCode, wParam, c++);
TextOut(hdc, 2, 75, szBuf, cch);
ReleaseDC(hwndMain, hdc);
return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam,
lParam);
}

/****************************************************************
WH_MOUSE hook procedure
****************************************************************/

LRESULT CALLBACK MouseProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;
{
CHAR szBuf[128];
CHAR szMsg[16];
HDC hdc;
static int c = 0;
int cch;

if (nCode < 0)/* do not process the message */
return CallNextHookEx(myhookdata[MOUSE].hhook, nCode,
wParam, lParam);

/*
* Call an application-defined function that converts a message
* constant to a string and copies it to a buffer.
*/

LookUpTheMessage((PMSG) lParam, szMsg);

hdc = GetDC(hwndMain);
cch = wsprintf(szBuf,
"MOUSE - nCode: %d, msg: %s, x: %d, y: %d, %d times",
nCode, szMsg, LOWORD(lParam), HIWORD(lParam), c++);
TextOut(hdc, 2, 95, szBuf, cch);
ReleaseDC(hwndMain, hdc);
return CallNextHookEx(myhookdata[MOUSE].hhook, nCode, wParam,
lParam);
}

/****************************************************************
WH_KEYBOARD hook procedure
****************************************************************/

LRESULT CALLBACK KeyboardProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;
{
CHAR szBuf[128];
HDC hdc;
static int c = 0;
int cch;

if (nCode < 0)/* do not process message */
return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode,
wParam, lParam);

hdc = GetDC(hwndMain);
cch = wsprintf(szBuf, "KEYBOARD - nCode: %d, vk: %d, %d times ",
nCode, wParam, c++);
TextOut(hdc, 2, 115, szBuf, cch);
ReleaseDC(hwndMain, hdc);
return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode, wParam,
lParam);
}

/****************************************************************
WH_MSGFILTER hook procedure
****************************************************************/

LRESULT CALLBACK MessageProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;
{
CHAR szBuf[128];
CHAR szMsg[16];
CHAR szCode[32];
HDC hdc;
static int c = 0;
int cch;

if (nCode < 0)/* do not process message */
return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,
wParam, lParam);

switch (nCode) {
case MSGF_DIALOGBOX:
lstrcpy(szCode, "MSGF_DIALOGBOX");
break;

case MSGF_MENU:
lstrcpy(szCode, "MSGF_MENU");
break;

case MSGF_SCROLLBAR:
lstrcpy(szCode, "MSGF_SCROLLBAR");
break;

case MSGF_NEXTWINDOW:
lstrcpy(szCode, "MSGF_NEXTWINDOW");
break;

default:
wsprintf(szCode, "Unknown: %d", nCode);
break;
}

/*
* Call an application-defined function that converts a message
* constant to a string and copies it to a buffer.
*/

LookUpTheMessage((PMSG) lParam, szMsg);

hdc = GetDC(hwndMain);
cch = wsprintf(szBuf,
"MSGFILTERnCode: %s, msg: %s, %d times",
szCode, szMsg, c++);
TextOut(hdc, 2, 135, szBuf, cch);
ReleaseDC(hwndMain, hdc);
return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,
wParam, lParam);
}
 

フック関数

フックに関する関数とメッセージを次に示します。

関数

CallMsgFilter

CallNextHookEx

CallWndProc

CBTProc

DebugProc

DefHookProc (使われなくなりました)

GetMsgProc

JournalPlaybackProc

JournalRecordProc

KeyboardProc

MessageProc

MouseProc

SetWindowsHook (使われなくなりました)

SetWindowsHookEx

ShellProc

SysMsgProc

UnhookWindowsHook (使われなくなりました)

UnhookWindowsHookEx

メッセージ

WM_QUEUESYNC

▲ページトップに戻る

【本を読んでもよくらからない】 … 個別指導でわかりやすくお教えします
inserted by FC2 system