タッチデバイス

何年ぶりかわからないですが、タッチデバイスについて調べる機会があったので記しておきたいと思います。
ログまでとってあるので、それなりに役立つはず・・・。

まず使う必要はあるのか?

マウスの代用であればそのままの状態である「レガシーモード」でも一応は事足ります。
が、タッチ操作においては「マウスダウン相当が無い」というのがマウスやペンと大きく異なる挙動の1つです。
これは主に「プレスアンドホールド」機能(押しっぱなしで右クリック)の弊害で、指を離すまでは左クリックか右クリックかを決定出来ないため、指で押してもマウスダウンが発生しません。(勿論回避方法はあるのでそれは後記)

もし、クリックだけで構成されたユーザインターフェイスであれば、そのままでもタッチデバイス対応のアプリであることを理解してください。
もし自前で実装したスクロールバーや特殊なGUI(ゲームライクなGUI)がある場合は、タッチデ操作を意識したプログラムを組む必要があるでしょう。

モード

windowsにおけるタッチデバイスは主に3種類のモードがあります。

  1. LegacyDevice(レガシーデバイス
  2. TouchMDevice(タッチデバイス
  3. GestureDevice(ジェスチャーバイス

レガシーはそのままの状態でOSがタッチ操作をマウス操作に置き換えてくれます。
タッチはタッチ操作の生データを貰う方法で、より反応の良い挙動が可能です。が、後記する制約により単純に反応が早くなるわけではなく、ズームジェスチャーなどにも対応しません。
ジェスチャーはパンやズームなど特殊な操作をOSで解析して使用出来るモードです。タッチといえばコレですが、ほぼタッチアプリ専用です。マウスと混同使用を考えると相当苦戦されるでしょう。

プレスアンドホールド

windowsではジェスチャの1つであるプレスアンドホールドだけが特別な機能として別枠でもうけられています。
ペン(デジタイザ)とタッチ共用設定で、OSの設定関係なくアプリケーション層でOn/Off切り替えが可能です。
設定はグローバルアトムにて行います。

const TABLET_DISABLE_PRESSANDHOLD=$00000001;

TabletAtom := 'MicrosoftTabletPenServiceProperty';
AtomID := GlobalFindAtom(TabletAtom);
if (AtomID=0)then AtomID := GlobalAddAtom(TabletAtom);
flg := GetProp(windowhandle,TabletAtom);
SetProp(windowhandle, TabletAtom,flg or TABLET_DISABLE_PRESSANDHOLD);

このプレスアンドホールドの有無によってタッチ操作時のイベントの内容が変わります。
なので、3モードx2プレスアンドホールド=6 のパターンが存在します。

マウスダウンとクリック

タッチ操作でもうひとつ考慮したい点がこのマウスダウンです。
マウスで左ボタンを押し込んだ時にボタンのグラフィックが変わる挙動を実現するには、このイベントが必要になります。

タッチ操作では基本マウスダウンが指を押したときに発生しません。
プレスアンドホールドの関係で指を離すまで左右のボタン判定が決定しないため、離すタイミングで一気に(クリック)イベントがなだれ込みます。

wait	//指を離すまでイベント無し
mouse(FromTouch).move...0(194,154) 7543ms
mouse(FromTouch).down...0(194,154)Left 11ms
mouse(FromTouch).up...0(194,154)Left 6ms
mouse(FromMouse).move...0(194,154) 7ms

これはペンやマウスとは全く異質なイベントの流れで、もしクリック処理を「GetAsyncKeyState」によってポーリングを行っている場合、マウスダウン間隔が短すぎてクリック処理がすり抜けます。
必ずイベントを見て補間なりしないと、クリックすらできないアプリが出来上がります。

と、ここまでが前置きです。