C++ MFC dialog not closing when parent closed - c++

I am a newbie and I want to learn but I can't find anything about this.
I attached a dialog to the parent. but, when I close the parent the dialog stays open.
the parent is an exe file that loads the dialog (DLL) and opens it (like a plugin).
how can I check if the parent closed then the dialog will be closed too?

When a window is about to be destroy , WM_DESTROY is sent to that window, you can add an event to the WM_DESTORY event on the parent Dialog, then on that function close the child dialog manually.

Related

Is there a way to get a notification when a dialog opens or closes?

I have to do modifications to a very old and complex MFC App.
At the moment there is the need to notify via an external interface when a dialog (no matter modal or nonmodal) is opened or closed and to count the opened dialogs.
To do this before every DoModal() and Create is no option because there are also DLLs involved that can open dialogs and cannot be changed.
So is there a way to be notified, if a dialog opens?
And is there a way to be notified, if a dialog is closed?
TIA Michael

open a dialog behind a modal dialog or after it is closed

I have an application which has several background tasks running in non-GUI threads which may time to time require some user interaction so they send signal to the main thread and the corresponding slot creates a dialog and shows it to the user. Meanwhile the task thread is waiting in a blocking event loop. Once the user answers the dialog and closes it, the task event loop is signaled to quit and the task resumes.
There is however a problem. In the GUI thread I can still use the application which time to time shows some modal dialogs. When there is a modal dialog already shown and then the background tasks requests another dialog to be opened, this task-related dialog is displayed in front of the modal dialog. But this new dialog is not modal and the modal dialog is hidden behind it. The non-modal one therefore is not responsive, the application feels like it got stuck.
My idea was to display the new dialog always behind the modal dialog, which I believe I can get with QApplication::activeModalWidget(). But I do not know how to do this. How can I show a dialog behind another dialog but still in front of the main window (which is a parent of both dialogs)? I tried to call QApplication::activeModalWidget()->activateWindow() after I show the non-modal one but his causes blinking of windows and moreover I can still click into the new non-modal dialog hiding the modal one. So this is not a perfect solution.
Or do you see any other solution?
Maybe I could implement a queue of dialogs, and once there is any modal dialog visible, then the new background task-related dialog would not be shown, only enqueued and shown once the modal dialog is closed. However this feels more fragile solution to me.
Any ideas?
UPDATE: I redefined the question by adding "or after it is closed" becasue this works for me too.
I found a solution which seems to work well and which shows the non-modal dialog only after the modal dialog is closed.
QWidget *nonModalDialog = ... // creates the non-modal dialog
nonModalDialog->setAttribute(Qt::WA_DeleteOnClose);
QWidget *modalDialog = qApp->activeModalWidget();
if (modalDialog == nullptr)
{
// no modal dialog, we can show the non-modal one now
dialog->show();
}
else
{
// we must wait until the modal one is closed
QObject::connect(modalDialog, &QWidget::destroyed, nonModalDialog, &QWidget::show);
}
This seems simple and robust.
I think you are looking for QWidget::raise(). You should be able to use QApplication::activeModalWidget()->raise() after calling dialog->show() on your non-modal dialog.
If you're getting into situations where you have multiple modal and non-modal dialogs, all launched in different order, this might not be enough to solve the problem. You might raise one modal dialog only to have others behind other non-modal dialogs and end up stuck again. You should consider keeping a reference to the collection of modal dialogs that are currently active so that you can make sure they are always on top of the non-modal dialogs.

In MFC Close only the Child Dialog, not the Parent

I'm a newcomer to MFC world. I need to have some dialog based operaion for an old application. There I'm having a trouble for an appraently obvious thing and that is I can't seem to find a way to close the child dialog (Modal) that I'm invoking from my parent (also a Modal). In all the ways I tried always both child and parent is getting closed at once.
Here is what I tried:
I've created a default MFC application in VS 2012 Professional
ParentDlg.cpp
void ParentDlg::OnBnClickedOk()
{
ChildDlg childDlg;
dialogOutput.DoModal();
CDialogEx::OnOK();
}
In my Child.cpp for a Close button (ID: IDCLOSE)
ChildDlg.cpp
void ChildDlg::OnBnClickedClose()
{
// TODO: Add your control notification handler code here
EndDialog(IDCLOSE);
}
But this is closing both the parent and child, but I need only the child dialog to be closed (Parent Dialog should remain open) as I'm clicking the 'Close' buton on the child dialog.
In short, I like to have the same behaviour of the default IDOK button of 'IDD_ABOUTBOX' dialog, which is also a Modal dialog and closes only the About Box when I click on the 'OK' button in it.
You should only place IDOK in the ID property of your close button. And only the child dialog will close. You should no longer create an event handler, and if you did, delete the event handler.

mfc How can Child dialog know if Parent dialog push "cancel" button?

I made Child dialog in Parent dialog's tab control like this.
dialog
Child dialog uses database, so it has to be "db.Close()" when I push Parent dialog's "cancel" button.
In this case, How can Child dialog know if Parent dialog push "cancel" button?
OR...
How can Child dialog know right before destroyed by Parent dialog?
1) You could make a message handler in child's class and send it a message from it's parrent.
2) Other way is to make a public method in child's class who clears the window when DB is closed. From the parent call this method on child's object.
The first is much better and much safer solution.

How can I minimize a child dialog to the task bar in an MFC application?

I open a child dialog from a parent dialog. Among the child dialog properties I enabled the "Minimize" property. But if click the "Minimize" button, then the child dialog minimizes to the left corner of the screen instead of the Windows task bar. How can I solve this?
Your child dialog must have an extended style containing WS_EX_APPWINDOW (in addition to being a top-level window).
If I remember correctly, the "child" dialog has to be a top-level dialog if you want it to have a presence on the taskbar.
In other words, when creating your child dialog set the parent to NULL or to GetDesktopWindow(). I guess it depends on how your child dialog is being created, though.
It would help if you included the code you're using to create the child dialog.