Browse Source

# revisions: 33746,33763

git-svn-id: branches/fixes_3_0@33792 -
marco 9 years ago
parent
commit
6e11cbc95e

+ 2 - 0
.gitattributes

@@ -12855,6 +12855,8 @@ tests/test/units/variants/tcustomvariant.pp svneol=native#text/plain
 tests/test/units/variants/tvararrayofintf.pp svneol=native#text/plain
 tests/test/units/variants/tw26370.pp svneol=native#text/plain
 tests/test/units/variants/tw27044.pp svneol=native#text/plain
+tests/test/units/windows/twinrawinput32.pp svneol=native#text/plain
+tests/test/units/windows/twinrawinput64.pp svneol=native#text/plain
 tests/test/uobjc24.pp svneol=native#text/plain
 tests/test/uobjc26.pp svneol=native#text/plain
 tests/test/uobjc27a.pp svneol=native#text/plain

+ 1 - 0
rtl/win/wininc/ascdef.inc

@@ -293,6 +293,7 @@ function WinHelp(hWndMain:HWND; lpszHelp:LPCSTR; uCommand:UINT; dwData:DWORD):WI
 function ChangeDisplaySettings(lpDevMode:LPDEVMODE; dwFlags:DWORD):LONG; external 'user32' name 'ChangeDisplaySettingsA';
 function EnumDisplaySettings(lpszDeviceName:LPCSTR; iModeNum:DWORD; lpDevMode:LPDEVMODE):WINBOOL; external 'user32' name 'EnumDisplaySettingsA';
 function SystemParametersInfo(uiAction:UINT; uiParam:UINT; pvParam:PVOID; fWinIni:UINT):WINBOOL; external 'user32' name 'SystemParametersInfoA';
+function GetRawInputDeviceInfo(hDevice: HANDLE; uiCommand: UINT; pData: LPVOID; pcbSize: PUINT): UINT external 'user32' name 'GetRawInputDeviceInfoA';
 function AddFontResource(_para1:LPCSTR):longint; external 'gdi32' name 'AddFontResourceA';
 function CopyMetaFile(_para1:HMETAFILE; _para2:LPCSTR):HMETAFILE; external 'gdi32' name 'CopyMetaFileA';
 function CreateFont(_para1:longint; _para2:longint; _para3:longint; _para4:longint; _para5:longint;_para6:DWORD; _para7:DWORD; _para8:DWORD; _para9:DWORD; _para10:DWORD;_para11:DWORD; _para12:DWORD; _para13:DWORD; _para14:LPCSTR):HFONT;

+ 1 - 0
rtl/win/wininc/ascfun.inc

@@ -296,6 +296,7 @@ function WinHelpA(hWndMain:HWND; lpszHelp:LPCSTR; uCommand:UINT; dwData:DWORD):W
 function ChangeDisplaySettingsA(lpDevMode:LPDEVMODE; dwFlags:DWORD):LONG; external 'user32' name 'ChangeDisplaySettingsA';
 function EnumDisplaySettingsA(lpszDeviceName:LPCSTR; iModeNum:DWORD; lpDevMode:LPDEVMODE):WINBOOL; external 'user32' name 'EnumDisplaySettingsA';
 function SystemParametersInfoA(uiAction:UINT; uiParam:UINT; pvParam:PVOID; fWinIni:UINT):WINBOOL; external 'user32' name 'SystemParametersInfoA';
+function GetRawInputDeviceInfoA(hDevice: HANDLE; uiCommand: UINT; pData: LPVOID; pcbSize: PUINT): UINT external 'user32' name 'GetRawInputDeviceInfoA';
 function AddFontResourceA(_para1:LPCSTR):longint; external 'gdi32' name 'AddFontResourceA';
 function CopyMetaFileA(_para1:HMETAFILE; _para2:LPCSTR):HMETAFILE; external 'gdi32' name 'CopyMetaFileA';
 function CreateFontA(_para1:longint; _para2:longint; _para3:longint; _para4:longint; _para5:longint;_para6:DWORD; _para7:DWORD; _para8:DWORD; _para9:DWORD; _para10:DWORD;_para11:DWORD; _para12:DWORD; _para13:DWORD; _para14:LPCSTR):HFONT;

+ 1 - 0
rtl/win/wininc/base.inc

@@ -143,6 +143,7 @@
      HWINSTA = HANDLE;
      HWND = HANDLE;
      HTASK = HANDLE;
+     HRAWINPUT = HANDLE;
 
      LANGID = word;
      LCID   = DWORD;

+ 112 - 0
rtl/win/wininc/defines.inc

@@ -6097,6 +6097,118 @@ const
     REPLACEFILE_IGNORE_MERGE_ERRORS = $00000002;
     REPLACEFILE_IGNORE_ACL_ERRORS   = $00000004;
 
