-
May 20th, 2008, 07:25 PM
#1
MainFrame/ChildFrame
Is the MainFrame notified in any way that the child frame has been closed? The user clicked X?
Mike B
-
May 20th, 2008, 08:41 PM
#2
Re: MainFrame/ChildFrame
By default it doesn't (AFAIK), but that doesn't stop you from sending your own message from the child to the main frame.
-
May 20th, 2008, 09:50 PM
#3
Re: MainFrame/ChildFrame
the MDI child frames are actually managed by a MDICLIENT window that fills the client area of the MDI Frame window. The MFC MDI frame window class
creates this client window and sends/receives messages to/from it. There is not an MFC wrapper around the MDICLIENT window. I think Ajay's suggestion
is a good option.
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
May 21st, 2008, 04:36 AM
#4
Re: MainFrame/ChildFrame
Originally Posted by Arjay
By default it doesn't (AFAIK), but that doesn't stop you from sending your own message from the child to the main frame.
Thanks for the reply. I thought about sending my own messages, and tried it as well, but I want to send the HWND of the closing window to the main frame. I tried from the WM_CLOSE message handler of the child frame but at this point, isn't the HWND already invalid?
Hmmm, I will look at this again.
Mike Bujak
-
May 21st, 2008, 04:50 AM
#5
Re: MainFrame/ChildFrame
Hmmm, MainFrame not catching message:
Code:
//ChildFrame.h
const UINT MsgChildFrameClosing = ::RegisterWindowMessage(_T("MsgChildFrameClosing-{F9AF1A58-073D-4703-8E1C-45EC939FBA0A}"));
//ChildFrame.cpp
void ChildFrame::OnClose()
{
HWND hWnd = GetSafeHwnd();
GetParent()->SendMessage(MsgChildFrameClosing, 0, (LPARAM)hWnd);
CMDIChildWnd::OnClose();
}
// MainFrame.h
afx_msg LRESULT OnChildFrameClosing(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
//MainFrame.cpp
BEGIN_MESSAGE_MAP(MainFrame, CMDIFrameWnd)
ON_REGISTERED_MESSAGE(MsgChildFrameClosing, OnChildFrameClosing)
END_MESSAGE_MAP()
HWND MainFrame::CreateView(CRuntimeClass* pRuntime, BOOL maximized, BOOL show)
{
ChildFrame* pFrame = new ChildFrame();
CCreateContext context;
context.m_pCurrentDoc = NULL;
context.m_pNewViewClass = pRuntime;
context.m_pNewDocTemplate = NULL;
context.m_pLastView = GetActiveFrame()->GetActiveView();
if(!pFrame->LoadFrame(IDR_InformTYPE, WS_OVERLAPPEDWINDOW, this, &context))
return NULL;
pFrame->InitialUpdateFrame(NULL, show);
if(maximized)
pFrame->MDIMaximize();
else
CenterChildFrame(pFrame);
return pFrame->GetSafeHwnd();
}
LRESULT MainFrame::OnChildFrameClosing(WPARAM wParam, LPARAM lParam)
{
HWND hWnd = (HWND)lParam;
if(hWnd)
{
::AfxMessageBox(_T("ChildFrameClosing())"));
}
return (0);
}
From the code above:
1) I register a windows message.
2) I declared message handler in MainFrame
3) In the CreateView(...) I created the ChildFrame and set the MainFrame (this) as its parent.
4) I implement the handler fo the registered message.
Problem is, the MainFrame is not getting the message. Any ideas?
Question, even if it did get the message, would the HWND still be valid?
Mike B
-
May 21st, 2008, 10:56 AM
#6
Re: MainFrame/ChildFrame
There are a few options for doing this.
1. You do not need to register a windows message. Instead you would do the
following
a. Define a constant for the message
Code:
#define WM_MDI_CHILD_WINDOW_CLOSING (WM_APP + 1)
b. Your code in the main frame only changes for the message map implementation
Code:
//MainFrame.cpp
BEGIN_MESSAGE_MAP(MainFrame, CMDIFrameWnd)
ON_MESSAGE(WM_MDI_CHILD_WINDOW_CLOSING, OnChildFrameClosing)
END_MESSAGE_MAP()
c. in the child frame post or send a message using this constant
What do you mean by "would the HWND still be valid?"
The hwnd will still be whatever number you put in the lparam parameter.
However if you use PostMessage, which is asynchronous, then by the time the main frame handles the message this handle will no longer be associated with the child frame window. It will either not "point" to any window or may have been recycled and point to some other window.
You can use SendMessage, which is not asynchronous, is you really need the window handle to be "valid" in that it is still associated by the operating system with your child window.
Of course this assumes that you are sending this message before DestroyWindow has been called for the child frame. The WM_CLOSE handler should work.
What are you going to use this handle for in the Main frame class?
2. You can avoid using messages. In the header file for your Main frame class put
Code:
__inline MainFrame* GET_MAIN_FRAME()
{
MainFrame* mf = static_cast<MainFrame*>(AfxGetMainWnd());
ASSERT(mf && mf->IsKindOf(RUNTIME_CLASS(MainFrame)));
return mf;
}
now instead of using messages you just add whatever function call you want to your main frame class. You can now pass whatever parameters you want
Code:
//in child window
GET_MAIN_FRAME()->FOO(...)
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
May 21st, 2008, 02:12 PM
#7
Re: MainFrame/ChildFrame
Originally Posted by souldog
There are a few options for doing this.
1. You do not need to register a windows message. Instead you would do the
following
a. Define a constant for the message
Code:
#define WM_MDI_CHILD_WINDOW_CLOSING (WM_APP + 1)
I would prefer to register the window messages. It seems easier to managing names and values that way. Is there a reason why registering a windows message is a bad idea?
b. Your code in the main frame only changes for the message map implementation
Code:
//MainFrame.cpp
BEGIN_MESSAGE_MAP(MainFrame, CMDIFrameWnd)
ON_MESSAGE(WM_MDI_CHILD_WINDOW_CLOSING, OnChildFrameClosing)
END_MESSAGE_MAP()
c. in the child frame post or send a message using this constant
Well, assuming I follow your advice regarding the message definitions, thanks.
What do you mean by "would the HWND still be valid?"
I just wasn't sure if the handle was still "associated" with the window prior to my SendMessage(...) call. I stepped through working code and it seems ok.
What are you going to use this handle for in the Main frame class?
Simply to update a custom menu. It has a "LED" light showing the window is open. When the window is closed, I need to tell the menu-bar the window associated to that "LED" is no longer there.
Each menu item has a member HWND variable associating the menu item to a particular window.
2. You can avoid using messages. In the header file for your Main frame class put
Code:
__inline MainFrame* GET_MAIN_FRAME()
{
MainFrame* mf = static_cast<MainFrame*>(AfxGetMainWnd());
ASSERT(mf && mf->IsKindOf(RUNTIME_CLASS(MainFrame)));
return mf;
}
now instead of using messages you just add whatever function call you want to your main frame class. You can now pass whatever parameters you want
Code:
//in child window
GET_MAIN_FRAME()->FOO(...)
Great suggestion! Didn't even think of that!
Mike B
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|