Introduction
Sometimes, it may be useful to have a modal window with Doc/View architecture, toolbars/statusbar support (i.e. base features implemented in MFC frame windows). How to get these without implementing all of these features in a CDialog
-derived class? The CModalFrame
utility class presented here helps you implement a modal dialog's behavior for any CFrameWnd
-derived window class in an easy way.
If you have to use it and have a bit of time, please add a comment at the bottom of this page and tell, in which context you decided to use this code. I would be interested.
Background
Some basic facts:
- All required features are already implemented in
CFrameWnd
-derived classes.
- The basic support of modal message loop is already implemented in the
CWnd
class.
Brief implementation description:
- The utility code uses only the
CFrameWnd
class interface and does not make any suggestions about the internal implementation details of any CFrameWnd
-derived classes.
CModalFrame::Run
creates an instance of the internal CModalDialogLock
class which:
- stores modal loop context,
- runs modal message loop and,
- supports multiple running modal frames.
CModalDialogLock
subclasses the created frame window to provide:
- update command UI for the frame on
WM_KICKIDLE
message,
- exit from modal message loop on
WM_NCDESTROY
message and,
- restore standard modal window behavior on
WM_NCACTIVATE
message.
- You should not use
WS_CHILD
window style for a frame. Because its parent window is disabled during modal loop. So child frame window also will be disabled (for example, MDI child frame)!
Using the code
- Files needed:
- ModalFrame.h
- ModalFrame.cpp
Sample of usage:
void CMyView::OnRunModalFrame()
{
CCreateContext context;
context.m_pNewViewClass = RUNTIME_CLASS(CMyOtherView);
context.m_pCurrentDoc = GetDocument();
context.m_pNewDocTemplate = GetDocument()->GetTemplate();
context.m_pLastView = this;
context.m_pCurrentFrame = GetParentFrame();
CRuntimeClass * pFrameClass = RUNTIME_CLASS(CMyModalFrame);
if (!CModalFrame::Run(*pFrameClass, false, IDR_MYFRAMERESOURCE,
WS_OVERLAPPEDWINDOW |
FWS_ADDTOTITLE, this, &context))
{
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
}
}
void CMyModalFrame::OnClose()
{
int nModalResult = -1;
CModalFrame::End(this, nModalResult);
}
See demo project code for more details.
History
- Version 1.2
- Bug fixing.
- More accurate work with a stack of modal frames.
- Version 1.1
- Implemented support for multiple running modal frames.
- More accurate restoring active window after the end of the modal message loop.
- Version 1.0