+// WM_INPUT wParam
+(*
+ * The input is in the regular message flow,
+ * the app is required to call DefWindowProc
+ * so that the system can perform clean ups.
+ *)
+    RIM_INPUT       = 0;
+
+(*
+ * The input is sink only. The app is expected
+ * to behave nicely.
+ *)
+    RIM_INPUTSINK   = 1;
+
+(*
+ * Type of the raw input
+ *)
+  RIM_TYPEMOUSE       = 0;
+  RIM_TYPEKEYBOARD    = 1;
+  RIM_TYPEHID         = 2;
+
+(*
+ * Define the mouse button state indicators.
+ *)
+
+  RI_MOUSE_LEFT_BUTTON_DOWN   = $0001;  // Left Button changed to down.
+  RI_MOUSE_LEFT_BUTTON_UP     = $0002;  // Left Button changed to up.
+  RI_MOUSE_RIGHT_BUTTON_DOWN  = $0004;  // Right Button changed to down.
+  RI_MOUSE_RIGHT_BUTTON_UP    = $0008;  // Right Button changed to up.
+  RI_MOUSE_MIDDLE_BUTTON_DOWN = $0010;  // Middle Button changed to down.
+  RI_MOUSE_MIDDLE_BUTTON_UP   = $0020;  // Middle Button changed to up.
+
+  RI_MOUSE_BUTTON_1_DOWN      = RI_MOUSE_LEFT_BUTTON_DOWN;
+  RI_MOUSE_BUTTON_1_UP        = RI_MOUSE_LEFT_BUTTON_UP;
+  RI_MOUSE_BUTTON_2_DOWN      = RI_MOUSE_RIGHT_BUTTON_DOWN;
+  RI_MOUSE_BUTTON_2_UP        = RI_MOUSE_RIGHT_BUTTON_UP;
+  RI_MOUSE_BUTTON_3_DOWN      = RI_MOUSE_MIDDLE_BUTTON_DOWN;
+  RI_MOUSE_BUTTON_3_UP        = RI_MOUSE_MIDDLE_BUTTON_UP;
+
+  RI_MOUSE_BUTTON_4_DOWN      = $0040;
+  RI_MOUSE_BUTTON_4_UP        = $0080;
+  RI_MOUSE_BUTTON_5_DOWN      = $0100;
+  RI_MOUSE_BUTTON_5_UP        = $0200;
+
+(*
+ * If usButtonFlags has RI_MOUSE_WHEEL, the wheel delta is stored in usButtonData.
+ * Take it as a signed value.
+ *)
+  RI_MOUSE_WHEEL              = $0400;
+
+(*
+ * Define the mouse indicator flags.
+ *)
+  MOUSE_MOVE_RELATIVE      = 0;
+  MOUSE_MOVE_ABSOLUTE      = 1;
+  MOUSE_VIRTUAL_DESKTOP    = $02;  // the coordinates are mapped to the virtual desktop
+  MOUSE_ATTRIBUTES_CHANGED = $04;  // requery for mouse attributes
+//#if(WINVER >= 0x0600)
+  MOUSE_MOVE_NOCOALESCE    = $08;  // do not coalesce mouse moves
+//#endif /* WINVER >= 0x0600 */
+
+(*
+ * Define the keyboard overrun MakeCode.
+ *)
+
+  KEYBOARD_OVERRUN_MAKE_CODE    = $FF;
+
+(*
+ * Define the keyboard input data Flags.
+ *)
+  RI_KEY_MAKE             = 0;
+  RI_KEY_BREAK            = 1;
+  RI_KEY_E0               = 2;
+  RI_KEY_E1               = 4;
+  RI_KEY_TERMSRV_SET_LED  = 8;
+  RI_KEY_TERMSRV_SHADOW   = $10;
+
+(*
+ * Flags for GetRawInputData
+ *)
+
+  RID_INPUT               = $10000003;
+  RID_HEADER              = $10000005;
+
+(*
+ * Raw Input Device Information
+ *)
+  RIDI_PREPARSEDDATA      = $20000005;
+  RIDI_DEVICENAME         = $20000007;  // the return valus is the character length, not the byte size
+  RIDI_DEVICEINFO         = $2000000b;
+
+  RIDEV_REMOVE            = $00000001;
+  RIDEV_EXCLUDE           = $00000010;
+  RIDEV_PAGEONLY          = $00000020;
+  RIDEV_NOLEGACY          = $00000030;
+  RIDEV_INPUTSINK         = $00000100;
+  RIDEV_CAPTUREMOUSE      = $00000200;  // effective when mouse nolegacy is specified, otherwise it would be an error
+  RIDEV_NOHOTKEYS         = $00000200;  // effective for keyboard.
+  RIDEV_APPKEYS           = $00000400;  // effective for keyboard.
+//#if(_WIN32_WINNT >= 0x0501)
+  RIDEV_EXINPUTSINK       = $00001000;
+  RIDEV_DEVNOTIFY         = $00002000;
+//#endif /* _WIN32_WINNT >= 0x0501 */
+  RIDEV_EXMODEMASK        = $000000F0;
+
+//#if(_WIN32_WINNT >= 0x0501)
+(*
+ * Flags for the WM_INPUT_DEVICE_CHANGE message.
+ *)
+  GIDC_ARRIVAL             = 1;
+  GIDC_REMOVAL             = 2;
+//#endif /* _WIN32_WINNT >= 0x0501 */
 {$endif read_interface}
 
 {$ifdef read_implementation}

+ 46 - 0
rtl/win/wininc/func.inc

