AhkWin32Projection
Win32 API bindings for 64-bit AutoHotkey V2
Install / Use
/learn @holy-tao/AhkWin32ProjectionREADME
AhkWin32Projection
Win32 bindings for AutoHotkey V2.
This project allows you to replace this:
rect := Buffer(16, 0)
NumPut("int", 20, rect, 12)
With much more friendly, object-oriented syntax:
myRect := Rect()
myRect.top := 20
Replace DllCalls with far more readable function calls...
hDC := DllCall("GetDC", "ptr", 0)
hDC := Gdi.GetDC(0) ;Readable!
With rich IntelliSense features and full documentation directly in your IDE:

Table of Contents
- Table of Contents
- What Is This?
- Usage
- Structs
- COM Interfaces
- Enums and Constants
- Methods
- Limitations
- Links
What Is This?
This project provides bindings Win32 APIs in 64-bit AutoHotkey V2. It aims greatly simplify the process of working with structs, non-IDispatch COM interfaces, and DllCalls and to alleviate the plague of magic numbers that afflicts AutoHotkey programmers.
The project provides generated struct proxy objects, COM interface proxy objects, constant values, and friendly DllCall wrappers with doc comments rich Intellisense documentation compatible with AHK++.
Imagine you wanted to enumerate all the fonts on your system:
stdout := FileOpen("*", "w")
hDc := Gdi.GetDC(0) ;Equivalent to DllCall("GetDC", "ptr", 0)
searchFont := LOGFONTW()
searchFont.lfCharSet := FONT_CHARSET.ANSI_CHARSET
searchFont.lfFaceName := "Papyrus"
callback := CallbackCreate(EnumFontFamExProc, "Fast", 4)
Gdi.EnumFontFamiliesExW(hDc, searchFont, callback, 0, 0)
;https://learn.microsoft.com/en-us/previous-versions/dd162618(v=vs.85)
EnumFontFamExProc(lpelfe, lpntme, fontType, lparam){
logfont := LOGFONTW(lpelfe)
stdout.WriteLine(logfont.lfFaceName)
return 1 ;Return non-zero value to continue enumeration
}
~~No more~~ fewer magic numbers, much more readable code, no mucking around deprecated Win32 documentation!
Usage
This project is intended to be used as a library. You can "install" it by cloning the repo into an AutoHotkey library directory, and then reference types in your script using <library> syntax. I'll also cut releases after major changes (including metadata updates from Microsoft) that will remain stable, you can grab the latest one and update manually in releases. If you prefer stability over easy updates, go that route.
Files are organized by namespace:
#Include <AhkWin32Projection\Windows\Win32\Foundation\RECT>
#Include <AhkWin32Projection\Windows\Win32\UI\Controls\HDITEMW>
Don't Want 31,000 Files?
You can use Fetch-AhkWin32.ps1 to download only the types you need and their dependencies. This allows you to follow a pattern like CsWin32's NativeMethods.txt-based source generation. Specfy types either at the command line or in a text file, and only those types and the files they #Include will be downloaded. For versioning, you can anchor the script to a tag or a branch.
.\Fetch-AhkWin32.ps1 -Types "Windows.Win32.Networking.WinHttp.IWinHttpRequest","Windows.Win32.Networking.WinHttp.IWinHttpRequestEvents" -OutDir "./Lib"
The script will generate a .ahk stub that #Includes the types you told it to download, so in your code, all you need to do in your code is include it:
#Include ./Lib/Win32.includes.ahk
See the wiki for more usage details.
Common Namespaces
Namespaces can be unintuitive and they aren't really mapped to headers, so a few common namespaces are listed here. GitHub's file search functionality is also great if you're looking for something specific. Namespaces come directly from the metadata, so they won't be changed unless Microsoft changes them.
<details> <summary>Commonly used Namespaces</summary>Windows\Win32\UI\Controls: Most Gui and GuiControl related typesWindows\Win32\UI\WindowsAndMessaging: Contains more fundamental window-related structs and enums (e.g. theWINDOW_EX_STYLEenum)Windows\Win32\Foundation: Contains types common to all namespaces likeRECT,FILETIME, andPOINT.Windows\Win32\Graphics\GdiandGdiPlus: Contains most graphics-related types not otherwise contained inUI\Controls- font structs likeLOGFONTW, for example.Windows\Win32\System\LibraryLoader: Functions for loading and working with DLL and EXE files, including accessing resources in them.- Note that for whatever reason,
FreeLibraryis in the Foundations namespace
- Note that for whatever reason,
Windows\Win32\Networking\WinHttp: WinHTTP-related items (see also: About WinHTTP - Win32 apps | Microsoft Learn).Windows\Win32\System\Memory: Contains Apis for direct memory manipulation, including the direct allocation and freeing of heap resources, for advanced users.Windows\Win32\System\Com: Foundational COM interfaces and APIs, includingIUnknownitself and methods likeCoCreateInstance
Structs
All structs are represented with proxy objects extending Win32Struct. The base class provides utilities for initializing structs, cloning, copying, and comparing memory blocks. Struct proxy objects have properties whose getters and setters invoke NumGet and NumPut (or occasionally StrGet / StrPut):
cchTextMax {
get => NumGet(this, 24, "int")
set => NumPut("int", value, this, 24)
}
Embedded structs are not flattened (though unions are). For example, to get the handle of the window for which a NMHDDISPINFOW message was dispatched, you simply access its hdr property:
hwnd := dispInfo.hdr.hwndFrom
Struct proxies are buffer-like, so you can use them anywhere you would use a native Buffer. You can also access the ptr property directly. Unlike native AutoHotkey Buffers, struct proxies cannot be moved or resized.
See the wiki for more details.
Creating Structs
The Win32Struct.__New takes a pointer as its only argument. If that pointer is 0, a new Buffer is created to serve as the object's backing memory. This buffer is always cleared; every member of a new struct starts as 0 / NULL. If the pointer is not zero, the pointer is taken to be a pointer to the start of the struct proxy's memory block. Thus all you need to create a struct proxy is its pointer, as with the font enumeration example above:
logfont := LOGFONTW(lpelfe) ;Create a LOGFONTW struct at the pointer lpelfe
logfont := LOGFONTW() ;Create a new LOGFONTW struct backed by a Buffer
You can also initialize new structs using object literals. This works with embedded structures and array members as well. This method copies properties from the object literal into the struct member of the same name.
Wp := WINDOWPLACEMENT({
length: WINDOWPLACEMENT.sizeof
showCmd: 1,
rcNormalPosition: { ; An embedded RECT structure
top: 0,
bottom: 100,
left: 0,
right: 100
}
})
Struct members not present in the object literal remain at their default values (0 / NULL). In the above example (WINDOWPLACEMENT), the flags, ptMinPosition, and ptMaxPosition members are left unset and default to 0.
When initializing embedded structs or arrays, you can also provide a reference to an Array object or Win32Struct proxy object of the same type as the embedded struct. It is marginally faster to set the struct members manually, as doing so does not require the creation or disposal of a temporary object nor the enumeration of its properties.
COM Interfaces
COM Interfaces are included and use similar syntax to structs. Unlike native AutoHotkey, projected COM interfaces include interfaces that do not implement IDispatch. All COM interface proxies are objects extending Win32ComInterface. See the wiki for more details.
COM interface proxies, like struct proxies, a
Related Skills
node-connect
352.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
111.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
352.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
352.2kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
