フック関数
独自の処理
あまり好ましいことではありませんが
必要に応じて、コモンダイアログの機能を拡張することができます
コモンダイアログボックスには、フック関数と呼ばれるものを指定することができ
標準のメッセージ処理を行う前に、フック関数にメッセージが送られてくるので
このメッセージを処理することによって、独自の機能を追加する仕組みになっています
フック関数を適応するには、コモンダイアログの作成用構造体の
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