Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Windows API declarations for C#

This is for C# programmers, not for QM. In QM can be used only in C# scripts.

Contains 48000 declarations of struct, enum, delegate, extern functions, interfaces, coclasses, Guid, const.

Converted commonly used Windows 10 SDK header files. The list is below.

Tools used to convert C to C#:
Quick Macros - scripting.
Clang - preprocessing.
Dumpbin from SDK - extracting dll names and GUID.
My C-to-C# converter project.

More declarations may be added in the future. Usually for me it is easy to do with these tools. Your suggestions are welcome.

Macro SDK headers
Select All      Help
//#define __cplusplus 201103L //clang defines this
#define _MSC_VER 1900 //VS2015
#define _MSC_FULL_VER 190023026

#define _UNICODE 1
#define UNICODE 1
#define _WCHAR_T_DEFINED 1
#define _MT 1
#define _DLL 1
#define _WIN32 1 //defined for 32 and 64

#ifdef USE64BIT
#define _WIN64 1
#define _M_AMD64 100
#define _M_X64 100
#define _M_IX86 600
#define _INTEGRAL_MAX_BITS 64 //need if 32

#define WINVER 0x0A00 //Win10
#define _WIN32_WINNT 0x0A00
#define _WIN32_IE 0x0B00 //IE11

//add __int128 struct, because C# does not have a matching type
struct __int128 { float a, b, c, d; };
struct __int128d { float a, b, c, d; };
struct __int128i { float a, b, c, d; };

//prevent adding XML interfaces, but need some for parameters
#define __msxml_h__
#define __msxml2_h__
#define __msxml6_h__
typedef IntPtr IXMLElement;
typedef IntPtr IXMLDOMDocument;

//add some that are in headers that we remove
#define size_t LPARAM
#define intptr_t LPARAM
#define uintptr_t LPARAM
#define time_t LPARAM
typedef void* va_list;
typedef struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; } FILE;

#define WIN32_LEAN_AND_MEAN //don't include come rarely used headers in windows.h
#define USE_COM_CONTEXT_DEF //IContext etc

#include <windows.h>

#include <regstr.h> //registry strings
#include <ole2.h> //OLE. Includes objbase.h, oleauto.h, urlmon.h, ...
#include <commctrl.h> //common controls
#include <shlobj.h> //shell
#include <shellapi.h> //shell
#include <shlwapi.h> //misc string functions etc
#include <olectl.h> //some OLE API
#include <oleacc.h> //MSAA accessible objects
#include <UIAutomation.h> //UI Automation
#include <mmsystem.h> //multimedia etc
#include <tlhelp32.h> //process info etc
#include <psapi.h> //process info etc
#include <wtsapi32.h> //user sessions etc
#include <winperf.h> //something used with PDH
#include <pdh.h> //performance counters //TODO: test System.Diagnostics.PerformanceCounter
#include <uxtheme.h> //visual styles
#include <vsstyle.h> //visual styles
#include <dwmapi.h> //DWM
#include <htmlhelp.h> //HTML help
#include <winioctl.h> //file IO low-level
#include <aclapi.h> //security //TODO: test System.Security.AccessControl etc
#include <sddl.h> //security strings
#include <taskschd.h> //Task Scheduler
#include <ShellScalingAPI.h> //high DPI
#include <appmodel.h> //Windows Store apps
#include <winternl.h> //Windows semi-internal API, eg NtX, RtlX
#include <iepmapi.h> //IE protected mode
#include <userenv.h> //user profiles, CreateEnvironmentBlock
#include <netlistmgr.h> //network list
#include <winnetwk.h> //networking
#include <cderr.h> //commdlg errors
#include <commdlg.h> //common dialogs //TODO: test System.Windows.Forms.OpenFileDialog, .FontDialog etc.
#include <dde.h> //DDE
#include <ddeml.h> //DDE
#include <wininet.h> //internet. We can instead use System.Net.Http namespace and System.Net.FtpWebRequest classes, but maybe this still can be useful.
#include <winsock2.h> //sockets (TCP etc) //TODO: test System.Net.Sockets
#include <nspapi.h> //MS extensions for sockets
#include <richedit.h> //rich edit control
#include <usp10.h> //text drawing low-level
#include <dbt.h> //const/struct for WM_DEVICECHANGE
#include <ktmw32.h> //file transaction
#define _MSI_NO_CRYPTO
#include <msi.h> //installer. MsiGetShortcutTarget, MsiGetComponentPath.
#include <commoncontrols.h> //IImageList
#include <powrprof.h> //power profiles, SetSuspendState
#include <lm.h> //LAN management, NetServerEnum
#include <Wlanapi.h> //WiFi
#include <adhoc.h> //WiFi
#include <mscoree.h> //unmanaged .NET API

