フック関数


独自の処理

あまり好ましいことではありませんが
必要に応じて、コモンダイアログの機能を拡張することができます

コモンダイアログボックスには、フック関数と呼ばれるものを指定することができ
標準のメッセージ処理を行う前に、フック関数にメッセージが送られてくるので
このメッセージを処理することによって、独自の機能を追加する仕組みになっています

フック関数を適応するには、コモンダイアログの作成用構造体の
lpfnHook に、フック関数へのポインタを渡し、Flags に CC_ENABLEHOOK を指定します
フック関数は、次のようなアプリケーション定義コールバック関数です
UINT CALLBACK CCHookProc(
	HWND hdlg,
	UINT uiMsg,
	WPARAM wParam,
	LPARAM lParam
);
hdlg には、ダイアログのハンドルを指定します
uiMsg はメッセージ、wParam と lParam にはメッセージの追加情報を指定します
関数は、独自の処理をしたならば TRUE、そうでなければ FALSE を返します

標準のコモンダイアログボックスのメッセージ処理を行うのであれば
すなわち、フック関数がそのメッセージに興味がなければ FALSE を返せば良いのです
全てのメッセージは、標準のメッセージ処理関数に渡される前に、フック関数が受け取ります
ただし、WM_INITDIALOG メッセージだけは、標準のプロシージャの後に受け取ります
これは、コモンダイアログボックスが正しく初期化するためです
#include <windows.h>

UINT CALLBACK CCHookProc(HWND hdlg , UINT uiMsg , WPARAM wp , LPARAM lp) {
	switch(uiMsg) {
	case WM_INITDIALOG:
		SetWindowText(hdlg , TEXT("Kitty on your lap"));
		return TRUE;
	}
	return FALSE;
}

LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
	static CHOOSECOLOR cc = {0};
	static COLORREF color = 0 , CustColors[16];

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		cc.lStructSize	= sizeof (CHOOSECOLOR);
		cc.hwndOwner	= hWnd;
		cc.rgbResult	= color;
		cc.lpCustColors	= CustColors;
		cc.Flags	= CC_RGBINIT | CC_ENABLEHOOK;
		cc.lpfnHook	= CCHookProc;

		return 0;
	case WM_LBUTTONUP:
		if (!ChooseColor(&cc)) return 0;
		SetClassLong(hWnd , GCL_HBRBACKGROUND ,
			(LONG)CreateSolidBrush(cc.rgbResult));
		InvalidateRect(hWnd , NULL , TRUE);
		return 0;
	}
	return DefWindowProc(hWnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow ) {
	HWND hwnd;
	MSG msg;
	WNDCLASS winc;

	winc.style		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");

	if (!RegisterClass(&winc)) return -1;

	hwnd = CreateWindow(
			TEXT("KITTY") , TEXT("Kitty on your lap") ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL ,
			hInstance , NULL
	);

	if (hwnd == NULL) return -1;

	while(GetMessage(&msg , NULL , 0 , 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}


このプログラムは、コモンダイアログの初期化時に
SetWindowText() で、ダイアログのタイトルバーの文字列を変更しています

フック関数は、ダイアログボックスに独自のコントロールを貼りつけて
独自の処理を拡張するときなどにも重宝します
本来、必要でない限りは独自の拡張は推奨されませんが
例えば、音声ファイルを選択する「ファイルを開く」ダイアログボックスの場合は
ダイアログの下部に再生ボタンをとりつけて、音声を視聴できるようにすると便利でしょう


CCHookProc()

UINT CALLBACK CCHookProc(
	HWND hdlg,
	UINT uiMsg,
	WPARAM wParam,
	LPARAM lParam
);
コモンダイアログに追加できるフック関数です
アプリケーション定義のコールバック関数です

hdlg - ダイアログボックスのハンドルを指定します
uiMsg - メッセージを指定します
wParam - メッセージの追加情報を指定します
lParam - メッセージの追加情報を指定します

戻り値 - 処理をしたならば TRUE、そうでなければ FALSE



前のページへ戻る次のページへ