Using C# language to call windows API, in following codes we mainly used methods located in user32.dll , so we firstly should create a method in C# that will mapping the corresponding method in user32.dll. in these codes, you will see:
1. to get a window handler
2. to get a control in the window
3. to get the control text
4. to click a mouse left button in the current position
5. to invoke a button just same as user click on it
public class UITest
{
/// <summary>
/// To Get a window handler by window caption(Text)
/// </summary>
/// <param name="caption">window's catpoin</param>
/// <param name="delay">set delay time ; which may not find window because of window not completely loaded</param>
/// <param name="maxTries">maximum tries times</param>
/// <returns>a window handler</returns>
public static IntPtr FindTopLevelWindow(string caption, int delay, int maxTries)
{
IntPtr mwh = IntPtr.Zero;
bool formFound = false;
int attempts = 0;
do
{
mwh = FindWindow(null, caption);
if (mwh == IntPtr.Zero)
{
Thread.Sleep(delay);
attempts++;
}
else
{
formFound = true;
}
} while (attempts < maxTries && !formFound);
return mwh;
}
/// <summary>
/// To get control handler by control caption(Text)
/// </summary>
/// <param name="hwndParent"></param>
/// <param name="caption"></param>
/// <returns>a control handler</returns>
public static IntPtr FindControlByCaption(IntPtr hwndParent, string caption)
{
if (hwndParent == IntPtr.Zero)
return IntPtr.Zero;
IntPtr result = IntPtr.Zero;
result = FindWindowEx(hwndParent, IntPtr.Zero, null, caption);
return result;
}
/// <summary>
/// To Get a control by Index, you can calculate it's index using Spy++
/// </summary>
/// <param name="hwndParent">parent handler</param>
/// <param name="index">index in parent handler</param>
/// <returns>a control hander</returns>
public static IntPtr FindControlByIndex(IntPtr hwndParent, int index)
{
if (hwndParent == IntPtr.Zero)
return IntPtr.Zero;
if (index == 0)
return hwndParent;
else
{
int ct = 0;
IntPtr result = IntPtr.Zero;
do
{
result = FindWindowEx(hwndParent, result, null, null);
if (result != IntPtr.Zero)
ct++;
}
while (ct < index && result != IntPtr.Zero);
return result;
}
}
/// <summary>
/// To click on a button or something like that
/// </summary>
/// <param name="hControl">control to click on</param>
public static void ClickOn(IntPtr hControl)
{
if (hControl == IntPtr.Zero)
return;
uint WM_LBUTTONDOWN = 0x0201;
uint WM_LBUTTONUP = 0x0202;
PostMessage1(hControl, WM_LBUTTONDOWN, 0, 0);
PostMessage1(hControl, WM_LBUTTONUP, 0, 0);
}
/// <summary>
/// Close the window
/// </summary>
/// <param name="hControl"></param>
public static void CloseWindow(IntPtr hControl)
{
if (hControl == IntPtr.Zero)
return;
uint WM_CLOSE = 0x0010;
PostMessage1(hControl, WM_CLOSE, 0, 0);
}
/// <summary>
/// send one char to an editable control
/// </summary>
/// <param name="hControl">an editable control</param>
/// <param name="c">one char</param>
public static void SendChar(IntPtr hControl, char c)
{
if (hControl == IntPtr.Zero)
return;
uint WM_CHAE = 0x0102;
SendMessage1(hControl, WM_CHAE, c, 0);
}
/// <summary>
/// Fill in a string in an Editable control like textbox
/// </summary>
/// <param name="hControl">an editable control</param>
/// <param name="s">a string</param>
public static void SendString(IntPtr hControl, string s)
{
foreach (char c in s)
{
SendChar(hControl, c);
}
}
/// <summary>
/// To get the display text of control
/// </summary>
/// <param name="hControl">a control handler</param>
/// <returns>text string</returns>
public static string GetControlText(IntPtr hControl)
{
if (hControl == IntPtr.Zero)
return "Control Not Find!";
uint WM_GETTEXT = 0x000D;
uint WM_GETTEXTLENGTH = 0x000E;
int textLength = 0;
string result = null;
textLength = SendMessage5(hControl, WM_GETTEXTLENGTH, 0, 0);
if (textLength == 0)
return "Control Text is empty";
//if we use textLength as wParam, we will get the length of the older text for this control
byte[] buffer = new byte[256];
int numFetched = SendMessage3(hControl, WM_GETTEXT, 256, buffer);
result = System.Text.Encoding.Unicode.GetString(buffer);
if (result != null)
return result;
else
return "Failed to Get Text";
}
/// <summary>
/// To check if the specified text was contained in this list box
/// </summary>
/// <param name="hControl">list box handler</param>
/// <param name="itemText"></param>
/// <returns>return true if text was contained</returns>
public static bool IsListBoxContainItem(IntPtr hControl, string itemText)
{
if (hControl == IntPtr.Zero)
return false;
uint LB_FINDSTRING = 0x018F;
bool isFound = false;
int result = -1;
result = SendMessage4(hControl, LB_FINDSTRING, -1, itemText);
if (result >= 0)
isFound = true;
else
isFound = false;
return isFound;
}
//Menu
public static void SelectMenu(IntPtr hwForm, int menuID)
{
uint WM_COMMAND = 0x0111;
SendMessage2(hwForm, WM_COMMAND, menuID, IntPtr.Zero);
}
//P/Invoke
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//hwndChildAfter default is IntPtr.Zero(Find from all controls)
[DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAter, string lpszClass, string lpszWindow);
//used for sending command "WM_CHAR"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern void SendMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);
//Used for sending command "WM_COMMAND"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern void SendMessage2(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);
//Used for sending command "WM_LBUTTONDOWN" and "WM_LBUTTONUP"
[DllImport("user32.dll", EntryPoint = "PostMessage", CharSet = CharSet.Auto)]
static extern void PostMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);
//Used for sending command "WM_GETTEXT"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern int SendMessage3(IntPtr hWndControl, uint Msg, int wParam, byte[] lParam);
//Used for sending command "LB_FINDSTRING"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern int SendMessage4(IntPtr hWnd, uint Msg, int wParam, string lParam);
//Used for sending command "WM_GETTEXTLENGTH"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern int SendMessage5(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("user32.dll", EntryPoint = "GetMenu", CharSet = CharSet.Auto)]
public static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "GetSubMenu", CharSet = CharSet.Auto)]
public static extern IntPtr GetSubMenu(IntPtr hWnd, int nPos);
[DllImport("user32.dll", EntryPoint = "GetMenuItemID", CharSet = CharSet.Auto)]
public static extern int GetMenuItemID(IntPtr hMenu, int nPos);
//Test used in mouse_event
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr GetMessageExtraInfo();
[DllImport("user32.dll")]
internal static extern bool GetCursorPos(ref Point lpPoint);
[DllImport("user32.dll")]
internal static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll", EntryPoint = "mouse_event", CharSet = CharSet.Auto)]
static extern void mouse_event(uint command, int x, int y, int dwdata, IntPtr dwExtraInfo);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint RegisterWindowMessage(string lpString);
[DllImport("oleacc.dll", PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern object ObjectFromLresult(UIntPtr lResult, [MarshalAs(UnmanagedType.LPStruct)] Guid refiid, IntPtr wParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);
public enum SendMessageTimeoutFlags :
uint
{
SMTO_NORMAL = 0x0000,
SMTO_BLOCK = 0x0001,
SMTO_ABORTIFHUNG = 0x0002,
SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
}
/// <summary>
/// Click left button on the Point(X, Y)
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public static void ClickOnPosition(int x, int y)
{
uint MOUSEEVENTF_LEFTDOWN = 0x0002;
uint MOUSEEVENTF_LEFTUP = 0x0004;
mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, GetMessageExtraInfo());
mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, GetMessageExtraInfo());
}
/// <summary>
/// Move Cursor
/// </summary>
/// <param name="x">X direction Increment</param>
/// <param name="y">Y direction Increment</param>
public static void MoveCursor(int x, int y)
{
uint MOUSEEVENTF_MOVE = 0x0001;
mouse_event(MOUSEEVENTF_MOVE, x, y, 0, GetMessageExtraInfo());
}
/// <summary>
/// Click on Current cursor position
/// </summary>
public static void ClickOnCurrentPosition()
{
try
{
System.Drawing.Point defPnt = new System.Drawing.Point();
GetCursorPos(ref defPnt);
ClickOnPosition(defPnt.X, defPnt.Y);
Thread.Sleep(1000);
}
catch { }
}
}
{
/// <summary>
/// To Get a window handler by window caption(Text)
/// </summary>
/// <param name="caption">window's catpoin</param>
/// <param name="delay">set delay time ; which may not find window because of window not completely loaded</param>
/// <param name="maxTries">maximum tries times</param>
/// <returns>a window handler</returns>
public static IntPtr FindTopLevelWindow(string caption, int delay, int maxTries)
{
IntPtr mwh = IntPtr.Zero;
bool formFound = false;
int attempts = 0;
do
{
mwh = FindWindow(null, caption);
if (mwh == IntPtr.Zero)
{
Thread.Sleep(delay);
attempts++;
}
else
{
formFound = true;
}
} while (attempts < maxTries && !formFound);
return mwh;
}
/// <summary>
/// To get control handler by control caption(Text)
/// </summary>
/// <param name="hwndParent"></param>
/// <param name="caption"></param>
/// <returns>a control handler</returns>
public static IntPtr FindControlByCaption(IntPtr hwndParent, string caption)
{
if (hwndParent == IntPtr.Zero)
return IntPtr.Zero;
IntPtr result = IntPtr.Zero;
result = FindWindowEx(hwndParent, IntPtr.Zero, null, caption);
return result;
}
/// <summary>
/// To Get a control by Index, you can calculate it's index using Spy++
/// </summary>
/// <param name="hwndParent">parent handler</param>
/// <param name="index">index in parent handler</param>
/// <returns>a control hander</returns>
public static IntPtr FindControlByIndex(IntPtr hwndParent, int index)
{
if (hwndParent == IntPtr.Zero)
return IntPtr.Zero;
if (index == 0)
return hwndParent;
else
{
int ct = 0;
IntPtr result = IntPtr.Zero;
do
{
result = FindWindowEx(hwndParent, result, null, null);
if (result != IntPtr.Zero)
ct++;
}
while (ct < index && result != IntPtr.Zero);
return result;
}
}
/// <summary>
/// To click on a button or something like that
/// </summary>
/// <param name="hControl">control to click on</param>
public static void ClickOn(IntPtr hControl)
{
if (hControl == IntPtr.Zero)
return;
uint WM_LBUTTONDOWN = 0x0201;
uint WM_LBUTTONUP = 0x0202;
PostMessage1(hControl, WM_LBUTTONDOWN, 0, 0);
PostMessage1(hControl, WM_LBUTTONUP, 0, 0);
}
/// <summary>
/// Close the window
/// </summary>
/// <param name="hControl"></param>
public static void CloseWindow(IntPtr hControl)
{
if (hControl == IntPtr.Zero)
return;
uint WM_CLOSE = 0x0010;
PostMessage1(hControl, WM_CLOSE, 0, 0);
}
/// <summary>
/// send one char to an editable control
/// </summary>
/// <param name="hControl">an editable control</param>
/// <param name="c">one char</param>
public static void SendChar(IntPtr hControl, char c)
{
if (hControl == IntPtr.Zero)
return;
uint WM_CHAE = 0x0102;
SendMessage1(hControl, WM_CHAE, c, 0);
}
/// <summary>
/// Fill in a string in an Editable control like textbox
/// </summary>
/// <param name="hControl">an editable control</param>
/// <param name="s">a string</param>
public static void SendString(IntPtr hControl, string s)
{
foreach (char c in s)
{
SendChar(hControl, c);
}
}
/// <summary>
/// To get the display text of control
/// </summary>
/// <param name="hControl">a control handler</param>
/// <returns>text string</returns>
public static string GetControlText(IntPtr hControl)
{
if (hControl == IntPtr.Zero)
return "Control Not Find!";
uint WM_GETTEXT = 0x000D;
uint WM_GETTEXTLENGTH = 0x000E;
int textLength = 0;
string result = null;
textLength = SendMessage5(hControl, WM_GETTEXTLENGTH, 0, 0);
if (textLength == 0)
return "Control Text is empty";
//if we use textLength as wParam, we will get the length of the older text for this control
byte[] buffer = new byte[256];
int numFetched = SendMessage3(hControl, WM_GETTEXT, 256, buffer);
result = System.Text.Encoding.Unicode.GetString(buffer);
if (result != null)
return result;
else
return "Failed to Get Text";
}
/// <summary>
/// To check if the specified text was contained in this list box
/// </summary>
/// <param name="hControl">list box handler</param>
/// <param name="itemText"></param>
/// <returns>return true if text was contained</returns>
public static bool IsListBoxContainItem(IntPtr hControl, string itemText)
{
if (hControl == IntPtr.Zero)
return false;
uint LB_FINDSTRING = 0x018F;
bool isFound = false;
int result = -1;
result = SendMessage4(hControl, LB_FINDSTRING, -1, itemText);
if (result >= 0)
isFound = true;
else
isFound = false;
return isFound;
}
//Menu
public static void SelectMenu(IntPtr hwForm, int menuID)
{
uint WM_COMMAND = 0x0111;
SendMessage2(hwForm, WM_COMMAND, menuID, IntPtr.Zero);
}
//P/Invoke
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//hwndChildAfter default is IntPtr.Zero(Find from all controls)
[DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAter, string lpszClass, string lpszWindow);
//used for sending command "WM_CHAR"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern void SendMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);
//Used for sending command "WM_COMMAND"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern void SendMessage2(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);
//Used for sending command "WM_LBUTTONDOWN" and "WM_LBUTTONUP"
[DllImport("user32.dll", EntryPoint = "PostMessage", CharSet = CharSet.Auto)]
static extern void PostMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);
//Used for sending command "WM_GETTEXT"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern int SendMessage3(IntPtr hWndControl, uint Msg, int wParam, byte[] lParam);
//Used for sending command "LB_FINDSTRING"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern int SendMessage4(IntPtr hWnd, uint Msg, int wParam, string lParam);
//Used for sending command "WM_GETTEXTLENGTH"
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern int SendMessage5(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("user32.dll", EntryPoint = "GetMenu", CharSet = CharSet.Auto)]
public static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "GetSubMenu", CharSet = CharSet.Auto)]
public static extern IntPtr GetSubMenu(IntPtr hWnd, int nPos);
[DllImport("user32.dll", EntryPoint = "GetMenuItemID", CharSet = CharSet.Auto)]
public static extern int GetMenuItemID(IntPtr hMenu, int nPos);
//Test used in mouse_event
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr GetMessageExtraInfo();
[DllImport("user32.dll")]
internal static extern bool GetCursorPos(ref Point lpPoint);
[DllImport("user32.dll")]
internal static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll", EntryPoint = "mouse_event", CharSet = CharSet.Auto)]
static extern void mouse_event(uint command, int x, int y, int dwdata, IntPtr dwExtraInfo);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint RegisterWindowMessage(string lpString);
[DllImport("oleacc.dll", PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern object ObjectFromLresult(UIntPtr lResult, [MarshalAs(UnmanagedType.LPStruct)] Guid refiid, IntPtr wParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);
public enum SendMessageTimeoutFlags :
uint
{
SMTO_NORMAL = 0x0000,
SMTO_BLOCK = 0x0001,
SMTO_ABORTIFHUNG = 0x0002,
SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
}
/// <summary>
/// Click left button on the Point(X, Y)
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public static void ClickOnPosition(int x, int y)
{
uint MOUSEEVENTF_LEFTDOWN = 0x0002;
uint MOUSEEVENTF_LEFTUP = 0x0004;
mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, GetMessageExtraInfo());
mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, GetMessageExtraInfo());
}
/// <summary>
/// Move Cursor
/// </summary>
/// <param name="x">X direction Increment</param>
/// <param name="y">Y direction Increment</param>
public static void MoveCursor(int x, int y)
{
uint MOUSEEVENTF_MOVE = 0x0001;
mouse_event(MOUSEEVENTF_MOVE, x, y, 0, GetMessageExtraInfo());
}
/// <summary>
/// Click on Current cursor position
/// </summary>
public static void ClickOnCurrentPosition()
{
try
{
System.Drawing.Point defPnt = new System.Drawing.Point();
GetCursorPos(ref defPnt);
ClickOnPosition(defPnt.X, defPnt.Y);
Thread.Sleep(1000);
}
catch { }
}
}