@@ -668,6 +668,12 @@ function TrackPopupMenuEx(_para1:HMENU; _para2:UINT; _para3:longint; _para4:long
 function ChildWindowFromPointEx(_para1:HWND; _para2:POINT; _para3:UINT):HWND; external 'user32' name 'ChildWindowFromPointEx';
 function DrawIconEx(hdc:HDC; xLeft:longint; yTop:longint; hIcon:HICON; cxWidth:longint;cyWidth:longint; istepIfAniCur:UINT; hbrFlickerFreeDraw:HBRUSH; diFlags:UINT):WINBOOL; external 'user32' name 'DrawIconEx';
 function GetWindowInfo(hWnd:HWND; pwi:PWindowInfo):WINBOOL; external 'user32' name 'GetWindowInfo';
+function GetRawInputData(hRawInput: HRAWINPUT; uiCommand: UINT; pData: LPVOID; pcbSize: PUINT; cbSizeHeader: UINT): UINT; external 'user32' name 'GetRawInputData';
+function GetRawInputBuffer(pData: PRAWINPUT; pcbSize: PUINT; cbSizeHeader: UINT): UINT; external 'user32' name 'GetRawInputBuffer';
+function RegisterRawInputDevices(pRawInputDevices: PCRAWINPUTDEVICE; uiNumDevices: UINT; cbSize: UINT):WINBOOL; external 'user32' name 'RegisterRawInputDevices';
+function GetRegisteredRawInputDevices(pRawInputDevices: PRAWINPUTDEVICE; puiNumDevices: PUINT; cbSize: UINT): UINT; external 'user32' name 'GetRegisteredRawInputDevices';
+function GetRawInputDeviceList(pRawInputDeviceList: PRAWINPUTDEVICELIST; puiNumDevices: PUINT; cbSize: UINT): UINT; external 'user32' name 'GetRawInputDeviceList';
+function DefRawInputProc(paRawInput: PPRAWINPUT; nInput: longint; cbSizeHeader: UINT): LRESULT; external 'user32' name 'DefRawInputProc';
 
 function AnimatePalette(_para1:HPALETTE; _para2:UINT; _para3:UINT; var _para4:PALETTEENTRY):WINBOOL; external 'gdi32' name 'AnimatePalette';
 function Arc(_para1:HDC; _para2:longint; _para3:longint; _para4:longint; _para5:longint;_para6:longint; _para7:longint; _para8:longint; _para9:longint):WINBOOL; external 'gdi32' name 'Arc';
@@ -1276,6 +1282,16 @@ function EndMenu:BOOL; external 'user32' name 'EndMenu';
 function GetMenuBarInfo(_hwnd:HWND; idObject:longint; idItem:longint; pmbi:LPMENUBARINFO):BOOL; external 'user32' name 'GetMenuBarInfo';
 function IMAGE_FIRST_SECTION(ntheader : PIMAGE_NT_HEADERS):PIMAGE_SECTION_HEADER;
 
+function GET_RAWINPUT_CODE_WPARAM(wp: WPARAM): longint; inline;
+function RAWINPUT_ALIGN(x: PtrUInt): PtrUInt; inline;
+function NEXTRAWINPUTBLOCK(ptr: PRAWINPUT): PRAWINPUT; inline;
+function RIDEV_EXMODE(mode: DWORD): DWORD; inline;
+//#if (_WIN32_WINNT >= 0x0601)
+function GET_DEVICE_CHANGE_WPARAM(wParam: WPARAM): WORD; inline;
+//#elif (_WIN32_WINNT >= 0x0501)
+function GET_DEVICE_CHANGE_LPARAM(lParam: LPARAM): WORD; inline;
+//#endif /* (_WIN32_WINNT >= 0x0601) */
+
 {$endif read_interface}
 
 
@@ -2389,5 +2405,35 @@ begin
   IMAGE_FIRST_SECTION:=PIMAGE_SECTION_HEADER(OFS(ntheader^.OptionalHeader) + ntheader^.FileHeader.SizeOfOptionalHeader);
 end;
 
+function GET_RAWINPUT_CODE_WPARAM(wp: WPARAM): longint;
+begin
+  GET_RAWINPUT_CODE_WPARAM:=wp and $FF;
+end;
+
+function RAWINPUT_ALIGN(x: PtrUInt): PtrUInt;
+begin
+  RAWINPUT_ALIGN:=PtrUInt(x+(SizeOf(PtrUInt)-1)) and not PtrUInt(SizeOf(PtrUInt)-1);
+end;
+
+function NEXTRAWINPUTBLOCK(ptr: PRAWINPUT): PRAWINPUT;
+begin
+  NEXTRAWINPUTBLOCK:=PRAWINPUT(RAWINPUT_ALIGN(ULONG_PTR(PBYTE(ptr)+ptr^.header.dwSize)));
+end;
+
+function RIDEV_EXMODE(mode: DWORD): DWORD;
+begin
+  RIDEV_EXMODE:=mode and RIDEV_EXMODEMASK;
+end;
+
+function GET_DEVICE_CHANGE_WPARAM(wParam: WPARAM): WORD;
+begin
+  GET_DEVICE_CHANGE_WPARAM:=LOWORD(wParam);
+end;
+
+function GET_DEVICE_CHANGE_LPARAM(lParam: LPARAM): WORD;
+begin
+  GET_DEVICE_CHANGE_LPARAM:=LOWORD(lParam);
+end;
+
 {$endif read_implementation}
 

+ 200 - 0
rtl/win/wininc/struct.inc

@@ -9108,7 +9108,207 @@ type
     LPPROGRESS_ROUTINE = function(TotalFileSize,TotalBytesTransferred,StreamSize,StreamBytesTransferred:LARGE_INTEGER;dwStreamNumber,dwCallbackReason:DWord;hSourceFile,hDestinationFile :THandle;lpdata:pointer):Dword; Stdcall;
     TPROGRESS_ROUTINE = LPPROGRESS_ROUTINE;
 
+// Raw Input Messages
+//#if(_WIN32_WINNT >= 0x0501)
+{$push}{$packrecords 4}
+    tagRAWINPUTHEADER = record
+      dwType: DWORD;
+      dwSize: DWORD;
+      hDevice: HANDLE;
+      wParam: WPARAM;
+    end;
+    RAWINPUTHEADER = tagRAWINPUTHEADER;
+    TRAWINPUTHEADER = tagRAWINPUTHEADER;
+    PRAWINPUTHEADER = ^tagRAWINPUTHEADER;
+    LPRAWINPUTHEADER = ^tagRAWINPUTHEADER;
+
+(*
+ * Raw format of the mouse input
+ *)
+    tagRAWMOUSE = record
+      (*
+       * Indicator flags.
+       *)
+      usFlags: USHORT;
+
+      case longint of
+        0: (
+          (*
+           * The transition state of the mouse buttons.
+           *)
+          ulButtons: ULONG;
+
+          (*
+           * The raw state of the mouse buttons.
+           *)
+          ulRawButtons: ULONG;
+
+          (*
+           * The signed relative or absolute motion in the X direction.
+           *)
+          lLastX: LONG;
+
+          (*
+           * The signed relative or absolute motion in the Y direction.
+           *)
+          lLastY: LONG;
+
+          (*
+           * Device-specific additional information for the event.
+           *)
+          ulExtraInformation: ULONG
+        );
+        1: (
+          (*
+           * The transition state of the mouse buttons.
+           *)
+          usButtonFlags: USHORT;
+          usButtonData: USHORT
+        );
+    end;
+    RAWMOUSE = tagRAWMOUSE;
+    TRAWMOUSE = tagRAWMOUSE;
+    PRAWMOUSE = ^tagRAWMOUSE;
+    LPRAWMOUSE = ^tagRAWMOUSE;
 
+(*
+ * Raw format of the keyboard input
+ *)
+    tagRAWKEYBOARD = record
+      (*
+       * The "make" scan code (key depression).
+       *)
+      MakeCode: USHORT;
+
+      (*
+       * The flags field indicates a "break" (key release) and other
+       * miscellaneous scan code information defined in ntddkbd.h.
+       *)
+      Flags: USHORT;
+
+      Reserved: USHORT;
+
+      (*
+       * Windows message compatible information
+       *)
+      VKey: USHORT;
+      Message: UINT;
+
+      (*
+       * Device-specific additional information for the event.
+       *)
+      ExtraInformation: ULONG;
+    end;
+    RAWKEYBOARD = tagRAWKEYBOARD;
+    TRAWKEYBOARD = tagRAWKEYBOARD;
+    PRAWKEYBOARD = ^tagRAWKEYBOARD;
+    LPRAWKEYBOARD = ^tagRAWKEYBOARD;
+
+    (*
+     * Raw format of the input from Human Input Devices
+     *)
+    tagRAWHID = record
+      dwSizeHid: DWORD;    // byte size of each report
+      dwCount: DWORD;      // number of input packed
+      bRawData: array [0..0] of BYTE;
+    end;
+    RAWHID = tagRAWHID;
+    TRAWHID = tagRAWHID;
+    PRAWHID = ^tagRAWHID;
+    LPRAWHID = ^tagRAWHID;
+
+(*
+ * RAWINPUT data structure.
+ *)
+    tagRAWINPUT = record
+      header: RAWINPUTHEADER;
+      data: record
+        case longint of
+          0: (mouse: RAWMOUSE);
+          1: (keyboard: RAWKEYBOARD);
+          2: (hid: RAWHID);
+      end;
+    end;
+    RAWINPUT = tagRAWINPUT;
+    TRAWINPUT = tagRAWINPUT;
+    PRAWINPUT = ^tagRAWINPUT;
+    LPRAWINPUT = ^tagRAWINPUT;
+    PPRAWINPUT = ^PRAWINPUT;
+    LPLPRAWINPUT = ^LPRAWINPUT;
+
+    tagRID_DEVICE_INFO_MOUSE = record
+      dwId: DWORD;
+      dwNumberOfButtons: DWORD;
+      dwSampleRate: DWORD;
+      fHasHorizontalWheel: BOOL;
+    end;
+    RID_DEVICE_INFO_MOUSE = tagRID_DEVICE_INFO_MOUSE;
+    TRID_DEVICE_INFO_MOUSE = tagRID_DEVICE_INFO_MOUSE;
+    PRID_DEVICE_INFO_MOUSE = ^tagRID_DEVICE_INFO_MOUSE;
+
+    tagRID_DEVICE_INFO_KEYBOARD = record
+      dwType: DWORD;
+      dwSubType: DWORD;
+      dwKeyboardMode: DWORD;
+      dwNumberOfFunctionKeys: DWORD;
+      dwNumberOfIndicators: DWORD;
+      dwNumberOfKeysTotal: DWORD;
+    end;
+    RID_DEVICE_INFO_KEYBOARD = tagRID_DEVICE_INFO_KEYBOARD;
+    TRID_DEVICE_INFO_KEYBOARD = tagRID_DEVICE_INFO_KEYBOARD;
+    PRID_DEVICE_INFO_KEYBOARD = ^tagRID_DEVICE_INFO_KEYBOARD;
+
+    tagRID_DEVICE_INFO_HID = record
+      dwVendorId: DWORD;
+      dwProductId: DWORD;
+      dwVersionNumber: DWORD;
+
+      (*
+       * Top level collection UsagePage and Usage
+       *)
+      usUsagePage: USHORT;
+      usUsage: USHORT;
+    end;
+    RID_DEVICE_INFO_HID = tagRID_DEVICE_INFO_HID;
+    TRID_DEVICE_INFO_HID = tagRID_DEVICE_INFO_HID;
+    PRID_DEVICE_INFO_HID = ^tagRID_DEVICE_INFO_HID;
+
+    tagRID_DEVICE_INFO = record
+      cbSize: DWORD;
+      dwType: DWORD;
+      case longint of
+        0: (mouse: RID_DEVICE_INFO_MOUSE);
+        1: (keyboard: RID_DEVICE_INFO_KEYBOARD);
+        2: (hid: RID_DEVICE_INFO_HID);
+    end;
+    RID_DEVICE_INFO = tagRID_DEVICE_INFO;
+    PRID_DEVICE_INFO = ^tagRID_DEVICE_INFO;
+    LPRID_DEVICE_INFO = ^tagRID_DEVICE_INFO;
+
+(*
+ * Raw Input request APIs
+ *)
+    tagRAWINPUTDEVICE = record
+      usUsagePage: USHORT; // Toplevel collection UsagePage
+      usUsage: USHORT;     // Toplevel collection Usage
+      dwFlags: DWORD;
+      hwndTarget: HWND;    // Target hwnd. NULL = follows keyboard focus
+    end;
+    RAWINPUTDEVICE = tagRAWINPUTDEVICE;
+    TRAWINPUTDEVICE = tagRAWINPUTDEVICE;
+    PRAWINPUTDEVICE = ^tagRAWINPUTDEVICE;
+    LPRAWINPUTDEVICE = ^tagRAWINPUTDEVICE;
+    PCRAWINPUTDEVICE = ^tagRAWINPUTDEVICE;
+
+{$packrecords C}	
+    tagRAWINPUTDEVICELIST = record
+      hDevice: HANDLE;
+      dwType: DWORD;
+    end;
+    RAWINPUTDEVICELIST = tagRAWINPUTDEVICELIST;
+    PRAWINPUTDEVICELIST = ^tagRAWINPUTDEVICELIST;
+//#endif /* _WIN32_WINNT >= 0x0501 */
+{$pop}
 {$endif read_interface}
 
 

+ 1 - 0
rtl/win/wininc/unidef.inc

@@ -294,6 +294,7 @@ function WinHelp(hWndMain:HWND; lpszHelp:LPCWSTR; uCommand:UINT; dwData:DWORD):W
 function ChangeDisplaySettings(lpDevMode:LPDEVMODE; dwFlags:DWORD):LONG; external 'user32' name 'ChangeDisplaySettingsW';
 function EnumDisplaySettings(lpszDeviceName:LPCWSTR; iModeNum:DWORD; lpDevMode:LPDEVMODEW):WINBOOL; external 'user32' name 'EnumDisplaySettingsW';
 function SystemParametersInfo(uiAction:UINT; uiParam:UINT; pvParam:PVOID; fWinIni:UINT):WINBOOL; external 'user32' name 'SystemParametersInfoW';
+function GetRawInputDeviceInfo(hDevice: HANDLE; uiCommand: UINT; pData: LPVOID; pcbSize: PUINT): UINT; external 'user32' name 'GetRawInputDeviceInfoW';
 function AddFontResource(_para1:LPCWSTR):longint; external 'gdi32' name 'AddFontResourceW';
 function CopyMetaFile(_para1:HMETAFILE; _para2:LPCWSTR):HMETAFILE; external 'gdi32' name 'CopyMetaFileW';
 function CreateFontIndirect(_para1:PLOGFONT):HFONT; external 'gdi32' name 'CreateFontIndirectW';

+ 1 - 0
rtl/win/wininc/unifun.inc

@@ -293,6 +293,7 @@ function WinHelpW(hWndMain:HWND; lpszHelp:LPCWSTR; uCommand:UINT; dwData:DWORD):
 function ChangeDisplaySettingsW(lpDevMode:LPDEVMODEW; dwFlags:DWORD):LONG; external 'user32' name 'ChangeDisplaySettingsW';
 function EnumDisplaySettingsW(lpszDeviceName:LPCWSTR; iModeNum:DWORD;lpDevMode:LPDEVMODEW):WINBOOL; external 'user32' name 'EnumDisplaySettingsW';
 function SystemParametersInfoW(uiAction:UINT; uiParam:UINT; pvParam:PVOID; fWinIni:UINT):WINBOOL; external 'user32' name 'SystemParametersInfoW';
+function GetRawInputDeviceInfoW(hDevice: HANDLE; uiCommand: UINT; pData: LPVOID; pcbSize: PUINT): UINT; external 'user32' name 'GetRawInputDeviceInfoW';
 function AddFontResourceW(_para1:LPCWSTR):longint; external 'gdi32' name 'AddFontResourceW';
 function CopyMetaFileW(_para1:HMETAFILE; _para2:LPCWSTR):HMETAFILE; external 'gdi32' name 'CopyMetaFileW';
 function CreateFontIndirectW(_para1:PLOGFONTW):HFONT; external 'gdi32' name 'CreateFontIndirectW';

+ 2 - 2
tests/Makefile

@@ -1,5 +1,5 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-10-06 rev 31969]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2016-04-05 rev 33425]
 #
 default: allexectests
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-dragonfly arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android jvm-java jvm-android i8086-msdos
@@ -2106,7 +2106,7 @@ export LOG:=$(TEST_OUTPUTDIR)/log
 endif
 LOGFILES=$(TEST_OUTPUTDIR)/log $(TEST_OUTPUTDIR)/longlog $(TEST_OUTPUTDIR)/faillist
 LOGEXT=.testlog .tbslog .tbflog .webtbslog .webtbflog
