├── .gitignore ├── README.md ├── WinStructs.ahk ├── check sizes.ahk ├── decode.ahk └── example.ahk /.gitignore: -------------------------------------------------------------------------------- 1 | *.ini 2 | *.exe 3 | *.zip 4 | *.lnk 5 | *.scc 6 | *.png 7 | *.bak 8 | *.tmp.* 9 | *.obj 10 | *.cpp 11 | *.bat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WinStructs 2 | A collection of definitions for Windows structures for decoding DLL call and OnMessage results etc. For use with HotkeyIt's [_Struct library](https://github.com/HotKeyIt/_Struct). 3 | 4 | ## What? 5 | WinStructs is just a collection of text strings, there is no logic. 6 | It would be semantically similar to a "Header file" in C, as it provides information about the makeup of data structures. 7 | If working in AutoHotkey with DllCall or OnMessage, you are likely to get a Structure back, which you must interpret via bitwise operations. _Struct frees you from this by allowing you to interpret the data like an object, but you need a correctly crafted definition for the Structure - this is what WinSctructs seeks to provide. 8 | 9 | ## Why? 10 | Because it is a job that only ever needs to be done once for each structure. There is only one "correct" way to do it, so the only thing that would vary between implementations is naming convention. 11 | Therefore, in an ideal world, the first person to use a Structure decodes it properly and submits to this repostiory, and nobody else ever needs to bother do it again. 12 | 13 | ## How?... 14 | ... Do I decode a structure? 15 | The rules are fairly simple, but I am not hugely up on it yet. A part of this project is also to try and build a simple tutorial on how to convert the definition from an MSDN page into a valid definition. 16 | 17 | ## Who? 18 | Anyone is welcome to contribute - the AHKScript group is a non-exclusive group and all group members can make commits to the project. 19 | Make a post [here](http://ahkscript.org/boards/viewtopic.php?t=936) to request access. 20 | -------------------------------------------------------------------------------- /WinStructs.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | WinStructs - A class to hold Window Structure Definitions 3 | 4 | STYLE GUIDE 5 | =========== 6 | ALWAYS Put a link to the MSDN page for the STRUCT 7 | ALWAYS Use the same name as the Struct. 8 | ALWAYS Use the EXACT same name for properties. If it has a lower-case prefix, keep it. 9 | The reasons for this are two-fold. 10 | 1) The immediately obvious thing to do is to strip the lower case prefixes, however in some cases this would not be possible. 11 | eg: KBDLLHOOKSTRUCT has vkCode and scanCode - you could not have two properties called "Code". 12 | 2) Consistency. Seeing as we cannot achieve consistency by stripping lower case prefixes, the next best solution is to keep them exactly as on MSDN. 13 | Some properties on MSDN have prefixes, some do not. MSDN may not be consistent, be WinStructs is (With MSDN). 14 | 15 | 16 | ToDo 17 | ==== 18 | * Some way of bundling defines with struct definition? 19 | 20 | */ 21 | 22 | Class WinStructs { 23 | ; Define locations - used to check validity of Structures by looking up the actual size from the specified windows header file. 24 | ; Set to 1 for default header file of "Windows.h" 25 | ; Set to -1 to not check (un-named sub-structs etc) 26 | static Defines := { KBDLLHOOKSTRUCT: 1 27 | , POINT: 1 28 | , MSLLHOOKSTRUCT: 1 29 | , RAWINPUTDEVICELIST: 1 30 | , RID_DEVICE_INFO_MOUSE: 1 31 | , RID_DEVICE_INFO_KEYBOARD: 1 32 | , RID_DEVICE_INFO_HID: 1 33 | , RID_DEVICE_INFO: 1 34 | , HIDP_CAPS: ["Hidusage.h", "Hidpi.h"] 35 | , RAWINPUTDEVICE: 1 36 | , HIDP_BUTTON_CAPS_Range: -1 37 | , HIDP_BUTTON_CAPS_NotRange: -1 38 | , HIDP_BUTTON_CAPS: ["Hidusage.h", "Hidpi.h"] 39 | , HIDP_VALUE_CAPS_Range: -1 40 | , HIDP_VALUE_CAPS_NotRange: -1 41 | , HIDP_VALUE_CAPS: ["Hidusage.h", "Hidpi.h"] 42 | , RAWMOUSE: 1 43 | , RAWKEYBOARD: 1 44 | , RAWHID: 1 45 | , RAWINPUTHEADER: 1 46 | , RAWINPUT: 1 47 | , STARTUPINFO: 1 } 48 | 49 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645568%28v=vs.85%29.aspx 50 | static RAWINPUTDEVICELIST := " 51 | ( 52 | HANDLE hDevice; // A handle to the raw input device. 53 | DWORD dwType; // The type of device. This can be one of the following values 54 | // RIM_TYPEHID 2 - The device is an HID that is not a keyboard and not a mouse 55 | // RIM_TYPEKEYBOARD 1 - The device is a keyboard. 56 | // RIM_TYPEMOUSE 0 - The device is a mouse. 57 | )" 58 | 59 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645589(v=vs.85).aspx 60 | static RID_DEVICE_INFO_MOUSE := " 61 | ( 62 | DWORD dwId; 63 | DWORD dwNumberOfButtons; 64 | DWORD dwSampleRate; 65 | BOOL fHasHorizontalWheel; 66 | )" 67 | 68 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645587(v=vs.85).aspx 69 | static RID_DEVICE_INFO_KEYBOARD := " 70 | ( 71 | DWORD dwType; 72 | DWORD dwSubType; 73 | DWORD dwKeyboardMode; 74 | DWORD dwNumberOfFunctionKeys; 75 | DWORD dwNumberOfIndicators; 76 | DWORD dwNumberOfKeysTotal; 77 | )" 78 | 79 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645584%28v=vs.85%29.aspx 80 | static RID_DEVICE_INFO_HID := " 81 | ( 82 | DWORD dwVendorId; 83 | DWORD dwProductId; 84 | DWORD dwVersionNumber; 85 | USHORT usUsagePage; 86 | USHORT usUsage; 87 | )" 88 | 89 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645581%28v=vs.85%29.aspx 90 | static RID_DEVICE_INFO := " 91 | ( 92 | DWORD cbSize; 93 | DWORD dwType; 94 | { 95 | WinStructs.RID_DEVICE_INFO_MOUSE mouse; 96 | WinStructs.RID_DEVICE_INFO_KEYBOARD keyboard; 97 | WinStructs.RID_DEVICE_INFO_HID hid; 98 | } 99 | )" 100 | 101 | ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff539697(v=vs.85).aspx 102 | static HIDP_CAPS := " 103 | ( 104 | USHORT Usage; 105 | USHORT UsagePage; 106 | USHORT InputReportByteLength; 107 | USHORT OutputReportByteLength; 108 | USHORT FeatureReportByteLength; 109 | USHORT Reserved[17]; 110 | USHORT NumberLinkCollectionNodes; 111 | USHORT NumberInputButtonCaps; 112 | USHORT NumberInputValueCaps; 113 | USHORT NumberInputDataIndices; 114 | USHORT NumberOutputButtonCaps; 115 | USHORT NumberOutputValueCaps; 116 | USHORT NumberOutputDataIndices; 117 | USHORT NumberFeatureButtonCaps; 118 | USHORT NumberFeatureValueCaps; 119 | USHORT NumberFeatureDataIndices; 120 | )" 121 | 122 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645565(v=vs.85).aspx 123 | static RAWINPUTDEVICE := " 124 | ( 125 | USHORT usUsagePage; 126 | USHORT usUsage; 127 | DWORD dwFlags; 128 | HWND hwndTarget; 129 | )" 130 | 131 | ; https://msdn.microsoft.com/en-gb/library/windows/hardware/ff539693(v=vs.85).aspx 132 | static HIDP_BUTTON_CAPS_Range := " 133 | ( 134 | USHORT UsageMin; 135 | USHORT UsageMax; 136 | USHORT StringMin; 137 | USHORT StringMax; 138 | USHORT DesignatorMin; 139 | USHORT DesignatorMax; 140 | USHORT DataIndexMin; 141 | USHORT DataIndexMax; 142 | )" 143 | 144 | static HIDP_BUTTON_CAPS_NotRange := " 145 | ( 146 | USHORT Usage; 147 | USHORT Reserved1; 148 | USHORT StringIndex; 149 | USHORT Reserved2; 150 | USHORT DesignatorIndex; 151 | USHORT Reserved3; 152 | USHORT DataIndex; 153 | USHORT Reserved4; 154 | )" 155 | 156 | static HIDP_BUTTON_CAPS := " 157 | ( 158 | USHORT UsagePage; 159 | UCHAR ReportID; 160 | BOOLEAN IsAlias; 161 | USHORT BitField; 162 | USHORT LinkCollection; 163 | USHORT LinkUsage; 164 | USHORT LinkUsagePage; 165 | BOOLEAN IsRange; 166 | BOOLEAN IsStringRange; 167 | BOOLEAN IsDesignatorRange; 168 | BOOLEAN IsAbsolute; 169 | ULONG Reserved[10]; 170 | { 171 | WinStructs.HIDP_BUTTON_CAPS_Range Range; 172 | WinStructs.HIDP_BUTTON_CAPS_NotRange NotRange; 173 | }; 174 | )" 175 | 176 | ; https://msdn.microsoft.com/en-us/library/windows/hardware/ff539832(v=vs.85).aspx 177 | static HIDP_VALUE_CAPS_Range := " 178 | ( 179 | USAGE UsageMin; 180 | USAGE UsageMax; 181 | USHORT StringMin; 182 | USHORT StringMax; 183 | USHORT DesignatorMin; 184 | USHORT DesignatorMax; 185 | USHORT DataIndexMin; 186 | USHORT DataIndexMax; 187 | )" 188 | 189 | static HIDP_VALUE_CAPS_NotRange := " 190 | ( 191 | USAGE Usage; 192 | USAGE Reserved1; 193 | USHORT StringIndex; 194 | USHORT Reserved2; 195 | USHORT DesignatorIndex; 196 | USHORT Reserved3; 197 | USHORT DataIndex; 198 | USHORT Reserved4; 199 | )" 200 | 201 | static HIDP_VALUE_CAPS := " 202 | ( 203 | USAGE UsagePage; 204 | UCHAR ReportID; 205 | BOOLEAN IsAlias; 206 | USHORT BitField; 207 | USHORT LinkCollection; 208 | USAGE LinkUsage; 209 | USAGE LinkUsagePage; 210 | BOOLEAN IsRange; 211 | BOOLEAN IsStringRange; 212 | BOOLEAN IsDesignatorRange; 213 | BOOLEAN IsAbsolute; 214 | BOOLEAN HasNull; 215 | UCHAR Reserved; 216 | USHORT BitSize; 217 | USHORT ReportCount; 218 | USHORT Reserved2[5]; 219 | ULONG UnitsExp; 220 | ULONG Units; 221 | LONG LogicalMin; 222 | LONG LogicalMax; 223 | LONG PhysicalMin; 224 | LONG PhysicalMax; 225 | { 226 | WinStructs.HIDP_VALUE_CAPS_Range Range; 227 | WinStructs.HIDP_VALUE_CAPS_NotRange NotRange; 228 | }; 229 | )" 230 | 231 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645578(v=vs.85).aspx 232 | static RAWMOUSE := " 233 | ( 234 | USHORT usFlags; 235 | { 236 | ULONG ulButtons; 237 | { 238 | USHORT usButtonFlags; 239 | USHORT usButtonData; 240 | }; 241 | }; 242 | ULONG ulRawButtons; 243 | LONG lLastX; 244 | LONG lLastY; 245 | ULONG ulExtraInformation; 246 | )" 247 | 248 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645575(v=vs.85).aspx 249 | static RAWKEYBOARD := " 250 | ( 251 | USHORT MakeCode; 252 | USHORT Flags; 253 | USHORT Reserved; 254 | USHORT VKey; 255 | UINT Message; 256 | ULONG ExtraInformation; 257 | )" 258 | 259 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645549(v=vs.85).aspx 260 | static RAWHID := " 261 | ( 262 | DWORD dwSizeHid; 263 | DWORD dwCount; 264 | BYTE bRawData[1]; 265 | )" 266 | 267 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645571(v=vs.85).aspx 268 | static RAWINPUTHEADER := " 269 | ( 270 | DWORD dwType; 271 | DWORD dwSize; 272 | HANDLE hDevice; 273 | WPARAM wParam; 274 | )" 275 | 276 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms645562(v=vs.85).aspx 277 | static RAWINPUT := " 278 | ( 279 | WinStructs.RAWINPUTHEADER header; 280 | { 281 | WinStructs.RAWMOUSE mouse; 282 | WinStructs.RAWKEYBOARD keyboard; 283 | WinStructs.RAWHID hid; 284 | } 285 | BYTE buffer[49]; // buffer as the structure might differe for devices. ToDo: check on x64 286 | )" 287 | 288 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms644967(v=vs.85).aspx 289 | static KBDLLHOOKSTRUCT := " 290 | ( 291 | DWORD vkCode; 292 | DWORD scanCode; 293 | DWORD flags; 294 | DWORD time; 295 | ULONG_PTR dwExtraInfo; 296 | )" 297 | 298 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms644970(v=vs.85).aspx 299 | static MSLLHOOKSTRUCT := " 300 | ( 301 | WinStructs.POINT pt; 302 | { 303 | DWORD mouseData; 304 | struct { 305 | WORD mouseData_low; 306 | WORD mouseData_high; 307 | }; 308 | }; 309 | DWORD flags; 310 | DWORD time; 311 | ULONG_PTR dwExtraInfo; 312 | )" 313 | 314 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspx 315 | static POINT := " 316 | ( 317 | LONG x; 318 | LONG y; 319 | )" 320 | 321 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx 322 | static RECT := " 323 | ( 324 | LONG left; 325 | LONG top; 326 | LONG right; 327 | LONG bottom; 328 | )" 329 | 330 | ; https://msdn.microsoft.com/en-us/library/windows/desktop/bb787537(v=vs.85).aspx 331 | static SCROLLINFO := " 332 | ( 333 | UINT cbSize; 334 | UINT fMask; 335 | int nMin; 336 | int nMax; 337 | UINT nPage; 338 | int nPos; 339 | int nTrackPos; 340 | )" 341 | 342 | ; https://msdn.microsoft.com/en-us/library/ms686331(v=vs.85).aspx 343 | static STARTUPINFO := " 344 | ( 345 | DWORD cb; 346 | LPSTR lpReserved; 347 | LPTSTR lpDesktop; 348 | LPTSTR lpTitle; 349 | DWORD dwX; 350 | DWORD dwY; 351 | DWORD dwXSize; 352 | DWORD dwYSize; 353 | DWORD dwXCountChars; 354 | DWORD dwYCountChars; 355 | DWORD dwFillAttribute; 356 | DWORD dwFlags; 357 | WORD wShowWindow; 358 | WORD cbReserved2; 359 | LPBYTE lpReserved2; 360 | HANDLE hStdInput; 361 | HANDLE hStdOutput; 362 | HANDLE hStdError; 363 | )" 364 | } 365 | -------------------------------------------------------------------------------- /check sizes.ahk: -------------------------------------------------------------------------------- 1 | #SingleInstance force 2 | 3 | #include winstructs.ahk 4 | #include <_Struct> 5 | #Include 6 | 7 | Gui, Add, ListView, w600 h400, Item|Extra Includes|Win|_Struct|OK? 8 | Gui, Show 9 | 10 | LV_ModifyCol(1, 250) 11 | LV_ModifyCol(2, 200) 12 | LV_ModifyCol(3, 50) 13 | LV_ModifyCol(4, 50) 14 | 15 | sc := new SizeofChecker() 16 | 17 | count := 0 18 | good := 0 19 | 20 | For key, value in WinStructs.Defines { 21 | count++ 22 | if (value = -1){ 23 | good++ 24 | continue 25 | } 26 | if (value = 1){ 27 | ;value := ["Windows.h"] 28 | ;value := [] 29 | value := "" 30 | } 31 | s := new _Struct("WinStructs."key) 32 | s := sizeof(s) 33 | c := sc.Check(key, value) 34 | ;c += 0 35 | if (s = c){ 36 | good++ 37 | okstr := "YES" 38 | } else { 39 | okstr := "NO" 40 | } 41 | 42 | i := "" 43 | Loop % value.MaxIndex(){ 44 | if (A_Index > 1){ 45 | i .= "," 46 | } 47 | i .= value[A_Index] 48 | } 49 | LV_ADD(,key, i, c, s, okstr) 50 | } 51 | msg := good " of " count " items matched OK" 52 | msgbox % msg 53 | 54 | Esc:: 55 | GuiClose: 56 | ExitApp -------------------------------------------------------------------------------- /decode.ahk: -------------------------------------------------------------------------------- 1 | ; A simple script to see how Struct interprets various WinStructs structures 2 | #SingleInstance force 3 | 4 | #Include <_Struct> 5 | #Include 6 | 7 | sl := "" 8 | Count := 0 9 | for key, value in WinStructs { 10 | if (key = "__class" || key = "defines"){ 11 | continue 12 | } 13 | if (Count){ 14 | sl .= "|" 15 | } 16 | sl .= key 17 | Count++ 18 | } 19 | 20 | Gui, Add, Text, Center w400 , % "RUNNING AS: " (A_PtrSize = 4? "32" : "64") "-Bit ( PtrSize: " A_PtrSize ")" 21 | Gui, Add, Text, Section, Structure Name: 22 | Gui, Add, DDL, w250 ys vStructName gDecode, %sl% 23 | ;Gui, Add, Edit, ys w250 vStructName Section 24 | Gui, Add, Button, ys gDecode, Decode 25 | Gui, Add, Edit, xm w400 h400 vOutput 26 | Gui, Show 27 | 28 | return 29 | 30 | Decode: 31 | Gui, Submit, NoHide 32 | out := GetOffsets(StructName) 33 | GuiControl, , Output, % out 34 | return 35 | 36 | ;Esc:: 37 | GuiClose: 38 | ExitApp 39 | 40 | GetOffsets(name){ 41 | if (!ObjHasKey(WinStructs, name)){ 42 | return "Not Found" 43 | } 44 | struct := new _Struct("WinStructs." name) 45 | arr := [] 46 | obj := struct.ToObj() 47 | 48 | for key, value in obj { 49 | arr[struct.Offset(key)] := key 50 | } 51 | 52 | for key, value in arr { 53 | s .= value ": NumGet(data, b + " key ",""" struct.AhkType(value) """)`n" 54 | } 55 | s .= "`n`nSize: " sizeof(struct) 56 | ;Clipboard := s 57 | ;msgbox % s 58 | return s 59 | } 60 | -------------------------------------------------------------------------------- /example.ahk: -------------------------------------------------------------------------------- 1 | ; Example script 2 | ; Use a GetWindowRect Dll Call to get a RECT structure containing information on the Size of the window 3 | ; Use a GetCursorPos Dll Call to get a POINT structure containing mouse position 4 | ; Pass bits of each to a MoveWindow Dll Call 5 | 6 | #NoEnv 7 | #SingleInstance force 8 | 9 | #include <_Struct> 10 | #include 11 | 12 | Gui,+LastFound 13 | Gui,Show,w100 h100 ;show window 14 | hwnd:=WinExist() ;get window handle 15 | 16 | /* 17 | GetWindowRect 18 | Docs: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633519%28v=vs.85%29.aspx 19 | Returns a RECT: https://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx 20 | A RECT is defined thus in WinStructs: 21 | static RECT := " 22 | ( 23 | LONG left; 24 | LONG top; 25 | LONG right; 26 | LONG bottom; 27 | )" 28 | */ 29 | 30 | RECT:=new _Struct(WinStructs.RECT) ;create structure 31 | DllCall("GetWindowRect","Uint",hwnd,"Uint",RECT[]) ;get window position 32 | RECT.right := RECT.right - RECT.left ;Set RECT.right to be the width 33 | RECT.bottom := RECT.bottom - RECT.top ;Set RECT.bottom to be the height 34 | 35 | /* 36 | GetCursorPos 37 | Docs: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648390%28v=vs.85%29.aspx 38 | Returns a POINT: https://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspx 39 | A POINT is defined thus in WinStructs: 40 | static POINT := " 41 | ( 42 | LONG x; 43 | LONG y; 44 | )" 45 | */ 46 | 47 | /* 48 | MoveWindow 49 | Docs: https://msdn.microsoft.com/en-gb/library/windows/desktop/ms633534(v=vs.85).aspx 50 | */ 51 | POINT := new _Struct(WinStructs.POINT) 52 | While DllCall("GetCursorPos","Uint",POINT[]) && DllCall("MoveWindow","Uint",hwnd,"int",POINT.x,"int",POINT.y,"int",RECT.right,"int",RECT.bottom,"Int",1){ 53 | Sleep, 10 54 | } 55 | 56 | return 57 | 58 | Esc:: 59 | GuiClose: 60 | Gui,Destroy 61 | RECT:="" 62 | ExitApp --------------------------------------------------------------------------------