06-22-2016, 04:38 AM
#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
[DllImport("user32.dll")]
public static extern int InternalGetWindowText(Wnd hWnd, [Out] StringBuilder pString, int cchMaxCount);
//example of a function that uses a callback function (delegate)
[DllImport("user32.dll")]
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
[DllImport("user32.dll")]
public static extern bool GetWindowRect(Wnd hWnd, out RECT lpRect);
}
#endregion
#region my-console-program
class Program
{
[STAThread]
static void Main(string[] args)
{
//find Notepad window
Wnd hwnd = API.FindWindow("Notepad", null);
Console.WriteLine(hwnd);
//get window name
var sb = new StringBuilder(1000);
API.InternalGetWindowText(hwnd, sb, sb.Capacity);
var s = sb.ToString();
Console.WriteLine(s);
//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);
Console.WriteLine(r);
//don't close console immediately
Console.ReadKey();
}
}
#endregion
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();'.