Question

I am creating a function to find specific windows given a window hierarchy as follows:

protected bool MapWindowHierarchy (ATS.Library.Window window)
{
    bool result = false;
    List<Process> processes = null;

    processes = GetProcesses().ToList();

    processes.ForEach
    (
        process =>
        {
            if (process.MainWindowHandle == window.Handle)
            {
                // Populate window properties.
                //  Get child windows with filled properties.
            }
        }
    );

    return (result);
}

protected bool MapWindowHierarchy (List<ATS.Library.Window> windows)
{
    return (windows.All(window => this.MapWindowHierarchy(window)));
}

public sealed class Window
{
    public IntPtr Handle { get; set; }
    public string Class { get; set; }
    public Rectangle Bounds { get; set; }
    public Win32Api.User32.ShowWindowCommands WindowState { get; set; }
    public string Caption { get; set; }
    public int Style { get; set; }
    public List<ATS.Library.Window> Windows { get; set; }

    public void PopulateFromHandle(IntPtr hWnd)
    {
        // Populate above properties using Win32 API.
    }
}

This is just rough code but the objective is to create a heirarchy using the [Window] class and see if the actual hierarchy using [EnumChildWindows] matches. This apparently works fine but I came across this SO question, Hans Passant's comment "Every unique window in a desktop session must have a unique Windows class name", I wasn;t sure how to interpret it (see image below for multiple windows with the same class name). Perhaps what he mentions only applies to managed code (WinForms, WPF, etc.).

Furthermore, I am not sure how to retrieve the class names and text of the windows given I have the handle (hWnd) like Spy++ does (see image below). Notice how the text is retrieved in the tree view but not the [Find Window] dialog.

Spy++

Question:

  • Should I be worried about Han's comment since I am only targeting native apps?
  • How to get the class name given a window's handle?
  • How to get the window text given a window's handle (like in the image)?
Was it helpful?

Solution

Not sure why you have to worry. But yes, these "Button" controls you highlighted in your screenshot are not unique windows. They all look the same and behave the exact same way when you click them. The only difference is that their text "property" is different. So they are therefore the exact same window "class". With "property" and "class" in double-quotes since the winapi is a C api and the C language doesn't support classes or properties.

A window class pre-selects a bunch of properties for a window, you can see them back in the WNDCLASSEX structure, the one you fill in before you call RegisterClassEx(). You then create windows from that, you pass the class name in the CreateWindowEx() winapi call. The scheme was designed to make it easy to create windows that are similar, much like you use a class in C# to create objects that are similar. But can still have their own Text property. And their own Click event handler.

You get the window class name from a handle with the GetClassName() winapi function.

You get the text "property" from a handle with the GetWindowText() winapi function. GetWindowTextLength() tells you how large a string buffer you need to pass to GetWindowText().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top