//core audio API
#include <Audioclient.h>
#include <Audiopolicy.h>
#include <Mmdeviceapi.h>
#include <Devicetopology.h>
#include <Endpointvolume.h>

#if 0
//these are little tested and probably not useful
#include <iphlpapi.h> //IP helper, eg list network adapters. Use System.Net.NetworkInformation namespace.
#include <icmpapi.h> //ICMP, eg to implement a Ping(). Use System.Net.NetworkInformation namespace.
#include <GL/gl.h> //openGL
#include <GL/glu.h> //openGL util

//these are never tested but seem interesting
#include <RestartManager.h> //restart manager
#include <Pla.h> //performance logs and alerts
#include <Esent.h> //extensible storage engine
#include <Clfsw32.h> //common log file system. .NET has something similar in System.Diagnostics.
#include <Clfsmgmtw32.h> //common log file management. .NET has something similar in System.Diagnostics.
#include <WinEvt.h> //event log. .NET has something similar in System.Diagnostics.
#include <Winsxs.h> //several interfaces for side-by-side assembly management

//these probably should not be added
#include <shldisp.h> //shell IDispatch interfaces
#include <scrnsave.h> //screen saver
#include <dbghelp.h> //debug help library
#include <imagehlp.h> //many the same as dbghelp.h. Includes wintrust.h -> wincrypt.h which is not welcome.
#include <setupapi.h> //obsolete
#include <mapi.h> //only for MS Outlook. Can instead use Outlook COM.
#include <snmp.h> //can instead download a SNMP .NET library
#include Sspi.h //authentication. Includes Security.h. Use .NET classes.
//these would be included if no WIN32_LEAN_AND_MEAN
#include <winefs.h> //encrypted file system. .NET can encrypt/decrypt a file, but maybe this also can be useful.
#include <winspool.h> //printer API. Big. Use System.Drawing.Printing namespace. See also System.Printing namespace.
#include <wincrypt.h> //cryptography. Large. Use System.Security.Cryptography namespace.

How to use the downloaded file containing Windows API declarations:
Select All      Help
// Don't add this file to your project. Copy-paste only declarations that you need.
// Not all declarations can be compiled without editing.
//    For example, cannot declare some struct pointer (use IntPtr instead, or in struct replace non-blittable types with IntPtr etc), cannot use undefined struct pointer/ref/out (use IntPtr instead).
// Not all declarations are correct, usually because declarations in Windows SDK files from which they have been automatically converted lack some info.
//    For example, some function parameters that should be 'out' or '[Out]' or '[In]' or array now are just 'ref', because SDK declarations didn't have proper in/out annotations. Also for this reason some parameters that should be 'string' now are 'StringBuilder'.
//    You may want to create overloads where parameters can be of more than one type.
//    You may want to add 'SetLastError=true' to DllImport attribute parameters.
// Some declarations contain pointers and therefore can be used only in 'unsafe' context, in some cases with 'fixed'. Or you can replace pointers to IntPtr.
// These declarations are for Windows 10. Some Windows API are different or missing on other Windows versions.
// In some cases need to use different declarations in 32-bit and 64-bit process. This file contains everything that is not different, + 64-bit versions, + 32-bit versions with name suffix ""__32"".

Also known as P/invoke, pinvoke, platform invoke signatures, call unmanaged dll exported methods, Win32 API, COM interop.
Could you give some simple examples how to use this Windows API in C#?
Select All      Help
#region copy-paste-from-Api.cs

using System;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;

using Wnd = System.IntPtr; //HWND (window handle)
using LPARAM = System.IntPtr; //LPARAM, WPARAM, LRESULT, X_PTR, SIZE_T, ... (non-pointer types that have different size in 64-bit and 32-bit process)

//add this to projects that will use these API
[module: DefaultCharSet(CharSet.Unicode)]

static unsafe class API
    //simplest Windows API function declaration  example
    [DllImport("user32.dll", EntryPoint = "FindWindowW")]
    public static extern Wnd FindWindow(string lpClassName, string lpWindowName);

    //example of a function that gets text using a caller-allocated buffer
    public static extern int InternalGetWindowText(Wnd hWnd, [Out] StringBuilder pString, int cchMaxCount);

    //example of a function that uses a callback function (delegate)
    public static extern bool EnumChildWindows(Wnd hWndParent, WNDENUMPROC lpEnumFunc, LPARAM lParam);

    //example delegate type declaration
    public delegate bool WNDENUMPROC(Wnd param1, LPARAM param2);

    //this is probably the most popular Windows API function, but .NET does not have a wrapper function or class that works with any window
    [DllImport("user32.dll", EntryPoint = "SendMessageW")]
    public static extern LPARAM SendMessage(Wnd hWnd, uint Msg, LPARAM wParam, LPARAM lParam);

    //overload example: lParam is string
    [DllImport("user32.dll", EntryPoint = "SendMessageW")]
    public static extern LPARAM SendMessage(Wnd hWnd, uint Msg, LPARAM wParam, string lParam);

    //constant example
    public const uint WM_SETTEXT = 0xC;

    //struct example
    public struct RECT
        public int left;
        public int top;
        public int right;
        public int bottom;

        //of course here we can add member functions
        public override string ToString()
            return string.Format("L={0} T={1} R={2} B={3}  W={4} H={5}", left, top, right, bottom, right-left, bottom-top);

    //and a function that uses the struct
    public static extern bool GetWindowRect(Wnd hWnd, out RECT lpRect);



