CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7

Hybrid View

  1. #1
    Join Date
    Feb 2001
    Posts
    2,455

    MainFrame/ChildFrame

    Is the MainFrame notified in any way that the child frame has been closed? The user clicked X?

    Mike B

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    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.

  3. #3
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    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."

  4. #4
    Join Date
    Feb 2001
    Posts
    2,455

    Re: MainFrame/ChildFrame

    Quote 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

  5. #5
    Join Date
    Feb 2001
    Posts
    2,455

    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

  6. #6
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    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."

  7. #7
    Join Date
    Feb 2001
    Posts
    2,455

    Re: MainFrame/ChildFrame

    Quote 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
  •  





Click Here to Expand Forum to Full Width

Featured