■
WM_INPUTで送られてくる、マルチタッチ(multitouch)のRAWHID(生データ構造/Data Format)
typedef struct _OEM_INPUT_REPORT { UCHAR ReportID; union { struct { UCHAR bStatus; USHORT wXData; USHORT wYData; USHORT wPressureData; } InputReport; UCHAR RawInput[7]; }; } OEM_INPUT_REPORT, *POEM_INPUT_REPORT; #define REPORTID_FEATURE 7 #define REPORTID_MOUSE 3 #define REPORTID_MTOUCH 1 #define REPORTID_MAX_COUNT 8
c#で扱う場合は以下のように定義しておけば、最低限OKとなる。
[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct OEM_INPUT_REPORT { public int dwSizeHid; // byte size of each report public int dwCount; // number of input packed public byte ReportID; public byte bStatus; public byte ContactId; public ushort wXData; public ushort wYData; public byte bStatus2; public byte ContactId2; public ushort wXData2; public ushort wYData2; public byte ActualCount; }
RAWHIDから取りたい場合は
[DllImport("user32.dll")] public static extern int GetRawInputData( IntPtr rawInput, int command, IntPtr data, ref int size, int headerSize);
を使う。最初、IntPtr data に 0 を入れて、sizeをもらい、そのsizeでAllocHGlobalしたIntPtrを、再度渡す。そしてIntPtrからReadByteする。ReadByteのoffsetは16(ヘッダ分)+8(RAWHIDのヘッダ)から。
で、WM_INPUTのデータのbStatusはFINGER_STATUS,RANGE_STATUS,RANGE_FINGER_STATUSを見るべきか。
さらに、数値ではなく、ビットで判断すること!
// bStatus bit values #define INSTATUS_INITIAL_TOUCH 0x01 #define INSTATUS_TOUCH_MOVE 0x02 #define INSTATUS_UNTOUCH 0x04 #define INSTATUS_MULTI_TOUCH 0x08 #define INSTATUS_WARNING_PENDING 0x10 #define INSTATUS_RESERVED 0x20 #define INSTATUS_RANGE_CHECKING 0x40 #define INSTATUS_Z_MEASURE 0x80 #define FINGER_STATUS 0x01 // finger down (either touch or mouse) #define RANGE_STATUS 0x02 // inrange #define RANGE_FINGER_STATUS 0x03 // finger down (range + finge)
デバイス情報は以下で取得するが、PCに複数のデバイスが繋がっていたら、WM_INPUTのデバイスと、下記のデバイスが異なる場合もあるので、注意(現状未対応)。Microsoft.Ink.dllはWindows7なら、C:\Windows\assembly\GAC_32\Microsoft.Ink\6.1.0.0__31bf3856ad364e35\Microsoft.Ink.dllとかにあるはず。問題は、x64/x86の区別をどうするかだが、とりあえずx86で参照しておく。
Tablets ts = new Tablets(); Tablet t = ts.DefaultTablet;
そのほか
・生データなので、当然、画面の回転を考慮しなければならない
>タッチデバイスがどのディスプレイと対応しているかはどう判断するのだろう???