-TESTSUBDIRS=cg cg/variants cg/cdecl cpu16 cpu16/i8086 library opt units/system units/dos units/crt units/objects units/strings units/sysutils units/math units/sharemem units/strutils units/matrix units/lineinfo units/ucomplex units/fpwidestring units/cpu
+TESTSUBDIRS=cg cg/variants cg/cdecl cpu16 cpu16/i8086 library opt units/system units/dos units/crt units/objects units/strings units/sysutils units/math units/sharemem units/strutils units/matrix units/lineinfo units/ucomplex units/fpwidestring units/cpu units/fmtbcd units/windows
 TESTPACKAGESUBDIRS=packages/win-base packages/webtbs packages/hash packages/fcl-registry packages/fcl-process packages/zlib packages/fcl-db packages/fcl-base packages/fcl-xml packages/cocoaint packages/bzip2
 ifdef QUICKTEST
 export QUICKTEST

+ 1 - 1
tests/Makefile.fpc

@@ -154,7 +154,7 @@ LOGFILES=$(TEST_OUTPUTDIR)/log $(TEST_OUTPUTDIR)/longlog $(TEST_OUTPUTDIR)/faill
 LOGEXT=.testlog .tbslog .tbflog .webtbslog .webtbflog
 
 # Subdirs available in the test subdir