#region my-console-program

class Program
    static void Main(string[] args)
        //find Notepad window
        Wnd hwnd = API.FindWindow("Notepad", null);

        //get window name
        var sb = new StringBuilder(1000);
        API.InternalGetWindowText(hwnd, sb, sb.Capacity);
        var s = sb.ToString();

        //find first child window
        Wnd hctrl = default(Wnd);
        API.EnumChildWindows(hwnd, (h, p) => { hctrl = h; return false; }, default(LPARAM) );

        //set child window text
        API.SendMessage(hctrl, API.WM_SETTEXT, default(LPARAM), "Notepad window name is " + s);

        //get window rectangle
        API.RECT r;
        API.GetWindowRect(hwnd, out r);
        //don't close console immediately


Normally you'll use this in C# projects. To allow 'unsafe' keyword, in project Properties Build tab check 'Allow unsafe code'. Or remove the 'unsafe' keyword.

If want to run this as a QM C# script, remove the 'unsafe' keyword or use code 'CsScript x.SetOptions("compilerOptions=/unsafe"); x.Exec("")'. Also remove 'Console.ReadKey();'.
Thanks a lot for a thorough explanation.
I could compile and run it both as C# project and QM script.
Without your clarification and sample I have no clue how to get started on using this API stuff.
It really convenient to use C++ API in C# now.
Function SDK_find_declaration
Trigger Cd     Help - how to add the trigger to the macro
Select All      Help
;Finds a Windows API declaration in Api.cs.
;How to use:
;;;In your C# editor type a Windows API name, move the mouse over it and run this macro.
;;;Or move the mouse over a Windows API name anywhere, for example in API documentation.
;;;To run this macro you can use a hotkey trigger; default is Ctrl+D.
;;;The macro shows a dialog with the API name, its C# declaration (empty if not found) and several options.
;;;In the dialog review the declaration, maybe change options, and click OK.
;;;If you start this macro while it is already running, it replaces text in the dialog.
;;;Also you can edit text in the dialog Name field to search for a new name.
;How it works:
;;;Double-clicks to select word from mouse, and gets the word through the clipboard.
;;;Finds the declaration in Api.cs file and shows it in dialog together with options.
;;;Api.cs file full path must be specified in the dialog.
;;;The macro can copy the declaration to the clipboard or/and run a macro that for example can insert the declaration in a C# file. Example - function SDK_insert_declaration.

spe 20
int w=win(mouse)
if w!=_hwndqm or !WinTest(child(mouse) "Toolbar*") ;;prevent double clicking the Run button
,if(w!=win) act w; key LR ;;prevent VS selecting whole line when there is selected text
,str name.getsel

if getopt(nthreads)>1
,w=win("Windows API for C#" "#32770")
,if w
,,name.setwintext(id(4 w))
,,act w

str dd=
;0 "" 0x90C80AC8 0x0 0 0 552 166 "Windows API for C#"
;3 Static 0x54000000 0x0 8 8 28 12 "Name"
;4 Edit 0x54030080 0x200 40 8 152 12 "Nam" "Windows API name (a function, struct, enum, delegate, const, interface, COM class, Guid).[]In your C# editor type the name, move the mouse over it and run this macro."
;6 Edit 0x54231044 0x200 8 24 536 72 "Decl"
;10 Static 0x54000000 0x0 16 116 38 13 "File Api.cs"
;11 Edit 0x54030080 0x200 56 116 208 13 "Api"
;7 Button 0x54012003 0x0 288 116 76 13 "Copy to clipboard"
;14 Button 0x54012003 0x0 376 116 54 13 "Run macro"
;15 Edit 0x54030080 0x200 432 116 104 13 "Mac" "Should begin with:[]function str'name str'decl"
;1 Button 0x54030001 0x4 8 144 48 14 "OK"
;2 Button 0x54030000 0x4 60 144 48 14 "Cancel"
;5 Button 0x54020007 0x0 8 100 536 37 "Options"
;DIALOG EDITOR: "" 0x2040308 "*" "" "" ""

