0

I am trying to get the hwnd of a child window(caption = "Reset") to apply in IsWindowVisible() function but the child window could not be found.

This is the code:

#include <iostream>
#include <windows.h>
using namespace std;

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{

    char class_name[100];
    char title[100];
    GetClassNameA(hwnd,class_name, sizeof(class_name));
    GetWindowTextA(hwnd,title,sizeof(title));
    cout <<"Window title: "<<title<<endl;
    cout <<"Class name  : "<<class_name<<endl;
    cout <<"hwnd        : " <<hwnd<<endl<<endl;

    return TRUE;
}


int main()
{
    HWND hwnd = ::FindWindowA("#32770",NULL);

    EnumChildWindows(hwnd,EnumWindowsProc,0);

    system("PAUSE");

    return 0;

}

There are a lots of window with the same classname #32770 (Dialog), also without title. After run the code, the result came out different types of window (with classname like WorkerW, IME, etc.).

The tree diagram get from Spy++ are like this:

...Window 00180726 "" #32770 (Dialog)

...Window 001F0962 "Reset" Button

I tried to find the child window if window title and window class(#32770) are included, it succeed.

My question is: How to find the child window (Reset) if we don't have a specific parent window? I tried apply EnumWindows, EnumChildWindows, FindWindows, FindWindowsEx in main() but still can't get what I expect.

Advance thanks for any kind of helps.

  • You can't use FindWindow(), that returns only the first match and the odds that it is the one you want are too low. Use EnumWindows() instead, in the callback use EnumChildWindows(). Still risky, "Reset" is a pretty popular button caption, further filtering by process ID (use GetWindowThreadProcessId) would be wise. – Hans Passant Nov 06 '19 at 08:57
  • I tried to use EnumWindows() but it included all the active and inactive windows. Is it possible to filter and only find the active window? I not sure how to use EnumChildWindows() in the callback, I'm new with all of these. Any guidance? – Joshua_0101 Nov 06 '19 at 09:42

1 Answers1

0

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

Ahmed Anter
  • 650
  • 4
  • 13
  • Is it depends on the mouse cursor? Not sure about how the Point works. – Joshua_0101 Nov 06 '19 at 09:33
  • your dialog pops up at the same or different position every time? – Ahmed Anter Nov 06 '19 at 09:37
  • The same position and it always set as top window. – Joshua_0101 Nov 06 '19 at 09:43
  • POINT pt={10,10}; where 10 ,10 is x and y from top left corner then call windowfrompoint(pt); no need for mouse at all – Ahmed Anter Nov 06 '19 at 09:44
  • The point is depends on the screen coordinates right? Because the position and size of the dialog are fixed at the center of screen. So the point should at center? – Joshua_0101 Nov 06 '19 at 09:55
  • But if the application used in different resolution of screen might caused it will not functioning well. – Joshua_0101 Nov 06 '19 at 10:06
  • call GetWindowRect(GetDesktopWindow(),&rct); then x=rct.right/2; y=rct.bottom/2; – Ahmed Anter Nov 06 '19 at 10:17
  • It works fine. But is there any way to retrieve the hwnd of 'Reset' button from the EnumChildWindows? I cannot find the method to get it, mostly just end in the EnumChildWindows stage. Maybe based on the caption Reset? – Joshua_0101 Nov 07 '19 at 01:35
  • do you know the button control ID? then you can use ::GetDlgItem() to get handle – Ahmed Anter Nov 07 '19 at 08:24
  • Yes, I can know the Process ID, but since all the child window shared the same Process ID and it could not get the exact Window Handle of the 'Reset' button. Can't it track by Window Name or the order of child window (1st, 2nd,..)? – Joshua_0101 Nov 07 '19 at 09:21
  • use spy++ to get Control ID for Reset button and use it with GetDlgItem(hdlg,id) – Ahmed Anter Nov 07 '19 at 09:42
  • I means can it be done by retrieve the data based on what we found from the EnumChildWindows? If use Spy++ to get the Control ID and apply into GetDlgItem() might not possible because the ID change everytimes after the application is closed. – Joshua_0101 Nov 07 '19 at 09:48
  • The control id should not change when you close the application it is design time value – Ahmed Anter Nov 07 '19 at 09:51
  • It changed for the software that I'm using :( I have checked by using Spy++. The Process ID and Thread ID will changed after closed and relaunch the software. But the both ID will be the same from Parent to Child to Child-Child Window when the software is running. – Joshua_0101 Nov 07 '19 at 10:08
  • you misunderstand Control ID is not Process ID or Thread ID. you will find get it using spy++ in window properties dialog https://learn.microsoft.com/en-us/visualstudio/debugger/general-tab-window-properties-dialog-box?view=vs-2019 – Ahmed Anter Nov 07 '19 at 10:14
  • Sorry for my misunderstanding. It works fine now. Thanks a lot! – Joshua_0101 Nov 07 '19 at 15:50