-TESTSUBDIRS=cg cg/variants cg/cdecl cpu16 cpu16/i8086 library opt units/system units/dos units/crt units/objects units/strings units/sysutils units/math units/sharemem units/strutils units/matrix units/lineinfo units/ucomplex units/fpwidestring units/cpu
+TESTSUBDIRS=cg cg/variants cg/cdecl cpu16 cpu16/i8086 library opt units/system units/dos units/crt units/objects units/strings units/sysutils units/math units/sharemem units/strutils units/matrix units/lineinfo units/ucomplex units/fpwidestring units/cpu units/fmtbcd units/windows
 TESTPACKAGESUBDIRS=packages/win-base packages/webtbs packages/hash packages/fcl-registry packages/fcl-process packages/zlib packages/fcl-db packages/fcl-base packages/fcl-xml packages/cocoaint packages/bzip2
 
 ifdef QUICKTEST

+ 101 - 0
tests/test/units/windows/twinrawinput32.pp

@@ -0,0 +1,101 @@
+{ %TARGET=win32 }
+
+uses windows;
+
+var
+  errors_found: Boolean = false;
+
+procedure DoCheckSize(const StructName: string; ActualSize, ExpectedSize: SizeUInt);
+begin
+  if ActualSize <> ExpectedSize then
+  begin
+    Writeln('SizeOf(', StructName, ') is wrong - got ', ActualSize, ', expected ', ExpectedSize);
+    errors_found := true;
+  end;
+end;
+
+procedure DoCheckOffset(const StructAndFieldName: string; ActualOffset, ExpectedOffset: SizeUInt);
+begin
+  if ActualOffset <> ExpectedOffset then
+  begin
+    Writeln('Offset of ', StructAndFieldName, ' is wrong - got ', ActualOffset, ', expected ', ExpectedOffset);
+    errors_found := true;
+  end;
+end;
+
+
+
+
+begin
+  DoCheckSize('RAWINPUTHEADER', SizeOf( RAWINPUTHEADER ),   16 ) ;
+    DoCheckOffset('RAWINPUTHEADER'+'.'+'dwType', SizeUInt(@(PRAWINPUTHEADER (nil)^.  dwType )),   0 ) ;
+    DoCheckOffset('RAWINPUTHEADER'+'.'+'dwSize', SizeUInt(@(PRAWINPUTHEADER (nil)^.  dwSize )),   4 ) ;
+    DoCheckOffset('RAWINPUTHEADER'+'.'+'hDevice', SizeUInt(@(PRAWINPUTHEADER (nil)^.  hDevice )),   8 ) ;
+    DoCheckOffset('RAWINPUTHEADER'+'.'+'wParam', SizeUInt(@(PRAWINPUTHEADER (nil)^.  wParam )),   12 ) ;
+  DoCheckSize('RAWMOUSE', SizeOf( RAWMOUSE ),   24 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'usFlags', SizeUInt(@(PRAWMOUSE (nil)^.  usFlags )),   0 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'ulButtons', SizeUInt(@(PRAWMOUSE (nil)^.  ulButtons )),   4 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'ulRawButtons', SizeUInt(@(PRAWMOUSE (nil)^.  ulRawButtons )),   8 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'lLastX', SizeUInt(@(PRAWMOUSE (nil)^.  lLastX )),   12 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'lLastY', SizeUInt(@(PRAWMOUSE (nil)^.  lLastY )),   16 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'ulExtraInformation', SizeUInt(@(PRAWMOUSE (nil)^.  ulExtraInformation )),   20 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'usButtonFlags', SizeUInt(@(PRAWMOUSE (nil)^.  usButtonFlags )),   4 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'usButtonData', SizeUInt(@(PRAWMOUSE (nil)^.  usButtonData )),   6 ) ;
+  DoCheckSize('RAWKEYBOARD', SizeOf( RAWKEYBOARD ),   16 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'MakeCode', SizeUInt(@(PRAWKEYBOARD (nil)^.  MakeCode )),   0 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'Flags', SizeUInt(@(PRAWKEYBOARD (nil)^.  Flags )),   2 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'Reserved', SizeUInt(@(PRAWKEYBOARD (nil)^.  Reserved )),   4 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'VKey', SizeUInt(@(PRAWKEYBOARD (nil)^.  VKey )),   6 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'Message', SizeUInt(@(PRAWKEYBOARD (nil)^.  Message )),   8 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'ExtraInformation', SizeUInt(@(PRAWKEYBOARD (nil)^.  ExtraInformation )),   12 ) ;
+  DoCheckSize('RAWHID', SizeOf( RAWHID ),   12 ) ;
+    DoCheckOffset('RAWHID'+'.'+'dwSizeHid', SizeUInt(@(PRAWHID (nil)^.  dwSizeHid )),   0 ) ;
+    DoCheckOffset('RAWHID'+'.'+'dwCount', SizeUInt(@(PRAWHID (nil)^.  dwCount )),   4 ) ;
+    DoCheckOffset('RAWHID'+'.'+'bRawData', SizeUInt(@(PRAWHID (nil)^.  bRawData )),   8 ) ;
+  DoCheckSize('RAWINPUT', SizeOf( RAWINPUT ),   40 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'header', SizeUInt(@(PRAWINPUT (nil)^.  header )),   0 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'data', SizeUInt(@(PRAWINPUT (nil)^.  data )),   16 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'data.mouse', SizeUInt(@(PRAWINPUT (nil)^.  data.mouse )),   16 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'data.keyboard', SizeUInt(@(PRAWINPUT (nil)^.  data.keyboard )),   16 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'data.hid', SizeUInt(@(PRAWINPUT (nil)^.  data.hid )),   16 ) ;
+  DoCheckSize('RID_DEVICE_INFO_MOUSE', SizeOf( RID_DEVICE_INFO_MOUSE ),   16 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_MOUSE'+'.'+'dwId', SizeUInt(@(PRID_DEVICE_INFO_MOUSE (nil)^.  dwId )),   0 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_MOUSE'+'.'+'dwNumberOfButtons', SizeUInt(@(PRID_DEVICE_INFO_MOUSE (nil)^.  dwNumberOfButtons )),   4 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_MOUSE'+'.'+'dwSampleRate', SizeUInt(@(PRID_DEVICE_INFO_MOUSE (nil)^.  dwSampleRate )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_MOUSE'+'.'+'fHasHorizontalWheel', SizeUInt(@(PRID_DEVICE_INFO_MOUSE (nil)^.  fHasHorizontalWheel )),   12 ) ;
+  DoCheckSize('RID_DEVICE_INFO_KEYBOARD', SizeOf( RID_DEVICE_INFO_KEYBOARD ),   24 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwType', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwType )),   0 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwSubType', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwSubType )),   4 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwKeyboardMode', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwKeyboardMode )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwNumberOfFunctionKeys', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwNumberOfFunctionKeys )),   12 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwNumberOfIndicators', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwNumberOfIndicators )),   16 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwNumberOfKeysTotal', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwNumberOfKeysTotal )),   20 ) ;
+  DoCheckSize('RID_DEVICE_INFO_HID', SizeOf( RID_DEVICE_INFO_HID ),   16 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'dwVendorId', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  dwVendorId )),   0 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'dwProductId', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  dwProductId )),   4 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'dwVersionNumber', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  dwVersionNumber )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'usUsagePage', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  usUsagePage )),   12 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'usUsage', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  usUsage )),   14 ) ;
+  DoCheckSize('RID_DEVICE_INFO', SizeOf( RID_DEVICE_INFO ),   32 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'cbSize', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  cbSize )),   0 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'dwType', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  dwType )),   4 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'mouse', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  mouse )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'keyboard', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  keyboard )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'hid', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  hid )),   8 ) ;
+  DoCheckSize('RAWINPUTDEVICE', SizeOf( RAWINPUTDEVICE ),   12 ) ;
+    DoCheckOffset('RAWINPUTDEVICE'+'.'+'usUsagePage', SizeUInt(@(PRAWINPUTDEVICE (nil)^.  usUsagePage )),   0 ) ;
+    DoCheckOffset('RAWINPUTDEVICE'+'.'+'usUsage', SizeUInt(@(PRAWINPUTDEVICE (nil)^.  usUsage )),   2 ) ;
+    DoCheckOffset('RAWINPUTDEVICE'+'.'+'dwFlags', SizeUInt(@(PRAWINPUTDEVICE (nil)^.  dwFlags )),   4 ) ;
+    DoCheckOffset('RAWINPUTDEVICE'+'.'+'hwndTarget', SizeUInt(@(PRAWINPUTDEVICE (nil)^.  hwndTarget )),   8 ) ;
+  DoCheckSize('RAWINPUTDEVICELIST', SizeOf( RAWINPUTDEVICELIST ),   8 ) ;
+    DoCheckOffset('RAWINPUTDEVICELIST'+'.'+'hDevice', SizeUInt(@(PRAWINPUTDEVICELIST (nil)^.  hDevice )),   0 ) ;
+    DoCheckOffset('RAWINPUTDEVICELIST'+'.'+'dwType', SizeUInt(@(PRAWINPUTDEVICELIST (nil)^.  dwType )),   4 ) ;
+  if errors_found then
+  begin
+    Writeln('Errors found!');
+    Halt(1);
+  end
+  else
+    Writeln('Ok!');
+
+end.

