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;

そのほか
・生データなので、当然、画面の回転を考慮しなければならない
 >タッチデバイスがどのディスプレイと対応しているかはどう判断するのだろう???