シングルクリックとダブルクリックの使い分ける
Top -> プログラミング -> WindowsAPI プログラミング -> シングルクリックとダブルクリックの使い分ける
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; }

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

左 WM_LBUTTONDOWN -> WM_LBUTTONUP -> WM_LBUTTONDBLCLK -> WM_LBUTTONUP
右 WM_RBUTTONDOWN -> WM_RBUTTONUP -> WM_RBUTTONDBLCLK -> 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で書かれております。Linux系ではEUCに変換してお試しください。
戻る
カウンター