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

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.

Related

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.

Adding CDialog inside CDockablePane and application becomes unresponsive

I want to add a CDialog control inside CDockablePane. When I use CDialog.DoModal() to display the dialog window, it makes the MFC application unresponsive and waiting for the CDialog result.
How can I make the application display the dialog and continue running without waiting for the CDialog result?
You cannot use DoModal to display the dialog. That displays a modal dialog, which prevents interaction with any other windows in your application until the dialog has been dismissed. Just like a message box does.
To display a non-modal dialog, you call the Create member function. Use the instance of your CDockablePane as the dialog's parent. You will also need to ensure that the dialog itself is a child window, without a border.
It might be easier to use a class derived from CFormView or CPaneDialog.

How to use SendMessage to pass values from child dialog box(modeless) to parent dialog box?

Suppose I opened a popup from parent window I have calculated some calculation on child window while submitting the value from child window I need to display the calculated value of child window to parent window textbox when I click a button in the pop up window.
Option 1:
You can pass the parent window handle to your child window in the constructor and use it to call SendMessage. However since Send Message is a blocking call you can consider using Post Message Instead.
Option 2:
void CModeLess::OnOK()
{
//Get the value from the control
m_ctrlEdit.GetWindowText(strVal);
m_Parent->SetName(strVal);
DestroyWindow();
}
Pass the parent dialog pointer while constructing the child dialog. And use it to call your member function.
Warning:
When you close the child window you should make sure to delete the memory of the child window pointer since you have mentioned the dialog is a modless. You need to inform the parent dialog that the child window is gone for that you need to use postmessage.
void CModeLess::PostNcDestroy()
{
CDialog::PostNcDestroy();
GetParent()->PostMessage(WM_MODELESS_CLOSED,0,0);
delete this;
}
Your child window is associated with a class.
Add a method to the child window's class that will return the calculated value. i.e. ChildwindowClass::GetCalculatedValue()
Then your parent window can use that method to get the value.
I'm assuming that you're using CDialog::DoModal to show the child window. Since DoModal is a blocking function, it's easy to know when the child window is done.
Use PostMessage to inform the parent dialog that the child dialog is done its calculation and that GetCalculatedValue can be used. Or you can pass the calculated value to the parent in PostMessage.
If the calculation is going to take a long time, use a worker thread to do it and PostMessage the result, otherwise you'll freeze your UI.

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.

Parent notification in MFC Dialog

I have a first dialog with a simple button on it and while clicking the button, a second dialog is created using CDialog::Create(IDD,this). I would like the parent to be notified when the second dialog is destroyed but without adding any code to the second dialog i.e., without adding a m_pParent->Notify() line in OnDestroy method.
I have tried OnParentNotify, PreTranslateMessage, SubclassWindow in the parent dialog with no success. I have not used the WS_CHILD style for the second dialog. Any idea?
To complete: in fact, I have a ComboBox derived class (but the issue is the same with buttons) and I'm displaying a modeless Dialog instead of displaying the listbox. But I would like the control to be as generic as possible so that any modeless dialog could be used. That's why I do not want to add a specific notification in the second dialog. If I'm obliged, I will use this trick but I asked for a more generic solution. PreTranslateMessage only catches WM_PAINT, WM_NCMOUSELEAVE and WM_NCMOUSEMOVE.
Use a base class and have your parent refer to the modeless child by base class only. In the base PostNcDestroy have it post to the parent.
It doesn't make sense to have the parent do a bunch of filtering / spying on all messages. It does make sense to implement behavior in a base class that you want to have common to all the different future flavors you might have of the modeless child.
OnParentNotify() is not called since dialog2 is not a child of dialog1.
PreTranslateMessage() should help here (although I don't like this bullet). The trick is that a modeless dialog doesn't destroy itself when it's closed. If you want the dialog to die, it must call DestroyWindow() when it closes, such in an OnCancel() override.
Of course, the first thing that comes to mind is t wonder why you don't want to add custom notification in your modeless dialog code.
EDIT: Another method would consist in installing a message hook (for the current thread, Not the whole system!). This would help you catch all messages for all windows associated to the same thread as dialog1. See SetWindowsHookEx()
How about posting a main parent form event to the message queue?