2

I am pretty new to the Win32API and trying to interact with other applications, but thought I would give this a try as a way to automate certain tasks.

I am wanting to be able to find a Windows Application Element and then be able to send it user interactions such as mouse click, right click, key press and so on.

Let's say for example I have a button. If I know what the text of the button is, then I want to search all active Applications for all elements of type "button" for that text. Maybe though it isn't a plain button, maybe it was an image that was made to look like a button. So we remove the type declaration and search for everything.

Once we find the title of the "right" application and which window the element is in, then in the future I want to be able to specify something like:

var handle = ReturnHandle("applicationTitle","ElementClass","Keyword");

Which would speed up accessing the handle, and then I believe I could send it an event using this solution: Simulating Key Press C#

I have below the code to find all open applications, but I am not sure how to iterate over all elements within them to write the ReturnHandle function. Any help would be appreciated.

private static void Main(string[] args)
{
    foreach (KeyValuePair<IntPtr, string> window in GetOpenWindows())
    {
        IntPtr handle = window.Key;
        var hwndChild = EnumAllWindows(handle, "ComboBox");
    }
}


public static IDictionary<HWND, string> GetOpenWindows()
{
    HWND shellWindow = GetShellWindow();
    Dictionary<HWND, string> windows = new Dictionary<HWND, string>();

    EnumWindows(delegate (HWND hWnd, int lParam)
    {
        if (hWnd == shellWindow) return true;
        if (!IsWindowVisible(hWnd)) return true;

        int length = GetWindowTextLength(hWnd);
        if (length == 0) return true;

        StringBuilder builder = new StringBuilder(length);
        GetWindowText(hWnd, builder, length + 1);

        windows[hWnd] = builder.ToString();
        return true;
    }, 0);

    return windows;
}

private delegate bool EnumWindowsProc(HWND hWnd, int lParam);

[DllImport("USER32.DLL")]
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);

[DllImport("USER32.DLL")]
private static extern int GetWindowText(HWND hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("USER32.DLL")]
private static extern int GetWindowTextLength(HWND hWnd);

[DllImport("USER32.DLL")]
private static extern bool IsWindowVisible(HWND hWnd);

[DllImport("USER32.DLL")]
private static extern IntPtr GetShellWindow();
Alan
  • 2,046
  • 2
  • 20
  • 43
  • Once you get the window handle, enumerate all its child windows. [How can I get the child windows of a window given its HWND?](https://stackoverflow.com/a/28055461) – 001 Feb 03 '21 at 22:21
  • Use the System.Windows.Automation namespace. – Hans Passant Feb 03 '21 at 22:26
  • If you're interacting with the standard Windows controls, consider utilities like [AutoHotKey](http://autohotkey.com). – Dour High Arch Feb 03 '21 at 22:48

0 Answers0