Closing Parent window using child window.! - mfc

I am new to MFC(vc++) and interested in learning it.I am having a parent window and a child window,I want to close both parent and child window, when a button is pressed from child window.Please help me in this.
thanks a lot in advance. :)

The child window is destroyed when the parent is destroyed. This is the normal behavior
If you call
GetParent()->DestroyWindow();
from the child, the parent gets destroyed and the child to. But take, care. A modal dialog is not closed with DestroyWindow. EndDIalog is the correct way. Also message and command Routing makes is unnecessary to handle the destruytion from the parent from a handler within the child.
As already written: Show us more of your code and your problem.

DoModal() will return either IDOK or IDCANCEL based upon the button clicked. So use it.
For example: http://msdn.microsoft.com/en-us/library/619z63f5.aspx
Note: In MFC only the identifier of the class will begin with 'C' not the object.

Try this:
AfxGetApp()->GetMainWnd()->PostMessage(WM_CLOSE);

Related

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.

Setting focus to the parent window in the OnShowWindow of the child window doesn't work

Generally I have some button that opens child window and the second press on this button should close it. I use a touch screen.
The problem is when I try to press the button for closing the child window, it is not pressed the first time, so I need another click.
In order to fix this I am trying to return the focus to the parent window after the child window is opened.
I register the OnShowWindow message and call SetFocus on the parent window:
void CFlashGuidanceSteps::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow, nStatus);
GetParent()->SetFocus();
}
While the function is called (I can see it in debugger), the focus is not returned to the parent window.
However, it works with the OnSetFocus event:
void CFlashGuidanceSteps::OnSetFocus(CWnd* pOldWnd)
{
CDialog::OnSetFocus(pOldWnd);
GetParent()->SetFocus();
}
Why is the focus is not retained with the OnShowWindow event?
The explanation
The usual rule in MFC is that OnXxx functions are called in response to similarly named window messages, e.g. WM_Xxx. So OnShowWindow would be called in response to WM_SHOWWINDOW.
And according to the documentation, WM_SHOWWINDOW is
Sent to a window when the window is about to be hidden or shown.
That means it is sent before the window is actually shown. So when you set the focus to the parent window inside of the OnShowWindow function, nothing actually happens because the parent window already has the focus. Then, after OnShowWindow finishes running, the child window is displayed and demands the focus. It is as if you never made any attempt to change the focus.
By contrast, OnSetFocus, which corresponds to WM_SETFOCUS, is not called until after the window has gained the focus. So when you reassign the focus here, it works because the child window doesn't steal the focus back.
The better idea
That explains the behavior you are seeing, and as you know, things work fine when you adjust the focus in OnSetFocus. But this really isn't the best way of solving the problem.
Manually changing the focus when a window gets and/or loses the focus is approaching the problem the wrong way around, and generally error-prone. You'll get all kinds of focus-related bugs that are difficult to debug. You are better off looking for ways to prevent the focus from changing when you don't want it to.
It sounds to me like you want to prevent the child window from getting the focus when it is created. And there is a way to do precisely that.
When you display the child window, presumably by calling the ShowWindow function or its moral equivalent in MFC, you should pass the SW_SHOWNA flag. That causes the window to be shown without activating it (i.e., granting it the focus).

After changing the parent of a child window with SetParent, the child window still sends notification to the old parent [duplicate]

I have an edit control. In the parent window I'm listening a WM_COMMAND message. But my control doesn't send it on change. Moreover, when I'm watching messages with Spy I can see only different keyboard messages on the edit control itself and the only message in the main parent window is WM_CTLCOLOREDIT.
P.S.: The only interesting thing I'm doing - I'm creating an edit with HWND_MESSAGE parent and assign a parent later with SetParent();
For an edit control, notifications are sent to the original parent of the control. That is, in your case, the message only window.
In a comment to a similar question Raymond Chen says:
Many controls cache the original parent. Not much you can do about it.
You may be best postponing creation of the edit control until you have created its parent.

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.

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?