ダブルクリックでウインドウを閉じる


ヒカル  2003-06-20 20:56:24  No: 51571  IP: [192.*.*.*]

こんばんは、ヒカルです。

フックを勉強する為に、ダブルクリックでウインドウを閉じようとマウスのメッセージを取得してみました。

何とかやってみたのですが、これでは動作してくれませんでした。
どのあたりがマズイのでしょうか?

アドバイスお願いしますm(__)m

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow) {

sethook(hWnd);

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

freehook();

}

void  CALLBACK sethook(HWND PutHandle){

  if (!hHookWnd){

      hHookWnd = SetWindowsHookEx(WH_MOUSE , CallWndProc, NULL, 0);
    }

}

void CALLBACK freehook(void){

    UnhookWindowsHookEx(hHookWnd);

}

LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam){

    if (nCode < 0){

        return CallNextHookEx(hHookWnd, nCode, wParam, lParam);

  }else{

    if( nCode == HC_ACTION ){
    
      if (wParam == WM_LBUTTONDOWN){

          //PostMessage(hWnd, WM_CLOSE, 0, 0);
          MessageBox(NULL, "フック完成", "WM_LBUTTONDOWN", MB_OK);

      }
    }

    }

    return CallNextHookEx(hHookWnd, nCode, wParam, lParam);
}

いろいろ試してはいるのですが、どうしてもメッセージボックスの表示ができません。
これは一部抜粋なのですが、宜しくお願いします。

編集 削除
YuO  2003-06-20 22:07:33  No: 51572  IP: [192.*.*.*]

え〜っと,CallWndProcだと……

WPARAM値は,メッセージがCurrent Threadから送られてくればNon-Zero,
LPARAM値はCWPSTRUCT構造体へのポインタです。

なので,
> if?(wParam?==?WM_LBUTTONDOWN){
if (((CWPSTRUCT *)wParam)->message == WM_LBUTTONDOWN){
にしてみてはどうでしょう。

編集 削除
ヒカル  2003-06-21 07:54:10  No: 51573  IP: [192.*.*.*]

こんにちは、YuOさん。

>if (((CWPSTRUCT *)wParam)->message == WM_LBUTTONDBLCLK){

ありがとうございます、早速試しました。
これでもダメでした、EXE起動と同時に強制終了されてしまいます。

仕掛けるフックが
hHookWnd = SetWindowsHookEx(WH_MOUSE , CallWndProc, NULL, 0);
のように、WH_MOUSEがマズイのでしょうか?

SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, NULL, GetCurrentThreadId());

ここでスレッドを渡していなかったので追加しました、
すると、if (wParam == WM_LBUTTONDBLCLK){
これでフックできているみたいでした。

でも、メッセージボックスをOKするとメッセージボックスの
無限ループになってしまいました。

これはどういう事になっているのでしょうか?

編集 削除
ブタゴリラ  2003-06-21 16:37:17  No: 51574  IP: [192.*.*.*]

すみませんが、
勘違いしているかもしれませんが、ちょっと突っ込みます。

*訂正前*
>if (((CWPSTRUCT *)wParam)->message == WM_LBUTTONDBLCLK){
********
じゃ無くて、

*訂正後*
if (((CWPSTRUCT *)lParam)->message == WM_LBUTTONDBLCLK){
********
じゃないですか?
CWPSTRUCTの構造体のポインタは、

lParamの方だったと思います。

編集 削除
ヒカル  2003-06-21 22:52:12  No: 51575  IP: [192.*.*.*]

ブタゴリラ さんへ

if (((CWPSTRUCT *)lParam)->message == WM_LBUTTONDBLCLK){
にしたところ全くの無反応になります。

WM_MOUSEのフックの場合、wParamでメッセージを取れる
と思われます、CWPSTRUCTの構造体は関係無しに、
if (wParam == WM_LBUTTONDBLCLK){これで取れています。

ちなみに、メッセージボックをだすでは無しに、
WM_CLOSEをそれで送信すると正常に動作しています。

メッセージボックスのボタンを押すとどうも
無限ループに陥るような実験結果となりました。

う〜ん、自分でもよく分かりません(^^;

編集 削除
岡田 之仁  2003-06-22 09:16:34  No: 51576  IP: [192.*.*.*]

> if (((CWPSTRUCT *)lParam)->message == WM_LBUTTONDBLCLK){
> にしたところ全くの無反応になります。

> WM_MOUSEのフックの場合、wParamでメッセージを取れる
> と思われます、CWPSTRUCTの構造体は関係無しに、
> if (wParam == WM_LBUTTONDBLCLK){これで取れています。

思われます・・・と書かれていますが、ヘルプで調べていないのですか?
SetWindowsHookEx(...)で、MH_MOUSE の場合は、MouseProcを参照で、
MOUSEHOOKSTRUCT 構造体は、同じく、lParam で渡されます。

無反応になるのは・・・もしかして・・・

ATOM MyRegisterClass( HINSTANCE hInstance )
{
  WNDCLASSEX wcex;

  wcex.cbSize = sizeof(WNDCLASSEX); 

  wcex.style    = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  wcex.lpfnWndProc  = (WNDPROC)WndProc;
  wcex.cbClsExtra    = 0;
  wcex.cbWndExtra    = 0;
  wcex.hInstance    = hInstance;
  wcex.hIcon    = LoadIcon(hInstance, (LPCTSTR)IDI_HOOKTEST);
  wcex.hCursor    = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
  wcex.lpszMenuName  = (LPCSTR)IDC_HOOKTEST;
  wcex.lpszClassName  = szWindowClass;
  wcex.hIconSm    = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

  return RegisterClassEx( &wcex );
}

の部分の、CS_DBLCLKS が無いと、クライアントエリアでのダブルクリックは
正確にイベントが発生しないとありますが・・・

今一度、コードの見直しをして下さい。

以上。

編集 削除
ヒカル  2003-06-22 21:06:48  No: 51577  IP: [192.*.*.*]

岡田 之仁 さんへ

>思われます・・・と書かれていますが、ヘルプで調べていないのですか?
>SetWindowsHookEx(...)で、MH_MOUSE の場合は、MouseProcを参照で、
>MOUSEHOOKSTRUCT 構造体は、同じく、lParam で渡されます。

if (wParam == WM_LBUTTONDBLCLK){
実際に、これで取れていまして、WM_CLOSEで
閉じることもできました。

ただ、if (((CWPSTRUCT *)lParam)->message == WM_LBUTTONDBLCLK){
これではできないという事でした。

>の部分の、CS_DBLCLKS が無いと、クライアントエリアでのダブルクリックは
>正確にイベントが発生しないとありますが・・・

これがないと上記のコードも動作しませんよね(^^

編集 削除