シングルクリックとダブルクリックの使い分ける
Top -> プログラミング -> WindowsSDK プログラミング -> シングルクリックとダブルクリックの使い分ける
1.シングルクリックとダブルクリックの使い分ける

ウインドウスタイルで「CS_DBLCLKS」を指定します。これを指定しないとダブルクリックが使用できません。

WNDCLASSEX wcl; 省略… wcl.style = CS_DBLCLKS; 省略…

他のプロパティも選択するのには以下のように「|」を使います。

WNDCLASSEX wcl; 省略… wcl.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; 省略…

ちなみに
CS_HREDRAWは水平方向のサイズ変更があったら全体を描き直し、 CS_VREDRAWは垂直方向のサイズ変更があったら全体を描き直しです。

2.正しく動作しないコード

シンプルに、左右シングルクリック、ダブルクリックしたらメッセージボックスを表示するコードを書いて見ます。

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message){ case WM_RBUTTONDOWN: MessageBox(hwnd, "右シングルクリック", "右シングルクリック", MB_OK); break; case WM_RBUTTONDBLCLK: MessageBox(hwnd, "右ダブルクリック", "右ダブルクリック", MB_OK); break; case WM_LBUTTONDOWN: MessageBox(hwnd, "左シングルクリック", "左シングルクリック", MB_OK); break; case WM_LBUTTONDBLCLK: MessageBox(hwnd, "左ダブルクリック", "左ダブルクリック", MB_OK); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }

このコードは一見正しく動作しそうですが、ダブルクリックがシングルクリックとして反応してしまいます。 これは、以下のようにメッセージが送られる為です。

左クリックの場合

  1. WM_LBUTTONDOWN
  2. WM_LBUTTONUP
  3. WM_LBUTTONDBLCLK
  4. WM_LBUTTONUP

右クリックの場合

  1. WM_RBUTTONDOWN
  2. WM_RBUTTONUP
  3. WM_RBUTTONDBLCLK
  4. WM_RBUTTONUP
3.正しく動作するコード

では、どのようにすれば良いのでしょうか?

上記のようにメッセージが送られてくるのを利用し、タイマーとGetDoubleClickTime()関数を使います。

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message){ case WM_RBUTTONDOWN: case WM_LBUTTONDOWN: SetTimer(hwnd, message, GetDoubleClickTime(), NULL); break; case WM_RBUTTONDBLCLK: KillTimer(hwnd, WM_RBUTTONDOWN); MessageBox(hwnd, "右ダブルクリック", "右ダブルクリック", MB_OK); break; case WM_LBUTTONDBLCLK: KillTimer(hwnd, WM_LBUTTONDOWN); MessageBox(hwnd, "左ダブルクリック", "左ダブルクリック", MB_OK); break; case WM_TIMER: KillTimer(hwnd, wParam); if(wParam == WM_RBUTTONDOWN) MessageBox(hwnd, "右シングルクリック", "右シングルクリック", MB_OK); if(wParam == WM_LBUTTONDOWN) MessageBox(hwnd, "左シングルクリック", "左シングルクリック", MB_OK); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }

他のプロパティも選択するのには以下のように「|」を使います。

WNDCLASSEX wcl; 省略… wcl.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; 省略…

WM_RBUTTONDOWNとWM_LBUTTONDOWNでタイマーを発生させます。

タイマー間隔は、GetDoubleClickTime()で得られた時間、すなわちダブルクリックの間隔です。 この間に、ダブルクリックメッセージがあればダブルクリック、タイマーメッセージであれば、シングルクリックとなります。

忘れていけないのは、メッセージが来た後、タイマーを切ることです。 これで、シングルとダブルクリックの使い分けができます。

サンプル

以下のリンクからサンプルを閲覧又はダウンロードできます。
このサンプルはSHIFT-JISで書かれております。

正しく動作しない方のソースファイル
正しく動作する方のソースファイル
戻る
カウンター