How to Get the Child Windows of a Window Given Its Hwnd

How can I get the child windows of a window given its HWND?

I've found the best solution to be Managed WindowsAPI. It had a CrossHair control that could be used to select a window(not part of the question), and a method AllChildWindows to get all child windows which likely wrapped the EnumChildWindows function. Better not to reinvent the wheel.

Get children windows of window by handle or pid

Clearly you are not actually talking about child windows, EnumWindows() doesn't enumerate them. These are surely owned windows, they stay on top of their owner and get minimized when the owner is minimized. Used for tool windows and dialogs, like Paint.NET uses. There is no dedicated winapi function to enumerate owned windows.

You can make it more efficient. Enumerate the threads in the process, use Process.Threads. Then for each thread use EnumThreadWindows(). GetWindowLongPtr() with GWLP_HWNDPARENT returns the handle of the owner, non-zero if it is an owned window.

How to find a child HWND of a child window of a child window (3 levels deep) with Win32 API?

You have to call FindWindowEx() for each child level that you want to go down, specifying the HWND found in the previous level as the parent, eg:

HWND hWnd = FindWindow("XYZ_Widget_1", NULL);
if (hWnd != NULL)
{
hWnd = FindWindowEx(hWnd, NULL, "XYZ_Widget_0", NULL);
if (hWnd != NULL)
{
hWnd = FindWindowEx(hWnd, NULL, "XYZ_Renderer", NULL);
// and so on...
}
}

There is no simplier way to do it. To simplify your code, you could write your own function that accepts a path of class/window names as input, looping through it calling FindWindow/Ex() for each leg as needed.

Obtain child window from Process.MainWindowHandle

I didn't found it because it creates multiple windows and some of them are hidden (including "main window"). Here is screenshot:

Sample Image

So I just enum every window of a process, find TFormPassDialog and then everything works fine. Here is my code:

class ExeLockFounder
{
const uint WM_SETTEXT = 0x000C;
delegate bool EnumDelegate(IntPtr hWnd, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string lpszWindow);

[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumDelegate lpfn, IntPtr lParam);

[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);

private static IntPtr GetWindowByClassName(IEnumerable<IntPtr> windows, string className)
{
foreach (var window in windows)
{
var sb = new StringBuilder(256);
GetClassName(window, sb, sb.Capacity);
if (sb.ToString() == className)
return window;
}
return IntPtr.Zero;
}

static IEnumerable<IntPtr> EnumerateProcessWindowHandles(Process process)
{
var handles = new List<IntPtr>();
foreach (ProcessThread thread in process.Threads)
EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
return handles;
}

private readonly IntPtr _editHandle;

public ExeLockFounder()
{
var processes = Process.GetProcessesByName("Setup");
var proc = Array.Find(processes, x => string.Equals(x.MainWindowTitle, "ExeLock", StringComparison.OrdinalIgnoreCase));

var windows = EnumerateProcessWindowHandles(proc);
var hWnd = GetWindowByClassName(windows, "TFormPassDialog");
_editHandle = FindWindowEx(hWnd, IntPtr.Zero, "TEdit", null);
}

public void SendText(string message)
{
SendMessage(_editHandle, WM_SETTEXT, IntPtr.Zero, message);
}
}

Unable to find child window of a parent window that don't have WindowName with ClassName #32770 (Dialog)

You can use WindowFromPoint to get parent dialog if you know its position then call EnumChildWindows to get its child

Find out if a window has a child window

The simplest way to determine whether or not a window has any children is to call GetWindow passing GW_CHILD.

function HasChildren(Window: HWND): Boolean;
begin
Result := GetWindow(Window, GW_CHILD)<>0;
end;

Get handle of child window to postmessage in C#

OK i found solution thanks to Oguz Ozgul.
I did it by FindWindowEx like :

 IntPtr child = FindWindowEx(hwnd10, IntPtr.Zero, "TscShellAxHostClass", null);
//check if window is caught
if(child!=IntPtr.Zero)
{
Console.WriteLine("Findow TscShellAxHostClass found!!!");

child = FindWindowEx(child, IntPtr.Zero, "ATL:00007FFC92EAF400", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow ATL:00007FFC92EAF400 found!!!");

child = FindWindowEx(child, IntPtr.Zero, "UIMainClass", null);
if (child != IntPtr.Zero)
{

Console.WriteLine("Findow UIMainClass found!!!");
child = FindWindowEx(child, IntPtr.Zero, "UIContainerClass", null);
if (child != IntPtr.Zero)
{

Console.WriteLine("Findow UIContainerClass found!!!");
child = FindWindowEx(child, IntPtr.Zero, "IHWindowClass", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow IHWindowClass found!!!");
}
}
}
}
}

Get child window handles in C#

Take a look at EnumChildWindows (pinvoke.net)

How to get a list of Window Rectangle from EnumChildWindow and store them?

For your first question, you may have a look here.

For your second question, you may define a structure with the fields you need, e.g.

#include <iostream>
#include <windows.h>
#include <vector>

struct MyWindow {
HWND handle_;
std::string name_;
std::string text_;
RECT rect_;
MyWindow(HWND handle, const std::string& name, const std::string& text, RECT rect): handle_{handle}, name_{name}, text_{text}, rect_{rect}{}
};

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
char name[100];
char text[100];
RECT rect{0};

GetClassNameA(hwnd,name, sizeof(name));
GetWindowTextA(hwnd,text,sizeof(text));
GetWindowRect(hwnd, &rect);

std::vector<MyWindow>* myVec = reinterpret_cast<std::vector<MyWindow>*>(lParam);

if (myVec) {
myVec->emplace_back(MyWindow(hwnd, std::string(name), std::string(text), rect));
} else {
// Pointer to vector is NULL, handle accordingly
return FALSE;
}

return TRUE;
}

int main()
{
POINT pt;
Sleep(3000);

std::vector<MyWindow> myChildWindows;

GetCursorPos(&pt);
HWND hwnd = WindowFromPoint(pt);
HWND hwndParent = GetParent(hwnd);

EnumChildWindows(hwndParent, EnumWindowsProc, reinterpret_cast<LPARAM>(&myChildWindows));

for (const auto & childWindow: myChildWindows) {
std::cout <<"Window name : "<< childWindow.name_ << std::endl;
std::cout <<"Class name : "<< childWindow.text_<< std::endl;
std::cout <<"hwnd : "<< childWindow.handle_<< std::endl;
std::cout << "Rect: " << childWindow.rect_.left << "/" << childWindow.rect_.right << std::endl;
std::cout << "---" << std::endl;
}

system("PAUSE");
return 0;
}

EDIT

I added a bit more code and explanation. This example should compile and run just fine.

std::vector is a sequence container that encapsulates dynamic size arrays 1.

When you declare myChildWindows in the main function, it is initialized to an empty vector, that can contain Objects of Type MyWindow. You can add and remove objects to that vector dynamically, i.e. you do not have to specify the size of the vector at compile time, like for example with an array. We then pass the pointer to this vector to your callback EnumWindowsProc. In this callback, we use this pointer to add Objects of type MyWindow to the vector. When EnumChildWindows returns, we can have a look at our vector by printing every object contained in the vector.



Related Topics



Leave a reply



Submit