• 締切済み

【Win32 API】 フックしたメッセージを無効化する方法は?

switch(wParam) { case WM_LBUTTONDBLCLK: /*WM_LBUTTONDBLCLKを無効化するロジック*/ ............. } 上記のように、WM_LBUTTONDBLCLKメッセージをフックして、そのメッセージを無効化する方法はありますか? 【問題の背景】 入力フィールドをダブルクリックすると、入力フィールドの表示がおかしくなるという不具合が発生しています。そのため、入力フィールドをダブルクリックしたときに、そのメッセージをフックして、無効化する方法はないかを探しています。 よろしくお願いします。

みんなの回答

  • akinori_s
  • ベストアンサー率60% (21/35)
回答No.1

WM_LBUTTONDBLCLKが来た時にDefWindowProc等を呼ばずに returnしても駄目ですか?

makotottie
質問者

お礼

ありがとうございました

makotottie
質問者

補足

FAILをreturnすることで、WM_LBUTTONDCLKを無効にする事が出来ました。これでデフォルトウィンドウプロシージャで処理されない事になるのでしょうか? 動作的にはうまくいってるのですが、なぜ上手くいっているのか、その原因がわかりません。

関連するQ&A

  • グローバルフックについて

    VC++6.0でグローバルフック用のDLLを作っていて、どうしてもわからないので質問させていただきます。 フックの内容は、ウィンドウが最前面にあるかどうか常に監視したいので、状態が変わるメッセージをフックしています。 フック対象はとあるゲームなんですが、テストのためにメモ帳を対象にテストをしました。 まず、spy++でウィンドウの状態を変化させたときに送られてくるメッセージを調べた結果。 WM_ACTIVATEが送られてくるので、これをフックしてみたのですが、spy++だとバックグラウンドに行った時、フォアグラウンドに行った時、最小化したとき、最小化から復帰したときにWM_ACTIVATEが送られてくるんですが、いざフックしてみると最小化するときと最小化から復帰したときにしかフックが作動しません。 spy++ではWM_SETFOCUSも送られてくるようだったので、そちらも試してみたのですが、まったく反応がありません。 逆に、spy++では検知してくれないWM_SHOWWINDOWではバックグラウンドに行った時、フォアグラウンドに行った時、最小化したとき、最小化から復帰したとき、すべてに反応してくれました。 このWM_SHOWWINDOWをフックしたときのようになれば問題無いのですが、フック対象をメモ帳からとあるゲームにしたときに、バックグラウンドに行った時と最小化したときは反応してくれたものの、フォアグラウンドに行った時と最小化から復帰したときは反応してくれません。 それと、WM_SHOWWINDOWのメッセージをフックした時のwparamの値なんですが、ネットで調べてみると 表示されようとしているとき 1 非表示されようとしているとき 0 となっているはずなのですが、自分のをみてみると常に647で固定されています。 どなたか解決策をご教授お願いします。 LRESULT CALLBACK WndProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode < 0) { return CallNextHookEx(hHook, nCode, wParam, lParam); } else if (nCode == HC_ACTION) { MSG *lmsg; lmsg = (MSG *)lParam; switch (lmsg->message){ case WM_SHOWWINDOW: MessageBox(NULL,"showwindow","info",MB_OK | MB_TOPMOST); return CallNextHookEx(hHook, nCode, wParam, lParam); break; } } return CallNextHookEx(hHook, nCode, wParam, lParam); }

  • キィーボードをフックしません、何故ですか???

    パソコンを現在人間が実際に操作中であるか否かを判定しながら進めるアプリを作っています 簡易的にキィーボードを操作していれば操作中と判断します(マウス操作も含めますが話を簡単にするため今はキィーだけとします) グローバルフックでKEY_DOWNをフックする為に以下のDLL(主要部分のみ)を作りました キィーが押されるとMW_KEYDOWN_DLLというメッセージをアプリに送ります EXPORT LRESULT CALLBACK HookProc( int nCode, WPARAM wParam, LPARAM lParam) { if(nCode == HC_ACTION) { CWPSTRUCT *pcwp = (CWPSTRUCT *)lParam; if(pcwp->message == WM_KEYDOWN) { SendMessage(g_hWnd, WM_KEYDOWN_DLL, pcwp->wParam, pcwp->lParam); ←(1) } } return (CallNextHookEx(g_hHook, nCode, wParam, lParam)); } MW_KEYDOWN_DLLメッセージを受けたアプリは操作中フラグを立てます(主要部分のみ) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_KEYDOWN_DLL: ここで操作中フラグを立てます ←(2)  このフラグは一定時間後にタイマーが倒します break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return (0L); } 実行してみると(1)に来ません、当然(2)のフラグは立ちません WM_KEYDOWNの代わりにWM_CREATE、WM_CLOSEだときちんとフックします WM_CHAR、MW_KEYUPなどのキィーボード系のメッセージだとフックしません なぜでしょうか??? 多分きわめて初歩的な知識の欠如によるものでしょうが分かりません 宜しくご指導願います

  • Win32 APIに関する質問

    Win32 APIでwidowsプログラミングをしているのですが、 メニューを開きとあるダイアログを開きボタン(これを押すとエディットから、入力されている文字列を取得する) を押すとエディットに入力されている、文字列をメッセージボックスに表示するはずなんですが (Messengerはその問題のボタンがついているプログラム) 「Messenger が原因で USER.EXEにエラーが発生しました。Messenger は終了します」 と出てそのプログラム(Messenger)が、終了させられてしまいます。 GetDlgText()というAPIが原因だと言う所までは分かりましたが、そこからさきがまったく分かりません このバグの解決方法を教えてください ↓がソースです(結構長いのでダイアログのコールバックだけ書きます) BOOL CALLBACK Dialog_RoomOption(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp){ int error; LPTSTR s; HWND edit_RoomAbout; switch(msg){ case WM_INITDIALOG: SetDlgItemText(hwnd,EID_PASSWORDEDIT,"パスワードを入力してください"); return TRUE; case WM_COMMAND: switch(LOWORD(wp)){ case BID_CREATE: GetDlgItemText(hwnd,EID_PASSWORDEDIT,RoomPassword,sizeof(RoomPassword)); MessageBox(hwnd,RoomPassword,TEXT("TESTTEST"),MB_OK); EndDialog(hwnd,BID_CREATE); return TRUE; } break; case WM_CLOSE: EndDialog(hwnd,NULL); return TRUE; } return FALSE; }

  • win32apiでの動画出力

    win32apiとopenCVを使った動画出力プログラムを作りたいのですが, フリーズしてしまいます. 詳しい方,力を貸してください. 以下にプログラムを載せます. LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int x, y; int id; int c; char* szWndName = "camera capture"; CvCapture* capture; // IplImage* img; switch (msg) { case WM_CREATE: hDC = GetDC( hWnd ); return DefWindowProc(hWnd, msg, wParam, lParam); case WM_COMMAND: switch(LOWORD(wParam)){ case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; case IDM_USB: capture = cvCaptureFromCAM(0); if(capture == NULL){ MessageBox(hWnd, (LPCTSTR)TEXT("Not camera"), (LPCTSTR)TEXT("Test"), MB_OK); return -1; } while(1){ img = cvQueryFrame(capture); bmpData = (LPDWORD)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, img->width * img->height * 4); iplTobmp(img, bmpInfo, bmpData); StretchDIBits( hDC, 0, 0, img->width, img->height, 0, 0, img->width, img->height, bmpData, &bmpInfo, DIB_RGB_COLORS, SRCCOPY); } ReleaseDC(hWnd, hDC); cvReleaseCapture(&capture); return 0; break; } break; case WM_LBUTTONDOWN: // マウスカーソルが移動したときに送られてくる // 移動先の座標を取得 x = LOWORD( lParam ); y = HIWORD( lParam ); // 座標をテキストファイルに書き込む _ftprintf( g_fp, _T("(%d %d)\n"), x, y ); return 0; case WM_CLOSE: id = MessageBox(hWnd, TEXT("Close?"), TEXT("Close"), MB_OKCANCEL | MB_ICONQUESTION); if(id == IDOK) DestroyWindow(hWnd); return (0L); case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); }

  • エディットボックス内でキー押されたときのメッセージ

    VC++6.0です。 メインウインドウ内のエディットボックス(一行)で、特定のキー入力を検知したいのですが、どのようにすればよいでしょうか。 mfcは使ってません。 //ウインドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {  switch( message )  {   case WM_CREATE:    //エディットボックスを作成    CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT","",          WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL,          0,0,2000, 20, hWnd, (HMENU)IDC_EDIT, g_hInst, NULL );    break;   case WM_COMMAND:    //エディットボックス内の変更はEN_CHANGEで受け取れるが、    //キーコードは送られてこない    break;  } }

  • win32api 画面のちらつき

    win32api ビットマップを描画したとき、タイマーで少しずつ動かしているのですが、 画面がかなりちらつきます。   調べても、イマイチわからなくてどうすればいいかわかりません。 是非、わかりやすく教えていただきたいです。   タイマーの中身です。 ugokuはタイマーがあるかないかを判断するためにいれました。 なかなかいい方法が見つからなかったので。 playermukiはそのままです。 case WM_TIMER:  ugoku=1; if(playermuki==1){ playerX-=3; InvalidateRect(VisualWnd,NULL,TRUE); }else if(playermuki==2){ playerX+=3; InvalidateRect(VisualWnd,NULL,TRUE); }else if(playermuki==3){ playerY+=3; InvalidateRect(VisualWnd,NULL,TRUE); }else if(playermuki==4){ playerY-=3; InvalidateRect(VisualWnd,NULL,TRUE); } break; また、タイマーをセットするとき case WM_KEYDOWN: if(wParam==VK_RIGHT){ playermuki=1; if(ugoku==0){ SetTimer(VisualWnd,ID_T_UGOKI,50,NULL); } }else if(wParam==VK_LEFT){ playermuki=2; if(ugoku==0){ SetTimer(VisualWnd,ID_T_UGOKI,50,NULL); } }else if(wParam==VK_UP){ playermuki=3; if(ugoku==0){ SetTimer(VisualWnd,ID_T_UGOKI,50,NULL); } }else if(wParam==VK_DOWN){ playermuki=4; if(ugoku==0){ SetTimer(VisualWnd,ID_T_UGOKI,50,NULL); } } return 0; タイマーを切るとき case WM_KEYUP: if(wParam==VK_RIGHT){ KillTimer(VisualWnd,ID_T_UGOKI); ugoku=0; }else if(wParam==VK_LEFT){ KillTimer(VisualWnd,ID_T_UGOKI); ugoku=0; }else if(wParam==VK_UP){ KillTimer(VisualWnd,ID_T_UGOKI); ugoku=0; }else if(wParam==VK_DOWN){ KillTimer(VisualWnd,ID_T_UGOKI); ugoku=0; } return 0;

  • SetWindowsHookEx(グローバルフック)の質問

    SetWindowsHookExでグローバルフックして メッセージをすりかえる事って可能でしょうか? 例えばWM_KEYDOWNが送られてきたら、それを無視して WM_CLOSEとかえるといった具合に。 試しにWH_CALLWNDPROCで受け取ったメッセージを 書き換えるだけでは無理でした(WindowsXp SP2) MSDNのWH_CALLWNDPROCRETの関数CallWndRetProcの説明で 「このフックプロシージャは、メッセージを調べることはできますが、変更することはできません。」 となっていました。 ということはWH_CALLWNDPROCのCallWndProcでは変更できるのかな?と思った次第です。 何か情報があれば宜しくお願いします。 (2000では不可だけど98だとできるとか?)

  • なぜhButton1ボタンからのWM_COMMANDはフックできてクライアントエリアのWM_RBUTTONDOWNはフックできないのでしょうか?

    #define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc") #define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc") #define STRCOMMAND TEXT("ボタンが押されました") HWND hButton1; LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam; HDC hDC; if(nCode==HC_ACTION) { hDC = GetDC(pcwpRetStruct->hwnd); switch(pcwpRetStruct->message) { case WM_COMMAND: TextOut(hDC, 10, 10, STRCOMMAND, strlen(STRCOMMAND)); break; case WM_RBUTTONDOWN: TextOut(hDC, 10, 10, STRRBUTTON, strlen(STRRBUTTON)); break; } ReleaseDC(pcwpRetStruct->hwnd, hDC); } return CallNextHookEx(NULL, nCode, wParam, lParam); } LRESULT CALLBACK mainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HHOOK hHook; HDC hDC; switch(uMsg) { case WM_DESTROY: UnhookWindowsHookEx(hHook); PostQuitMessage(0); return 0; case WM_CREATE: hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, my_HookProc, NULL, GetCurrentThreadId() ); if(!hHook) MessageBox(NULL, "hooking failed", NULL, MB_OK); hButton1 = CreateWindow( "BUTTON", "hButton1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 40, 100, 20, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL ); return 0; case WM_LBUTTONDOWN: hDC = GetDC(hWnd); TextOut(hDC, 10, 10, STRLBUTTON, strlen(STRLBUTTON)); ReleaseDC(hWnd, hDC); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

  • WM_INITDIALOGのフック

    どこにも載っていないため質問させていただきます。 次のようなコードを書いたとき、ダイアログの出現の検知ができるWM_INITDIALOGを検知できないのはなぜでしょうか。 hHookForDialog = SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetProcForDialog, hDll, 0); LRESULT CALLBACK CallWndRetProcForDialog(int nCode, WPARAM wp, LPARAM lp) { if(nCode < 0) return CallNextHookEx(hHookForDialog, nCode, wp, lp); PCWPRETSTRUCT Wmes = (PCWPRETSTRUCT)lp; if(nCode == HC_ACTION) { if(Wmes->message == WM_INITDIALOG) { PostMessage(hWndToSendMessage, mesDialogCreated, (WPARAM)(Wmes->hwnd), NULL); } } return CallNextHookEx(hHookForDialog, nCode, wp, lp); } フック自体は成功しているようで、条件文を外すとメッセージはたくさん飛んできます。 けれども目的のWM_INITDIALOGは無いようです。 どうすればいいのかご教授お願いします。

  • WM_VSCROLL内の実行回数について

    Visual Studio 2010 Express WIN32 ユニコードビルド C言語 でクライアント領域に縦スクロールバーを貼り付け次のようなプログラムを作りました。 スクロールバーの勉強中に適当に作ったプログラムです。 LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { PAINTSTRUCT ps; TCHAR moji[256]; static int countout=0; static int countin=0;       switch(message){       case WM_PAINT: BeginPaint(hwnd,&ps); wsprintf(moji,TEXT("switch文の外=%d回 switch文の中=%d"),countout,countin); TextOut(ps.hdc,0,0,moji,lstrlen(moji)); EndPaint(hwnd,&ps); break; case WM_VSCROLL: countout=countout+1; switch(LOWORD(wParam)){ case SB_LINEDOWN: countin=countin+1; break; } InvalidateRect(hwnd,NULL,TRUE); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,message,wParam,lParam); } return 0; } 私はこのプログラムの実行結果は スクロールバーのどこをクリックしてもcountoutは+1され下の矢印をクリックしたときはcountinが+1 されるという動作になると思ったのですが実行してみると スクロールバーの矢印をクリック countout が+2 スクロールバーのつまみをクリック countout が+3 スクロールバーの下矢印をクリック countout が+2,countinが+1 されるという結果になりました。 この結果から推測するとVSCROLLバーをクリックしたときはWM_VSCROLL:メッセージが複数回送られているということになると思うのですがどうしてこうなるのでしょうか? プログラミングの本などではWM_VSCROLL:の中のswitch文の外に初期化やInvalidateRectがあるのでWM_VSCROLLメッセージが送られるのは1回だけだと思ったのですが・・・・。

専門家に質問してみよう