WinDevLib
Windows Development Library for twinBASIC
Install / Use
/learn @fafalone/WinDevLibREADME
WinDevLib
Windows Development Library for twinBASIC
Current Version: 9.3.678 (March 27th, 2026)
(c) 2022-2026 Jon Johnson (fafalone)
[!IMPORTANT] Version 9.2.634 and higher now requires twinBASIC Beta 923 or newer. The project is now using twinBASIC's new
Aliassyntax support, which is impractical to version-gate. 954+ is required for OpenGL.
WinDevLib is a project to make all common Windows API COM interfaces, DLL declares, and related Types/Enums/Consts available while programming in twinBASIC.
Included are definitions of 3300+ common COM interfaces and 10,000+ APIs from all the common system modules, a level of coverage which makes WDL an entirely different experience than any VBx library, the largest of which offer at most 1/10th as much with huge gaps.
This makes working with WDL similar to working in C++ with #include <Windows.h> and a number of other headers for commonly used features. These have all been redone by hand from the original headers, in order to restore 64bit type info lost in VB6 versions, avoid the errors of automated conversion tools (e.g. Win32API_PtrSafe.txt is riddled with errors), and make them friendlier by converting groups of constants associated with a variable into an Enum so it comes up in Intellisense. This takes advantage of tB's ability to provide Intellisense for types besides Long in API defs (hopefully UDTs soon, this project has provisioning for that).
Creating this involves not only writing the definitions, but using tB compatible types-- so in some cases, even though there may be an existing way to import references to interfaces, they may be unusable due to e.g. the use of unsigned types, C-style arrays, double pointers, etc. In most cases these definitions are also compatible with VBA7, and with minor adjustments VB6; where they're not it's usually minor syntax adjustments, so this is also a great resource for APIs for those, covering vastly more than other other similar project.
This project is implemented purely in tB native code, as unlike VB6 there's language support for defining interfaces and coclasses. As a twinPACKAGE, regular code is supported in addition to the definitions, so some content normally found in regular addin modules have been built in (like you'd find in oleexp's mIID.bas, mPKEY.bas, etc, and helper functions). Does it still make sense to use a project like this when interfaces can be defined in-language? I'd say yes, because for a large number of interfaces, there's deep dependency chains with other interfaces and the types they rely on. It makes more sense to drop this in and be done with it than constantly have to define the interfaces you want and then stubs for their dependencies, especially when you might need those later on. This project is even more useful now with the API coverage; it should cover about 99% of your needs for core system DLLs.
This project also serves a comprehensive twinBASIC replacement for oleexp.tlb, my Modern Shell Interfaces Type Library project for VB6. 100% of the content is covered with little to no change (just String arguments in some places due to differences between how they're handled in typelibs).
Please report any bugs via the Issues feature here on GitHub.
Requirements
twinBASIC Beta 923 or newer is required.
Adding WinDevLib to your project
You have 2 options for this:
Via the Package Server
twinBASIC has an online package server and WinDevLib is published on it. Open your project settings and scroll to the Library References, then click Available Packages. Add "Windows Development Library for twinBASIC v7.0.272" (or whatever the newest version is). The other similar entry, "WinDevLib for Implements" contains Implements compatible versions of a small number of common interfaces not defined in a compatible way in the main project; you normally don't need this. For more details, including illustrations, see this post.
From a local file
You can download the project from this repository and use the WinDevLib.twinpack file. Navigate to the same area as above, and click on the "Import from file" button. WinDevLib.twinproj is the source for the package, if you want to edit it.
Optional Features
Compiler Flags
WinDevLib has some compiler constants you can enable:
WINDEVLIB_LITE - This flag disables most API declares and misc WinAPI definitions, including everything in wdAPIComCtl, wdAPI, and wdDefs. I used to like doing my APIs separate too, which is why oleexp never had the expansive coverage. But with that coverage now present, I think it's worth using, but this option will still be supported.
WDL_NO_DIRECTX - Excludes DirectX, Media Foundation, XAudio, and WinML content. This is useful to substantially cut down on Intellisense entries in non-multimedia apps. Basic 2D graphics remain (GDI, GDI+, WIC).
WDL_NO_GL - Excludes OpenGL.
WDL_NO_BYVAL_UDT - Do not use ByVal UDT arguments in interfaces/APIs. Reverts to the previous workarounds from VBx like LongLong for POINT and separate 32/64 bit defs for GUIDs. Useful for VBx code compatibility.
WDL_NO_COMCTL - You can use this flag if you already have an alternative common controls definition set, e.g. tbComCtlLib; it will disable wdAPIComCtl. (Note: WinDevLib has more complete comctl defs than tbComCtlLib, as that project was deprecated and not updated).
WDL_DLGSH - This enabled constants from dlg.h. These are extremely uncommon to use, and have very short, generic names likely to cause conflicts, so they're opt-in.
WDL_NOQUADLI - Restores the old LARGE_INTEGER definition of lo/high Long values.
[!WARNING] The
WDL_NOQUADLIconstant will break alignment on numerous Types; most only on x64, but some on both.
WDL_AVOID_INTRINSICS - Uses the Interlocked* APIs that are exported from kernel32.dll (32bit mode only) instead of the static library containing compiler intrinsic versions of those in addition to all the ones not exported and all the 64bit ones.
WDL_NO_LIBS - Fully exclude static libraries (currently only Interlocked); mainly intended for comparing current tB versions to Beta 423 where the Import Library syntax is not yet supported.
WDL_NO_DELEGATES - Do not use Delegate functions in place of function pointers.
WDL_NO_WS_ALIASES - Do not use ws_prefixes for the short name common word Winsock APIs (send, connect, bind, etc)
WDL_XAUDIO8 - Use XAudio8 DLLs for XAudio2 APIs (Windows 8)
WDL_NOMATH - Exclude built in math helper function (see below). Note: XAudio2 inlined helper functions unavailable when math disabled.
WDL_ADS_DEFINED - activeds.tlb is referenced, enable interfaces using its contents.
[!IMPORTANT] Currently flags are not inherited from the main project, so the only way to use these is to set them in the compiler flags for WinDevLib.twinproj then build a custom twinpack.
Custom Helper Functions
In addition to coverage of common Windows SDK-defined macros and inlined functions, a small number of custom helper functions are provided to deal with Windows data types and similar not properly supported by the language. These are:
Public Function GetMem(Of T)(ByVal ptr As LongPtr) As T - A generic to dereference a pointer into any type. The native CType(Of ) allows dereferencing to UDTs, but this helper allows instrinsic types in addition to UDTs, and is used the same way.
Public Function DCast(Of T, T2)(v As T2) As T - Direct Cast: Copies the data of v into any type, without modification, so no overflows, and possible to e.g. go from LongLong to POINT, with Dim pt As POINT = DCast(Of POINT)(SomeLongLong)
Public Function LPWSTRtoStr(lPtr As LongPtr, Optional ByVal fFree As Boolean = True) As String
Converts a pointer to an LPWSTR/LPCWSTR/PWSTR/etc to an instrinsic String (BSTR)
Public Function WCHARtoSTR(aCh() As Integer) As String
Converts an Integer arrat of WCHARs to a tB String (BSTR).
Public Function UtfToANSI(sIn As String) As String
Converts a Unicode string to ANSI. This function is [ConstantFoldable] -- it can be used to create strings resolved at compile time and stored as constants; this technique was developed to use ANSI strings in kernel mode, where the APIs that handle a normal String cannot be used.
Public Function VariantLPWSTRtoSTR(pVar As Variant, pOut As String) As Boolean
Retrieves a tB-style String from a VT_LPWSTR Variant. Returns False if pVar is a null pointer, or the Variant is not a VT_LPWSTR, or PropVariantToStringAlloc returns a nullptr.
Public Function GetSystemErrorString(lErrNum As Long, Optional ByVal lpSource As LongPtr = 0) As String
Public Function GetNtErrorString(lErrNum As Long) As String
Retrieve descriptions of HRESULT and NTSTATUS error codes, respectively.
Public Function VariantSetType(pvar As Variant, [TypeHint(VARENUM)] ByVal vt As Integer, [TypeHint(VARENUM)] Optional ByVal vtOnlyIf As Integer = -1) As Boolean
Sets a Variant to the specified type without any alteration to the data. vtOnlyIf will abort the change and return False if the original type is other than specified. This should only be used when VariantChangeType is not applicable, and only with full understanding of consequences like automation errors if you attempt to use intrinsic operations on unsupported types; e.g. if you set the type to VT_UI4, then CLng() will raise a 'type unsupported' runtime error.
Public Function PointerAdd(ByVal Start As LongPtr, ByVal Incr As LongPtr) As LongPtr
Public Function UnsignedAdd(ByVal Start As Long, ByVal Incr As Long) As Long
Public Function UnsignedAdd(ByVal Start As Integer, ByVal Incr As Integer) As Integer
`Public Function UnsignedAdd(ByVal Start As LongLong, ByVal I
