久しぶりのハッキングメモです。タイトル通りの内容で.NET FrameworkもといWindows.Formsフレームワークの仕様を掘り下げた記録です。
Win32APIのウィンドウメッセージも混ぜつつWindows.Formsフレームワークでのマウスのダブルクリックを行ったときのイベントの流れを調べると次のようになっていました。
- WM_LBUTTONDOWN message
- Control.MouseDown event
- WM_LBUTTONUP message
- Control.Click event
- Control.MouseClick event
- Control.MouseUp event
- WM_LBUTTONDBLCLK message
- Control.MouseDown event [*]
- WM_LBUTTONUP message
- Control.DoubleClick event
- Control.MouseDoubleClick event
- Control.MouseUp event [*]
Win32APIレベルでは「クリック」という概念は無く、Windows.Formsフレームワークにおける「クリック」はWM_LBUTTONUP(押し下げたマウスのボタンを放したイベント)によって生成されていることが分かります。またダブルクリックした場合でも一回目のクリックに関するイベントはシングルクリック時と同じように発生しています。当然ですが。さらに、Win32APIでは二回目のボタン押し下げイベントに対して通常のWM_LBUTTONDOWNではなくダブルクリック専用のWM_LBUTTONDOWNが送信されています。しかし、Windows.Formsフレームワーク側では一回目と同様にMouseDownイベントを発生させ、DoubleClickおよびMouseDoubleClickイベントを発生させています。なお二回目のクリックで発生するMouseDownおよびMouseUpイベント[*]発生時にイベントハンドラへ渡されるMouseEventArgs.Clicksは2に設定されています。
続いて他のプラットフォームがどうなのかということで、Mac OS XのCocoaフレームワークでの仕様を調べてみました。Mac OS X 10.6.6、Xcode 3.2.5でトリプルクリックを試したところ、次のような流れになっていました。
- mouseDown message (clickCount=1)
- mouseUp message (clickCount=1)
- mouseDown message (clickCount=2)
- mouseUp message (clickCount=2)
- mouseDown message (clickCount=3)
- mouseUp message (clickCount=3)
非常にシンプルです。Cocoaフレームワークは勉強を始めてから数日というレベルなのでリファレンスの読み込みが足らないのかもしれませんが、クリックという概念は直接フレームワークで提供していないようでした。まあmouseUpを受けてclickCountを判定すればクリックもダブルクリックも扱えますから特別にクリックという概念をフレームワークで用意するメリットは薄いようにも思えます。
あとはGtkも調べたのですが、こちらは記せるほど分かっていません。GTK#などから察するに、おそらくGDKの button_press_eventシグナルとbutton_release_eventシグナルを使ってCocoaと同様の考え方で処理するのだろうと思っています。
とりあえず仕様の整理。その上で設計を進めよう。うん。