Know when a child popup dialog is opened
-
See the
hwndParent
parameter at FindWindowEx function (Windows)[^]:Quote:
If hwndParent is NULL, the function uses the desktop window as the parent window. The function searches among windows that are child windows of the desktop.
You did not show us the full
Create
call but if you have passedCDialogBar
or any other window of your application as parent you must also pass it toFindWindowEx
(usingthis
for theCDialogBar
here):CWnd* pWnd = FindWindowEx(this->GetSafeHwnd(), NULL, _T("Dialog"), NULL);
But you should think about using a member variable. The only thing to do then is clearing the pointer when the dialog is closed. Otherwise you have to check for existance also in your
SomeButton
function to avoid creating multiple instances of your dialog.The creation of CMyDialog is:
pMyDialog->Create(CMyDialog::IDD, this);
I will try your advice, I hope to work. "But you should think about using a member variable. The only thing to do then is clearing the pointer when the dialog is closed. Otherwise you have to check for existance also in your SomeButton function to avoid creating multiple instances of your dialog." The CMyDialog could have only one instance, so, there is no problem with that.
-
The creation of CMyDialog is:
pMyDialog->Create(CMyDialog::IDD, this);
I will try your advice, I hope to work. "But you should think about using a member variable. The only thing to do then is clearing the pointer when the dialog is closed. Otherwise you have to check for existance also in your SomeButton function to avoid creating multiple instances of your dialog." The CMyDialog could have only one instance, so, there is no problem with that.
Flaviu2 wrote:
The CMyDialog could have only one instance, so, there is no problem with that.
How do you know that? If
CDialogBar::SomeButton
is called again (the name indicates that it requires only a mouse click), you would have multiple instances. When using a member variable you could then activate the existing dialog instead of creating a new one. -
Hi all of you. I have a dialogbar from where I open a popup dialog, let say
CMyDialog
, but it is opened in non modal way, dynamically created:void CDialogBar::SomeButton()
{
CMyDialog* pDialog = new CMyDialog;
pDialog->Create(...);
}From that dialogbar, it is possible to know if that
CMyDialog
is opened ?void CDialogBar::OtherButton()
{
CWnd* pWnd = FindWindowEx(NULL, NULL, _T("Dialog"), NULL);
ASSERT(NULL != pWnd);
}but the
pWnd
is always NULL, even whenCMyDialog
is open ... How can I know for sure if that CMyDialog is opened, without makingpDialog
as member variable ofCDialogbar
?Flaviu2 wrote:
CWnd* pWnd = FindWindowEx(NULL, NULL, _T("Dialog"), NULL);
Shouldn't the third parameter to
FindWindowEx()
be#32770
?"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
-
Flaviu2 wrote:
CWnd* pWnd = FindWindowEx(NULL, NULL, _T("Dialog"), NULL);
Shouldn't the third parameter to
FindWindowEx()
be#32770
?"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
-
I have try also this:
CWnd\* pWnd = FindWindowEx(GetSafeHwnd(), NULL, \_T("#32770"), NULL); TRACE(">>>%p\\t%d\\n", pWnd, pWnd->GetSafeHwnd());
and the result is
>>>00000000 0
Strange ... I guess that only member variable are safe ...
Flaviu2 wrote:
I have try also this:
CWnd* pWnd = FindWindowEx(GetSafeHwnd(), NULL, _T("#32770"), NULL);
TRACE(">>>%p\t%d\n", pWnd, pWnd->GetSafeHwnd());GetSafeHwnd() returns the window handle (HWND), not the CWnd* pointer. So the result of FindWindowEx() as well as its handle being "0" is obvious!
-
Flaviu2 wrote:
I have try also this:
CWnd* pWnd = FindWindowEx(GetSafeHwnd(), NULL, _T("#32770"), NULL);
TRACE(">>>%p\t%d\n", pWnd, pWnd->GetSafeHwnd());GetSafeHwnd() returns the window handle (HWND), not the CWnd* pointer. So the result of FindWindowEx() as well as its handle being "0" is obvious!
-
Flaviu2 wrote:
The CMyDialog could have only one instance, so, there is no problem with that.
How do you know that? If
CDialogBar::SomeButton
is called again (the name indicates that it requires only a mouse click), you would have multiple instances. When using a member variable you could then activate the existing dialog instead of creating a new one. -
The CMyDialog are closed when he lost the focus, so, there is no way to be two (or more) instances.
Quote:
The CMyDialog are closed when he lost the focus
OK. So it is some kind of popup or tooltip window. But the window will loose it's focus when clicking another button (as indicated by your
CDialogBar::OtherButton()
). I'm not sure what happens before. So it might be that the window is already destroyed when trying to find the handle. Even if not, you should not use the handle because the window would be destroyed shortly thereafter. -
Hi all of you. I have a dialogbar from where I open a popup dialog, let say
CMyDialog
, but it is opened in non modal way, dynamically created:void CDialogBar::SomeButton()
{
CMyDialog* pDialog = new CMyDialog;
pDialog->Create(...);
}From that dialogbar, it is possible to know if that
CMyDialog
is opened ?void CDialogBar::OtherButton()
{
CWnd* pWnd = FindWindowEx(NULL, NULL, _T("Dialog"), NULL);
ASSERT(NULL != pWnd);
}but the
pWnd
is always NULL, even whenCMyDialog
is open ... How can I know for sure if that CMyDialog is opened, without makingpDialog
as member variable ofCDialogbar
?Can I say I have never seen such a ridiculously convoluted way to do this. Doing an atomic string search is first slow, and secondly mildly dangerous and unreliable. There are two MUCH SAFER standard windows ways to do such a thing and both require you to put code on the dialog handler 1.) In the dialog itself on the WM_INITDIALOG message either post back a message dialog is open, or even just set a global variable to the dialog window. In the WM_DESTROY of the dialog post back a closed message or just zero the global variable to the dialog window. Something like this is probably the simplest for you
HWND MyDialog = 0; // You can make this global or declare it extern on your .h or have a function to access it.
// Your dialog message handler
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
...case WM\_INITDIALOG: ... MyDialog = hDlg; // Hold the handle to yourself for others break; case WM\_DESTROY: ... MyDialog = 0; // Dialog about to destroy stop others accessing break; ...
2.) In the dialog handler itself respond back to a user WM_APP message with your handle. The message will be enumerated to all windows in your application and you will be the only responder.
// Your dialog message handler
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
...case WM\_APP + 100: // Some user app number ... return (hDlg); // Return your handle in response to the message ...
Method 1 you simply need to look at the global variable MyDialog to know if the dialog is open or not and what it's handle is. Method 2 you use SendMessage(0, WM_APP+100, 0, 0) and if your dialog is open you will get a response back which will the handle to your dialog. If you get 0 back the dialog is not open because no other window will respond to WM_APP + 100.
In vino veritas
-
Can I say I have never seen such a ridiculously convoluted way to do this. Doing an atomic string search is first slow, and secondly mildly dangerous and unreliable. There are two MUCH SAFER standard windows ways to do such a thing and both require you to put code on the dialog handler 1.) In the dialog itself on the WM_INITDIALOG message either post back a message dialog is open, or even just set a global variable to the dialog window. In the WM_DESTROY of the dialog post back a closed message or just zero the global variable to the dialog window. Something like this is probably the simplest for you
HWND MyDialog = 0; // You can make this global or declare it extern on your .h or have a function to access it.
// Your dialog message handler
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
...case WM\_INITDIALOG: ... MyDialog = hDlg; // Hold the handle to yourself for others break; case WM\_DESTROY: ... MyDialog = 0; // Dialog about to destroy stop others accessing break; ...
2.) In the dialog handler itself respond back to a user WM_APP message with your handle. The message will be enumerated to all windows in your application and you will be the only responder.
// Your dialog message handler
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
...case WM\_APP + 100: // Some user app number ... return (hDlg); // Return your handle in response to the message ...
Method 1 you simply need to look at the global variable MyDialog to know if the dialog is open or not and what it's handle is. Method 2 you use SendMessage(0, WM_APP+100, 0, 0) and if your dialog is open you will get a response back which will the handle to your dialog. If you get 0 back the dialog is not open because no other window will respond to WM_APP + 100.
In vino veritas