○サブクラス化
ウィンドウズはすべてウインドウです(あたりまえかw)ですからボタンの中にもウィンドウプロシージャーがあり、その外のダイアログやウィンドウにもウィンドウプロシージャーがあります。
ボタンなどのコントロールはボタンの中のウィンドウプロシージャの中でボタンらしい動きを実現してそのメッセージを外のダイアログなどに送り出しているのです。
でもボタンなどの動きを変えたいときや、ボタンの外に送り出されないメッセージを処理したいときには元のプロシージャをすげ替える必要があります。
■まずはすげ替えるプロシージャ
コントロール内だけしか拾えないWM_LBUTTONDOWNメッセージを拾って、外に自作メッセージを送信します
この時にreturn 0;をすると元のプロシージャは呼び出されません。
#define WM_USER_MSG2 (WM_USER+101) //自作メッセージ
HWND hWnd;
WNDPROC DefaultProc;
LRESULT CALLBACK SubProc(HWND sub_hWnd,UINT msg,WPARAM wp,LPARAM lp){
switch (msg){
case WM_LBUTTONDOWN:
//外に対して自作メッセージを送信 wpに自分のコントロールIDをセット
SendMessage(hWnd,WM_USER_MSG2,GetDlgCtrlID(sub_hWnd),NULL);
//元のプロシージャにメッセージを渡したくないときは return 0; する
//return 0;
break;
}
//元のプロシージャを呼び出す
return CallWindowProc(DefaultProc,sub_hWnd,msg,wp,lp);
}
■コントロールのプロシージャを上のプロシージャにすげ替え
まずはウィンドウアプリケーションの通常のプロシージャを作成してその中で
ダイアログのIDC_EDIT1のプロシージャをすげ替えます。
すげ替えられるとEDIT1に対してマウスをクリックするとWM_USER_MSG2が飛んできます。
/ダイアログプロシージャー
BOOL CALLBACK DlgProc(HWND hDlg,UINT msg,WPARAM wp,LPARAM lp){
switch (msg){
case WM_INITDIALOG:
{
hWnd=hDlg;
HWND hCont1=GetDlgItem(hDlg,IDC_EDIT1);
DefaultProc=(WNDPROC)GetWindowLong(hCont1, GWL_WNDPROC);
SetWindowLong(hCont1,GWL_WNDPROC,(LONG)SubProc);
}
break;
case WM_USER_MSG2:
printf("ID %d\n",wp);
break;
この下もいろいろ続く・・・・
▲トップページ
>
Windows と C++