Unable to get hwnd of button inside a tab dialog - MFC

I am working on getting the hwnd by using the mouse cursor pointing on button/statictext. The problem is I cannot reach the button/statictext which is inside a tab dialog.

I used Spy++ to get the hierarchy, there are 3 layers to reach the desired button. MainWindow (#32770) - Tab1 (#32770) - Btn1 (Button). It shows that Tab1 is not parented to SysTabControl32 and have the same parent window with SysTabControl32.

Instead of getting the Btn1, I always get SysTabControl32, which has the same hierarchy level with Tab1, means that I only can reach the SysTabControl32 but not the Tab1.

If I used WindowFromPoint and point my mouse on Btn1, I will get SysTabControl32; using ChildWindowFromPoint, I will get 0 as return value; using RealChildWindowFromPoint, I will get SysTabControl32.

Spy++ only can detect MainWindow, SysTabControl32 and Tab1 but it cannot detect Btn1. I can get all the child windows by using EnumChildWindow but the ...FromPoint function still cannot find Tab1 and those child windows. Also, Spy++ is able to highlight Btn1 after I "Highlight" it but if I use 'Find Window' function in Spy++, Btn1 cannot be detected.

Is it the reason is the overlapping of sibling windows? Does anyone know what is the cause of this situation and how to solve it? Please help..Thanks
Last edited on
The problem is I cannot reach the button/statictext which is inside a tab dialog.

To get childs of a dialog you are supposed to use GetDlgItem function
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdlgitem

I can get all the child windows by using EnumChildWindow

Good, EnumChildWindow, will do the work too, but unlike GetDlgItem which gets you single control, the EnumChildWindow let's you do stuff on all child windows, I recommend you to use GetDlgItem to get a handle to button.

Is it the reason is the overlapping of sibling windows?

surely not.

If I used WindowFromPoint..

that doesn't sound as good design for your issue, just use GetDlgItem

Note: I'm not MFC expert, my sugesstions here are based on Win32, and should work just fine.

edit: the MFC dialog in guestion has a mehotd called GetDlgItem so you may use that instead of winapi version.
Last edited on
Hi malibor,

Thank you so much for the information. I'm a beginner in MFC and I'm not sure how to implement GetDlgItem in my MFC application because it consists of many others function and cpp files. Does it has any simple C++ code that I can try and test run in console before I apply it into MFC?

Below is the code that I have tried
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<windows.h>
#include<iostream>
using namespace std;

int main() {

		POINT pt;
		Sleep(3000);
		GetCursorPos(&pt);

		HWND hWnd = WindowFromPoint(pt);
		HWND hWndParent = GetParent(hWnd);
		MapWindowPoints(NULL, hWndParent, &pt, 1);
		HWND hWndChild = RealChildWindowFromPoint(hWndParent,pt);

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

		system("PAUSE");
		return 0;

}
Last edited on
Ok, I did a quick search on msdn an figured out, CDialog class inherits from CWnd which has a virtual base method Cwnd::GetDlgItem

reference:
https://docs.microsoft.com/en-us/cpp/mfc/reference/cwnd-class?view=vs-2019#getdlgitem

this is all you need, you should take a look at memory template to find out control ID which you pass into the Cwnd::GetDlgItem

then here is pseudo code:

1
2
3
CDialog dlg("my_dialog_template", nullptr); // Constructs a CDialog object from template.
CWnd* btn = dlg.GetDlgItem(IDOK); // get pointer to ie. OK button
HWND hButton = btn->GetSafeHwnd(); // get handle to button 


this is how to do it, but I guess the dialog you are talking about isn't created by you?
well in that case you don't know control ID (and you should not know it) and what that mean is you need to obtain this info somehow because template most likely isn't open source, here are few suggestions how to do it:

1
2
3
4
CDialog::GetDefID
CDialog::NextDlgCtrl
CDialog::GotoDlgCtrl
CWnd::GetFocus

for description of these see:
https://docs.microsoft.com/en-us/cpp/mfc/reference/cdialog-class?view=vs-2019

OR
if you need a handle you would call below method, and the use C API to "hack the MFC dialog":
CWnd::GetSafeHwnd
see info here:
https://docs.microsoft.com/en-us/cpp/mfc/reference/cwnd-class?view=vs-2019#getsafehwnd

Below is the code that I have tried

No no, first the code isn't MFC, if you are using MFC then please avoid C style API, and use MFC functionality in a manner similar to my sample, and secondly, WindowFromPoint doesn't look like maintanable solution for MFC, and it isn't FMC code or style either.

Instead make use of CWnd::GetFocus on the dialog pointer/varaible to get focus to button, that should be better and it's MFC code too.

In your code, where is the dialog pointer you were talking about? or object variable? use that to get the handle.
for example:
HWND hDialog = dlg_pointer->GetSafeHwnd();

Does it has any simple C++ code that I can try and test run in console before I apply it into MFC?

I'm afraid not without googling out, but all information you need is really on msdn, you just need to take a read.

as I said I don't know MFC I just try to help you with this info here is from msdn, it's not that hard to understand. since MFC is just winapi and C++. known concepts. the rest belongs to reading the reference.


Last edited on
but I guess the dialog you are talking about isn't created by you?
where is the dialog pointer you were talking about? or object variable?


Yes, the dialog isn't created by me. I have to assume that I don't know any information of the dialog/application such as the ControlID, hWnd or ClassName. I only can get these information by using the application that currently I'm working on. Actually it just like I'm developing an add-on tools for the application, similar to Spy++.

Anyway, much appreciate those provided info. Will study and try to apply them successfully. Thanks!
Topic archived. No new replies allowed.