+ 101 - 0
tests/test/units/windows/twinrawinput64.pp

@@ -0,0 +1,101 @@
+{ %TARGET=win64 }
+
+uses windows;
+
+var
+  errors_found: Boolean = false;
+
+procedure DoCheckSize(const StructName: string; ActualSize, ExpectedSize: SizeUInt);
+begin
+  if ActualSize <> ExpectedSize then
+  begin
+    Writeln('SizeOf(', StructName, ') is wrong - got ', ActualSize, ', expected ', ExpectedSize);
+    errors_found := true;
+  end;
+end;
+
+procedure DoCheckOffset(const StructAndFieldName: string; ActualOffset, ExpectedOffset: SizeUInt);
+begin
+  if ActualOffset <> ExpectedOffset then
+  begin
+    Writeln('Offset of ', StructAndFieldName, ' is wrong - got ', ActualOffset, ', expected ', ExpectedOffset);
+    errors_found := true;
+  end;
+end;
+
+
+
+
+begin
+  DoCheckSize('RAWINPUTHEADER', SizeOf( RAWINPUTHEADER ),   24 ) ;
+    DoCheckOffset('RAWINPUTHEADER'+'.'+'dwType', SizeUInt(@(PRAWINPUTHEADER (nil)^.  dwType )),   0 ) ;
+    DoCheckOffset('RAWINPUTHEADER'+'.'+'dwSize', SizeUInt(@(PRAWINPUTHEADER (nil)^.  dwSize )),   4 ) ;
+    DoCheckOffset('RAWINPUTHEADER'+'.'+'hDevice', SizeUInt(@(PRAWINPUTHEADER (nil)^.  hDevice )),   8 ) ;
+    DoCheckOffset('RAWINPUTHEADER'+'.'+'wParam', SizeUInt(@(PRAWINPUTHEADER (nil)^.  wParam )),   16 ) ;
+  DoCheckSize('RAWMOUSE', SizeOf( RAWMOUSE ),   24 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'usFlags', SizeUInt(@(PRAWMOUSE (nil)^.  usFlags )),   0 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'ulButtons', SizeUInt(@(PRAWMOUSE (nil)^.  ulButtons )),   4 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'ulRawButtons', SizeUInt(@(PRAWMOUSE (nil)^.  ulRawButtons )),   8 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'lLastX', SizeUInt(@(PRAWMOUSE (nil)^.  lLastX )),   12 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'lLastY', SizeUInt(@(PRAWMOUSE (nil)^.  lLastY )),   16 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'ulExtraInformation', SizeUInt(@(PRAWMOUSE (nil)^.  ulExtraInformation )),   20 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'usButtonFlags', SizeUInt(@(PRAWMOUSE (nil)^.  usButtonFlags )),   4 ) ;
+    DoCheckOffset('RAWMOUSE'+'.'+'usButtonData', SizeUInt(@(PRAWMOUSE (nil)^.  usButtonData )),   6 ) ;
+  DoCheckSize('RAWKEYBOARD', SizeOf( RAWKEYBOARD ),   16 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'MakeCode', SizeUInt(@(PRAWKEYBOARD (nil)^.  MakeCode )),   0 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'Flags', SizeUInt(@(PRAWKEYBOARD (nil)^.  Flags )),   2 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'Reserved', SizeUInt(@(PRAWKEYBOARD (nil)^.  Reserved )),   4 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'VKey', SizeUInt(@(PRAWKEYBOARD (nil)^.  VKey )),   6 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'Message', SizeUInt(@(PRAWKEYBOARD (nil)^.  Message )),   8 ) ;
+    DoCheckOffset('RAWKEYBOARD'+'.'+'ExtraInformation', SizeUInt(@(PRAWKEYBOARD (nil)^.  ExtraInformation )),   12 ) ;
+  DoCheckSize('RAWHID', SizeOf( RAWHID ),   12 ) ;
+    DoCheckOffset('RAWHID'+'.'+'dwSizeHid', SizeUInt(@(PRAWHID (nil)^.  dwSizeHid )),   0 ) ;
+    DoCheckOffset('RAWHID'+'.'+'dwCount', SizeUInt(@(PRAWHID (nil)^.  dwCount )),   4 ) ;
+    DoCheckOffset('RAWHID'+'.'+'bRawData', SizeUInt(@(PRAWHID (nil)^.  bRawData )),   8 ) ;
+  DoCheckSize('RAWINPUT', SizeOf( RAWINPUT ),   48 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'header', SizeUInt(@(PRAWINPUT (nil)^.  header )),   0 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'data', SizeUInt(@(PRAWINPUT (nil)^.  data )),   24 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'data.mouse', SizeUInt(@(PRAWINPUT (nil)^.  data.mouse )),   24 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'data.keyboard', SizeUInt(@(PRAWINPUT (nil)^.  data.keyboard )),   24 ) ;
+    DoCheckOffset('RAWINPUT'+'.'+'data.hid', SizeUInt(@(PRAWINPUT (nil)^.  data.hid )),   24 ) ;
+  DoCheckSize('RID_DEVICE_INFO_MOUSE', SizeOf( RID_DEVICE_INFO_MOUSE ),   16 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_MOUSE'+'.'+'dwId', SizeUInt(@(PRID_DEVICE_INFO_MOUSE (nil)^.  dwId )),   0 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_MOUSE'+'.'+'dwNumberOfButtons', SizeUInt(@(PRID_DEVICE_INFO_MOUSE (nil)^.  dwNumberOfButtons )),   4 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_MOUSE'+'.'+'dwSampleRate', SizeUInt(@(PRID_DEVICE_INFO_MOUSE (nil)^.  dwSampleRate )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_MOUSE'+'.'+'fHasHorizontalWheel', SizeUInt(@(PRID_DEVICE_INFO_MOUSE (nil)^.  fHasHorizontalWheel )),   12 ) ;
+  DoCheckSize('RID_DEVICE_INFO_KEYBOARD', SizeOf( RID_DEVICE_INFO_KEYBOARD ),   24 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwType', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwType )),   0 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwSubType', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwSubType )),   4 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwKeyboardMode', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwKeyboardMode )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwNumberOfFunctionKeys', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwNumberOfFunctionKeys )),   12 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwNumberOfIndicators', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwNumberOfIndicators )),   16 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_KEYBOARD'+'.'+'dwNumberOfKeysTotal', SizeUInt(@(PRID_DEVICE_INFO_KEYBOARD (nil)^.  dwNumberOfKeysTotal )),   20 ) ;
+  DoCheckSize('RID_DEVICE_INFO_HID', SizeOf( RID_DEVICE_INFO_HID ),   16 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'dwVendorId', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  dwVendorId )),   0 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'dwProductId', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  dwProductId )),   4 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'dwVersionNumber', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  dwVersionNumber )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'usUsagePage', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  usUsagePage )),   12 ) ;
+    DoCheckOffset('RID_DEVICE_INFO_HID'+'.'+'usUsage', SizeUInt(@(PRID_DEVICE_INFO_HID (nil)^.  usUsage )),   14 ) ;
+  DoCheckSize('RID_DEVICE_INFO', SizeOf( RID_DEVICE_INFO ),   32 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'cbSize', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  cbSize )),   0 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'dwType', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  dwType )),   4 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'mouse', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  mouse )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'keyboard', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  keyboard )),   8 ) ;
+    DoCheckOffset('RID_DEVICE_INFO'+'.'+'hid', SizeUInt(@(PRID_DEVICE_INFO (nil)^.  hid )),   8 ) ;
+  DoCheckSize('RAWINPUTDEVICE', SizeOf( RAWINPUTDEVICE ),   16 ) ;
+    DoCheckOffset('RAWINPUTDEVICE'+'.'+'usUsagePage', SizeUInt(@(PRAWINPUTDEVICE (nil)^.  usUsagePage )),   0 ) ;
+    DoCheckOffset('RAWINPUTDEVICE'+'.'+'usUsage', SizeUInt(@(PRAWINPUTDEVICE (nil)^.  usUsage )),   2 ) ;
+    DoCheckOffset('RAWINPUTDEVICE'+'.'+'dwFlags', SizeUInt(@(PRAWINPUTDEVICE (nil)^.  dwFlags )),   4 ) ;
+    DoCheckOffset('RAWINPUTDEVICE'+'.'+'hwndTarget', SizeUInt(@(PRAWINPUTDEVICE (nil)^.  hwndTarget )),   8 ) ;
+  DoCheckSize('RAWINPUTDEVICELIST', SizeOf( RAWINPUTDEVICELIST ),   16 ) ;
+    DoCheckOffset('RAWINPUTDEVICELIST'+'.'+'hDevice', SizeUInt(@(PRAWINPUTDEVICELIST (nil)^.  hDevice )),   0 ) ;
+    DoCheckOffset('RAWINPUTDEVICELIST'+'.'+'dwType', SizeUInt(@(PRAWINPUTDEVICELIST (nil)^.  dwType )),   8 ) ;
+  if errors_found then
+  begin
+    Writeln('Errors found!');
+    Halt(1);
+  end
+  else
+    Writeln('Ok!');
+
+end.