SkillAgentSearch skills...

AhkWin32Projection

Win32 API bindings for 64-bit AutoHotkey V2

Install / Use

/learn @holy-tao/AhkWin32Projection
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

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: Modern IntelliSense for APIs from the 90s

Table of Contents

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> </details>

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

View on GitHub
GitHub Stars33
CategoryDevelopment
Updated7d ago
Forks4

Languages

AutoHotkey

Security Score

95/100

Audited on Mar 31, 2026

No findings