str controls = "4 6 11 7 14 15"
str e4Nam e6Dec e11Api c7Cop c14Run e15Mac
rget e11Api "Api.cs" "\CsharpWinAPI" 0 "$my qm$\Api.cs"
rget c7Cop "bClipboard" "\CsharpWinAPI" 0 "1"
rget c14Run "bMacro" "\CsharpWinAPI"
rget e15Mac "sMacro" "\CsharpWinAPI"

if(!ShowDialog(dd &sub.DlgProc &controls)) ret

rset e11Api "Api.cs" "\CsharpWinAPI"
rset c7Cop "bClipboard" "\CsharpWinAPI"
rset c14Run "bMacro" "\CsharpWinAPI"
rset e15Mac "sMacro" "\CsharpWinAPI"

if(!e6Dec.len) ret

if c7Cop=1

if c14Run=1 and e15Mac.len
,mac e15Mac "" e4Nam e6Dec

err+ mes _error.description "" "x"

#sub DlgProc
function# hDlg message wParam lParam

sel message
,sub.Find hDlg
,case WM_COMMAND goto messages2
sel wParam
,case IDOK
,case EN_CHANGE<<16|4
,sub.Find hDlg
,case EN_CHANGE<<16|11
,if(FileExists(_s)) sub.Find hDlg
ret 1

#sub Find
function hDlg

str apiFile.getwintext(id(11 hDlg))
str name.getwintext(id(4 hDlg))

if(!apiFile.len) mes "Api.cs file not specified."; ret
if(!FileExists(apiFile)) mes "Api.cs file not found."; ret

type __CSHARPWINAPICACHE IStringMap'm str'path DateTime'time long'size

DateTime t; long z
FileGetAttributes apiFile z t
if apiFile!=__g_csWinApiCache.path or t!=__g_csWinApiCache.time or z!=__g_csWinApiCache.size
,sub.ApiFileToStringMap __g_csWinApiCache.m apiFile
,if(__g_csWinApiCache.m.Count=0) mes "Found 0 declarations in Api.cs file."; ret
,__g_csWinApiCache.path=apiFile; __g_csWinApiCache.time=t; __g_csWinApiCache.size=z
,;out "loaded"

if(empty(name)) ret
str decl
__g_csWinApiCache.m.Get2(name decl)
str decl32
if(__g_csWinApiCache.m.Get2(F"{name}__32" decl32)) decl+"[][]"; decl+decl32
if(decl.len) decl+"[]"
decl.setwintext(id(6 hDlg))

err+ mes _error.description "" "x"

#sub ApiFileToStringMap
function IStringMap&m $apiFile

m._create; m.Flags=2

str s.getfile(apiFile)

ARRAY(str) a

str rxType="(?ms)^(?:\[[^\r\n]+\r\n)*public (?:struct|enum|interface|class) (\w+)[^\r\n\{]+\{(?:\}$|.+?^\})"
str rxFunc="(?m)^(?:\[[^\r\n]+\r\n)*public (?:static extern|delegate) \w+\** (\w+)\(.+;$"
str rxGuid="(?m)^public static Guid (\w+) =.+;$"
str rxConst="(?m)^public (?:const|readonly) \w+ (\w+) =.+;$"

if(!findrx(s rxType 0 4 a)) end "failed" 1
sub.AddToMap a m
if(!findrx(s rxFunc 0 4 a)) end "failed" 1
sub.AddToMap a m
if(!findrx(s rxGuid 0 4 a)) end "failed" 1
sub.AddToMap a m
if(!findrx(s rxConst 0 4 a)) end "failed" 1
sub.AddToMap a m

#sub AddToMap
function ARRAY(str)&a IStringMap'm

int i
for i 0 a.len
,m.Add(a[1 i] a[0 i])

Function SDK_insert_declaration
Select All      Help
function str'name str'decl

;Inserts decl in file csFile, before line //insert new declaration here
;You can specify this function name in dialog "Windows API for C#" (function SDK_fine_declaration shows it) field "Run macro".
;If the file is open in Visual Studio, it nicely updates editor text, even with Undo, if the file is saved. Tested with Visual Studio 2015.

str csFile="Q:\Test\Test.cs" ;;change this

;out name
;out decl

str s.getfile(csFile)
int i=findrx(s "[][ \t]*//insert new declaration here")
if(i<0) end "the file must have line ''//insert new declaration here''"
decl.replacerx("(?m)^" "[9]") ;;tab-indent
s.insert(decl i)
s.setfile(csFile 0 -1 0x100)

Forum Jump:

Users browsing this thread: 1 Guest(s)