JavaFXのSwingNodeがJavaFXのイベントをSwingのイベントに変換しているあたり(続々) - torutkのブログ
の続きです。
タッチパネル操作を認識する*1プログラムと、タッチパネル操作を認識しない*2プログラムに対するWindows OSからプログラムへ発行される入力操作に関するWindowsメッセージを調べてみました。
調査に使用したのはVisual Studio付属のSpy++ツールです。
タッチパネル操作を認識するプログラム宛に発行されるWindowsメッセージ
JavaFXプログラムを動かし、spy++ツールでJavaFXプログラムを指定してWindowsメッセージのログを取得しました。
タップ操作
タップ操作(画面上を1本の指で接触して離す操作)をした際にWindows OSからJavaFXプログラムに発行されたWindowsメッセージ(WM_TOUCH*、WM_MOUSE*、WM_?BUTTON*)です。
Windowsメッセージ | 属性 | 備考 |
---|---|---|
WM_TOUCH | nTouchPoints:1 | |
: | : | 10個程度発行 |
WM_MOUSEMOVE | ||
WM_LBUTTONDOWN | ||
WM_LBUTTONUP | ||
WM_MOUSEMOVE |
1点TOUCHイベントが数個発生してから、マウスの左ボタン押し下げ/離したイベントが発生しています。
長押し操作
長押し操作(画面上を1本の指で接触し1秒間そのままにしてから離す操作)をした際にWindows OSからJavaFXプログラムに発行されたWindowsメッセージ(WM_TOUCH*、WM_MOUSE*、WM_?BUTTON*)です。
Windowsメッセージ | 属性 | 備考 |
---|---|---|
WM_TOUCH | nTouchPoints:1 | |
: | : | 100個程度発行 |
WM_MOUSEMOVE | ||
WM_RBUTTONDOWN | 画面上に黒枠の矩形(指より大きい程度)が表示された | |
WM_RBUTTONUP | ||
WM_MOUSEMOVE |
1点TOUCHイベントが百個程度発生してから、マウスの右ボタン押し下げ/離したイベントが発生しています。
ピンチ操作
ピンチ操作(画面上を2本の指で接触し2本の指を互いに近づける操作)をした際にWindows OSからJavaFXプログラムに発行されたWindowsメッセージ(WM_TOUCH*、WM_MOUSE*、WM_?BUTTON*)です。
Windowsメッセージ | 属性 | 備考 |
---|---|---|
WM_TOUCH | nTouchPoints:1 | |
: | : | 数個程度発行 |
WM_TOUCH | nTouchPoints:2 | |
: | : | 10個程度発行 |
WM_MOUSEMOVE | ||
WM_LBUTTONDOWN | ||
WM_MOUSEMOVE | fwKeys:MK_LBUTTON | |
WM_TOUCH | nTouchPoints:2 | |
: | : | 10数個程度発行 |
WM_MOUSEMOVE | fwKeys:MK_LBUTTON | |
WM_TOUCH | nTouchPoints:2 | |
: | WM_MOUSEMOVEとWM_TOUCHのペアが30個程度連続発行 | |
WM_TOUCH | nTouchPoints:1 | |
: | : | 数個程度発行 |
WM_LBUTTONUP | ||
WM_MOUSEMOVE |
マウス左ボタン押下に続いて、2点TOUCHイベントとWM_MOUSEMOVEイベントが繰り返し発生しています。その後、左ボタンが離されたイベントで終わります。
スライド操作
スライド操作(画面上を1本の指で接触したまま移動させる操作)をした際にWindows OSからJavaFXプログラムに発行されたWindowsメッセージ(WM_TOUCH*、WM_MOUSE*、WM_?BUTTON*)です。
Windowsメッセージ | 属性 | 備考 |
---|---|---|
WM_TOUCH | nTouchPoints:1 | |
: | : | 10個程度発行 |
WM_MOUSEMOVE | ||
WM_LBUTTONDOWN | ||
WM_MOUSEMOVE | fwKeys:MK_LBUTTON | |
WM_TOUCH | nTouchPoints:1 | |
: | WM_MOUSEMOVEとWM_TOUCHのペアが数十個程度連続発行 | |
WM_LBUTTONUP | ||
WM_MOUSEMOVE |
タッチパネル操作を認識しないプログラム宛に発行されるWindowsメッセージ
UnregisterTouchWindow APIを呼ぶJavaFXプログラムを動かし、spy++ツールでJavaFXプログラムを指定してWindowsメッセージのログを取得しました。
タップ操作
タップ操作(画面上を1本の指で接触して離す操作)をした際にWindows OSからJavaFXプログラムに発行されたWindowsメッセージ(WM_TOUCH*、WM_MOUSE*、WM_?BUTTON*)です。
Windowsメッセージ | 属性 | 備考 |
---|---|---|
WM_MOUSEMOVE | ||
WM_LBUTTONDOWN | ||
WM_LBUTTONUP |
長押し操作
長押し操作(画面上を1本の指で接触し1秒間そのままにしてから離す操作)をした際にWindows OSからJavaFXプログラムに発行されたWindowsメッセージ(WM_TOUCH*、WM_MOUSE*、WM_?BUTTON*)です。
Windowsメッセージ | 属性 | 備考 |
---|---|---|
WM_MOUSEMOVE | ||
WM_RBUTTONDOWN | ||
WM_RBUTTONUP |
ピンチ操作
ピンチ操作(画面上を2本の指で接触し2本の指を互いに近づける操作)をした際にWindows OSからJavaFXプログラムに発行されたWindowsメッセージ(WM_TOUCH*、WM_MOUSE*、WM_?BUTTON*)です。
Windowsメッセージ | 属性 | 備考 |
---|---|---|
WM_GESTURE | BEGIN | |
WM_GESTURE | ZOOM | |
: | : | |
WM_MOUSELEAVE | ||
WM_MOUSEMOVE | ||
WM_GESTURE | ZOOM | |
: | : | |
WM_MOUSEWHEEL | MK_CONTROL | |
WM_MOUSEMOVE | MK_CONTROL | |
WM_GESTURE | ZOOM | |
: | : | |
WM_MOUSEWHEEL | MK_CONTROL | |
WM_MOUSEMOVE | MK_CONTROL |
JavaFXの内部でのタッチ操作イベントを捌いている箇所を調査
modules/graphics/src/main/native-glass/win/GlassWindow.cpp においてメンバー関数WindProcでWindowsメッセージの場合分けと処理(switch文)をしています。WM_TOUCHの場合の処理を抜粋します。
case WM_TOUCH: if (IsEnabled()) { if (activeTouchWindow == 0 || activeTouchWindow == GetHWND()) { if(HandleViewTouchEvent(GetHWND(), msg, wParam, lParam) > 0) { activeTouchWindow = GetHWND(); } else { activeTouchWindow = 0; } } return 0; } break;
modules/graphics/src/main/native-glass/win/ViewContainer.cpp において、ViewContainer::HandleViewTouchEventメンバー関数が定義されています。
- タッチ点数を取得(最大10)
- GetTouchInputInfo APIでタッチ情報を取得
- 前回のタッチ点数とタッチ情報と今回のタッチ点数とタッチ情報を突合せていろいろと処理・・・
- タッチ点数が0でない(正の数)であれば、ViewContainer::NotifyTouchInputメンバー関数を呼ぶ
modules/graphics/src/main/native-glass/win/ViewContainer.cpp において、ViewContainer::NotifyTouchInputメンバー関数が定義されています。
- com.sun.glass.ui.win.WinGestureSupport(Javaのクラス)のnotifyBeginTouchEventを呼ぶ
- com.sun.glass.ui.TouchInputSupportのnotifyBeginTouchEventを呼ぶ
- com.sun.glass.ui.win.WinGestureSupport(Javaのクラス)のnotifyNextTouchEventを呼ぶ(タッチ点数の数だけ)
- com.sun.glass.ui.TouchInputSupportのnotifyNextTouchEventを呼ぶ
- com.sun.glass.ui.win.WinGestureSupport(Javaのクラス)のnotifyEndTouchEventを呼ぶ
- com.sun.glass.ui.TouchInputSupportのnotifyEndTouchEventを呼ぶ
- com.sun.glass.ui.win.WinGestureSupportのgestureFinishedを呼ぶ
- ジェスチャがスクロールか、回転か、ズームかを判定し、com.sun.glass.ui.GestureSupportのhandleScrollingEnd、handleRotationEnd、handleZoomingEndを呼ぶ
ここから先の追跡が困難ですが、JDK 8u60に付属のjavafx-srcを展開し、中にあるcom.sun.javafx.tk.quantum.GestureRecognizers が、GlassTouchEventListenerを実装しており、また、notifyBeginTouchEvent、notifyNextTouchEvent、notifyEndTouchEventメソッドを定義しています。
ジェスチャーの識別については、com.sun.javafx.tk.quantumパッケージに、ScrollGestureRecognizer、ZoomGestureRecognizer、SwipeGestureRecognizerなどのクラスが用意されており、これらにTouchイベントの発生状況からどんなジェスチャーかを判定しているように思われます。