プロが教えるわが家の防犯対策術!

タイトルバー上でのマウスボタンのアップを検出したいので、
WM_NCLBUTTONUPメッセージを拾うために、単純に以下のようなコードを書きました。
が、このコードではうまくWM_NCLBUTTONUPメッセージを拾えません。
ウィンドウを最大化しているときは問題なくメッセージを拾えるのですが、
それ以外の時(縮小表示)はメッセージを拾えません。
ただ、WM_NCLBUTTONDOWNは正しく拾うことができました。
ウィンドウが縮小表示になっている時にWM_NCLBUTTONUPを取得する場合には何か特殊な処理が必要なんでしょうか?
ご存知の方がいらっしゃったら、よろしくお願いします。

// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

switch (message) {

case WM_NCLBUTTONUP:
MessageBox(hWnd, "UP", "LBUTTON", MB_OK);
return 0;

case WM_DESTROY:
// ウインドウが破棄されたときの処理
PostQuitMessage(0);
return 0;

default:
// デフォルトの処理
return DefWindowProc(hWnd, message, wParam, lParam);
}
}

A 回答 (1件)

★『縮小表示』って何?


・タイトルバー上のマウス左クリックについて簡単に説明します。
(1)『WM_NCLBUTTONDOWN』を検出
(2)左ドラッグでウインドウの移動を開始『WM_ENTERSIZEMOVE』メッセージが発生
(3)左ドラッグでウインドウの移動を処理『WM_MOVING』メッセージの処理中
(4)左ドラッグでウインドウの移動を終了『WM_EXITSIZEMOVE』メッセージが発生
・以上のステップで処理されますが、(4)の移動終了はマウスの左ボタンが離された時に
 『WM_NCLBUTTONUP』ではなく『WM_EXITSIZEMOVE』が発生します。
・よって、『WM_NCLBUTTONUP』メッセージが発生するのは左ダブルクリック後の
 『WM_NCLBUTTONUP』メッセージだけです。

方法:
・『WM_NCLBUTTONUP』を拾うには先に『WM_NCLBUTTONDOWN』メッセージを拾って何も処理しないが
 処理したよと通知します。→『0』をリターンする。
・すると『DefWindowProc』関数で『WM_NCLBUTTONDOWN』メッセージの初期動作『ウインドウ移動』
 が行われないため『WM_NCLBUTTONUP』メッセージが普通に発生して取得できます。
 しかし、この単純な方法ではウインドウの移動機能が失われます。
・ウインドウの移動機能を使いながら『WM_NCLBUTTONUP』を利用するには『WM_EXITSIZEMOVE』の
 メッセージを拾ったら『WM_NCLBUTTONUP』を『PostMessage』関数でメッセージをポストすればよい。
 『SendMessage』関数でもいけるかも。
・他にもマウス・メッセージが発生する前に『WM_NCHITTEST』が発生するのでここでマウスの左ボタンが
 離されたことを処理すればよいが、自分ですべてマウスメッセージを発生させるための『ヒットテスト』
 処理を行わないといけないため大変です。→『DefWindowProc』関数に任せましょう。

サンプル:
switch ( message ){
 case WM_NCLBUTTONUP:
  MessageBox( hWnd, "UP", "LBUTTON", MB_OK );
  return 0;
 case WM_DESTROY:
  PostQuitMessage( 0 );
  return 0;
 case WM_EXITSIZEMOVE:
 {
  POINT po;
  
  GetCursorPos( &po ); ←マウス位置を取得
  PostMessage( hWnd, WM_NCLBUTTONUP, HTCAPTION, MAKELPARAM(po.x,po.y) );
  return DefWindowProc( hWnd, message, wParam, lParam );
 }
 default:
  return DefWindowProc( hWnd, message, wParam, lParam );
}

最後に:
・『WM_NCLBUTTONUP』で『wParam』、『lParam』の引数を特に利用しないのならば、
 『PostMessage( hWnd, WM_NCLBUTTONUP, 0, 0 );』などでも良いでしょう。
・また『WM_EXITSIZEMOVE』メッセージを『return 0;』していませんがこれは、『DefWindowProc』関数で
 『WM_EXITSIZEMOVE』メッセージを受け取れるようにするためです。こうしないと多分、ウインドウ移動
 がずっと続いてしまかもね。→とりあえず試してみて下さい。
・上記の方法で駄目ならばまた別の方法を考えましょう。
・以上。おわり。
    • good
    • 0
この回答へのお礼

Oh-Orangeさん、適切な回答をありがとうございました。
おかげさまで問題は解決しました。感謝いたします。
DefWindowProcあたりが何かやっているのではないか・・・とは思っていたのですが、思いつくことを色々試してもダメで困っていたのです。
本当にありがとうございあます。

お礼日時:2007/01/31 16:18

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!