タッチ関連の API は 2種類あります。
WM_TOUCH 系と WM_GESTURE 系
WM_TOUCH 系の方が低レベルで、直接複数のタッチ座標を取り出すことが出来ます。
WM_GESTURE の方はいくつかの決まった操作を容易に受け取ることができます。
WM_TOUCH 系のメッセージを有効にするには RegisterTouchWindow() を呼び出します。
これを実行しておかないと WM_TOUCH~ が送られて来ません。
データを受け取るのは簡単です。
WM_TOUCHDOWN
WM_TOUCHUP
WM_TOUCHMOVE
などマウスとよく似ているメッセージが来るので、さらに
GetTouchInputInfo() を使って詳細な情報を読み取ります。
起動時の判定
// ハードがマルチタッチをサポートしているかどうか
int value= ~GetSystemMetrics( SM_DIGITIZER );
if( !(value & 0xc0) ){
RegisterTouchWindow( hwnd, 0 );
}
メッセージ
case WM_TOUCHDOWN:
case WM_TOUCHUP:
case WM_TOUCHMOVE:
WM_Touch( mes, wparam, lparam );
return FALSE;
読み出しの例
void WM_Touch( UINT mes, WPARAM wparam, LPARAM lparam )
{
int inputs= LOWORD( wparam );
TOUCHINPUT tbuf[TOUCHMAX];
HANDLE hinput= reinterpret_cast( lparam );
if( GetTouchInputInfo( hinput, inputs, tbuf, sizeof(TOUCHINPUT) ) ){
TOUCHINPUT* tp= tbuf;
for( int i= 0 ; i< inputs ; i++, tp++ ){
...
}
}
CloseTouchInputHandle( hinput );
}
座標値そのままなので、これを元にズームや回転などの操作を検出するには
さらに一手間いります。
WM_GESTURE 系はそのあたりを簡単にしてくれます。
下記の操作が定義されています。
GID_ZOOM
GID_PAN
GID_ROTATE
GID_TWOFINGERTAP
GID_ROLLOVER
これらのメッセージは RegisterTouchWindow() を実行すると来なくなるので
WM_GESTURE 系を使う場合は RegisterTouchWindow() を実行してはいけません。
WM_GESTURE が送られてきたらさらに追加情報を受け取ります。
case WM_GESTURE:
WM_Gesture( mes, wparam, lparam );
return FALSE;
void WM_Gesture( UINT mes, WPARAM wparam, LPARAM lparam )
{
GESTUREINFO ginfo;
memset( &ginfo, 0, sizeof(GESTUREINFO) );
ginfo.cbSize= sizeof(GESTUREINFO);
HGESTUREINFO hgesture= reinterpret_cast( lparam );
if( GetGestureInfo( hgesture, &ginfo ) ){
...
}
CloseGestureInfoHandle( hgesture );
}
WM_GESTURE 系の仕様は若干変更があったようで、資料によっては記載内容が
異なっていることがあります。例えば今でも
・MSDN WM_GESTURE Message
このページにある dwCommand は存在しておらず GESTUREINFO 構造体の
dwID のことだと思われます。
同じように dwArgument も 64bit の ullArguments に変更されているようです。
・dwCommand → GESTUREINFO dwID
・dwArgument → GESTUREINFO ullArguments
・lParam → GESTUREINFO ptsLocation
その他いくつか気が付いた点。
初期状態では GID_ROTATE などのメッセージが来ませんでした。
SetGestureConfig() を使って送って欲しいメッセージの登録が出来るようです。
const int ConfigCount= 5;
GESTURECONFIG config[ConfigCount];
memset( config, 0, sizeof(GESTURECONFIG) * ConfigCount );
config[0].dwID= GID_ZOOM;
config[0].dwWant= GC_ZOOM;
config[1].dwID= GID_PAN;
config[1].dwWant= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY
|GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY
|GC_PAN_WITH_GUTTER
|GC_PAN_WITH_INERTIA;
config[2].dwID= GID_ROTATE;
config[2].dwWant= GC_ROTATE;
config[3].dwID= GID_TWOFINGERTAP;
config[3].dwWant= GC_TWOFINGERTAP;
config[4].dwID= GID_ROLLOVER;
config[4].dwWant= GC_ROLLOVER;
SetGestureConfig( hwnd, 0, 5, config, sizeof(GESTURECONFIG) );
これで全部のメッセージとオプションが有効になるはずです。
座標は ptsLocation に、追加パラメータは ullArguments に入ります。
GID_PAN + GF_INERTIA フラグが ON の場合は、ullArguments の上位 32bit に
慣性のパラメータが格納されているようです。
GID_INERTIA というのは存在していません。
なお、これらの動作を確認するには
・Windows7 Beta
・Windows SDK for Windows 7 BETA
・MultiTouch 対応 PC
が必要です。Vista では起動時に DLL の互換性が無くエラーになります。
HP の TouchSmart PC IQ800 を使いました。
Windows7 SDK の設定には少々注意が必要です。
新しい DirectX SDK もリリースされているので、DirectX SDK March 2009 を
併用する場合は特に。基本的にあとからリリースされた方を上にします。
・DirectX SDK March 2009
・Windows SDK for Windows 7 BETA
・VisualStudio 2008
VisualStudio の Tools → Options → Projects and Solutions → VC++ DIrectories の設定
Include files
$(DXSDK_DIR)include
$(WindowsSdkDir)\include
$(VCInstallDir)include
~
Library files (x64)
$(DXSDK_DIR)lib\x64
$(WindowsSdkDir)lib\x64
$(VCInstallDir)lib\amd64
~
Library files (x86)
$(DXSDK_DIR)lib\x86
$(WindowsSdkDir)lib
$(VCInstallDir)lib
~
またあらかじめスタートメニュー Microsoft Windows SDK v7.0 から
Windows SDK Configuration Tool を起動して v7.0 を選択しておきます。
関連エントリ
・DirectX SDK March 2009
・Windows7 とマルチタッチ / HP TouchSmart PC IQ800
・Direct2D と Direct3D10.1 の下位互換