0

I'm trying to obtain the handle to a window whose class name unfortunately changes (not my process). Only the first part of the class name stays constant (Afx:ControlBar:). It's also not a top process but rather a subwindow of another window.

I know that for a full string match on the class name, I could use

var controlBar = FindWindowEx(_parentWindow, IntPtr.Zero, "Afx:ControlBar:ac39000", "");

And I also know that I could just iterate through all child windows of _parentWindow using the childAfter parameter of FindWindowEx, but I'm not sure how I'd get the className from the returned IntPtr object.

Is there an easy way to get the desired window handle from a known className substring?

emilaz
  • 1,722
  • 1
  • 15
  • 31
  • 3
    "but I'm not sure how I'd get the className from the returned IntPtr object" Given an `IntPtr` to a window handle, you can use the [GetClassName() API](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclassname) to get the class name. See [here](https://stackoverflow.com/a/20023047/2330053) for an example. – Idle_Mind Nov 21 '22 at 16:53
  • 3
    If you know the parent use `EnumChildWindows` to enumerate its children, otherwise `EnumWindows` to enumerate top-level windows and then enumerate the children. `GetClassName` to get the class of each window returned to the enumeration. – Jonathan Potter Nov 21 '22 at 20:19
  • thanks for the useful suggestions, I've posted the solution I found based on your answers – emilaz Nov 23 '22 at 20:04

1 Answers1

0

Based on the useful example referred to by @Idle_Mind in the comments, here's how I solved it using GetClassName().

private static string GetWindowClassName(IntPtr handle)
{
    var buffer = new StringBuilder(128);
    GetClassName(handle, buffer, buffer.Capacity);
    return buffer.ToString();
}

private IntPtr GetControlBar(IntPtr startPointer)
{
    while (true)
    {
        startPointer = FindWindowEx(_parentWindow, startPointer, null, "");
        var className = GetWindowClassName(startPointer);
        if (className.StartsWith("Afx:ControlBar")) return startPointer;
        // if we have iterated all windows,, break
        if (startPointer == IntPtr.Zero) break;
    }

    return IntPtr.Zero;
}
emilaz
  • 1,722
  • 1
  • 15
  • 31