Last-Modified: Wed, 29 Jul 2026 08:58:19 GMT
Expires: Sat, 26 Jul 2036 08:58:19 GMT
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TestStack.White.InputDevices;
using TestStack.White.WindowsAPI;
namespace Tango.BuildExtensions
{
public class WindowInfo
{
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern int SendMessage(IntPtr hwndControl, uint Msg, int wParam, StringBuilder strBuffer); // get text
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
static extern int SendMessage(IntPtr hwndControl, uint Msg, int wParam, int lParam); // text length
[DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr SendMessageTimeout(IntPtr windowHandle, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags flags, uint timeout, out IntPtr result);
[Flags]
enum SendMessageTimeoutFlags : uint
{
SMTO_NORMAL = 0x0,
SMTO_BLOCK = 0x1,
SMTO_ABORTIFHUNG = 0x2,
SMTO_NOTIMEOUTIFNOTHUNG = 0x8,
SMTO_ERRORONEXIT = 0x20
}
private static List<IntPtr> GetAllChildrenHandles(IntPtr hParent, int maxCount)
{
List<IntPtr> result = new List<IntPtr>();
int ct = 0;
IntPtr prevChild = IntPtr.Zero;
IntPtr currChild = IntPtr.Zero;
while (true && ct < maxCount)
{
Debug.WriteLine("FindWindowEx: " + hParent);
currChild = FindWindowEx(hParent, prevChild, null, null);
if (currChild == IntPtr.Zero) break;
result.Add(currChild);
prevChild = currChild;
++ct;
}
return result;
}
private static int GetCaptionTextLength(IntPtr hTextBox)
{
// helper for GetCaptionText
uint WM_GETTEXTLENGTH = 0x000E;
IntPtr result = IntPtr.Zero;
SendMessageTimeout(hTextBox, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out result);
return (int)result;
}
private static string GetCaptionText(IntPtr hTextBox)
{
uint WM_GETTEXT = 0x000D;
int len = GetCaptionTextLength(hTextBox);
if (len <= 0) return null; // no text. consider empty string instead.
StringBuilder sb = new StringBuilder(len + 1);
SendMessage(hTextBox, WM_GETTEXT, len + 1, sb);
return sb.ToString();
}
public IntPtr Handle { get; set; }
public int Level { get; set; }
public String Caption { get; set; }
public WindowInfo Parent { get; set; }
public List<WindowInfo> Children { get; set; }
public WindowInfo()
{
Children = new List<WindowInfo>();
}
public void SetActive()
{
SetForegroundWindow(Handle);
}
public void PressKey(KeyboardInput.SpecialKeys key)
{
SetActive();
Keyboard.Instance.PressSpecialKey(key);
}
public override string ToString()
{
return Caption;
}
public static List<WindowInfo> GetAllWindows()
{
List<WindowInfo> windows = new List<WindowInfo>();
IntPtr hDesktop = GetDesktopWindow();
WindowInfo desktop = new WindowInfo();
desktop.Handle = hDesktop;
desktop.Level = 0;
desktop.Caption = "(Desktop)";
desktop.Parent = null;
windows.Add(desktop);
try
{
FillWindows(desktop, desktop.Children);
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
return windows;
}
private static void FlattenWindows(WindowInfo parent, List<WindowInfo> windows)
{
windows.Add(parent);
foreach (var window in parent.Children)
{
windows.Add(window);
FlattenWindows(window, windows);
}
}
public static WindowInfo GetWindow(String title)
{
var windows = GetAllWindows();
List<WindowInfo> flatList = new List<WindowInfo>();
FlattenWindows(windows.First(), flatList);
return flatList.FirstOrDefault(x => x.Caption == title);
}
private static void FillWindows(WindowInfo parent, List<WindowInfo> windows)
{
foreach (var handle in GetAllChildrenHandles(parent.Handle, 5000))
{
WindowInfo child = new WindowInfo();
child.Handle = handle;
child.Level = parent.Level + 1;
child.Caption = GetCaptionText(handle);
child.Parent = parent;
if (child.Caption != null)
{
Debug.WriteLine(parent.Caption + " | " + child.Caption);
windows.Add(child);
}
FillWindows(child, child.Children);
}
}
}
}