| bitbucket: C++ MFC ATL WTL Win32 COM ActiveX Samples Tutorials Source Code Controls |
Implement MDI "Close All Windows" |
Shows a snippet that closes all child frames in an MDI application. Implementation is MFC-dependent, but can easily be adjusted.
For an MFC Doc/View application, you can use CWinApp::CloseAllDocuments.
MFC applications that don't use Document/View-Model, you can use the following code. It can be easily adopted to non-MFC applications, and contains a nice helper function to enumerate direct child or desktop windows into an STL array.
// Helper function: Enumerate windows into an STL Vector
static BOOL CALLBACK DoEnumWndInVec(HWND wnd, LPARAM lp)
{
std::vector<HWND> & vec = *(std::vector<HWND> *) lp;
vec.push_back(wnd);
return TRUE;
}
bool EnumWndInVector(std::vector<HWND> & vec, HWND parent = NULL)
{
BOOL ok;
vec.resize(0);
if (parent)
ok = EnumChildWindows(parent, DoEnumWndInVec, (LPARAM) &vec);
else
ok = EnumWindows(DoEnumWndInVec, (LPARAM) &vec);
return ok != 0;
}
// ---- Handler for "Close All" menu item ----
void CMainFrame::OnWindowCloseall()
{
CWnd * frame = GetActiveFrame();
if (!frame || frame->m_hWnd == m_hWnd) return;
// if no window actice, GetActiveFrame returns "this" !!
CWnd * parent = frame->GetParent();
if (!parent) return;
std::vector<HWND> vec;
EnumWndInVector(vec, parent->m_hWnd);
for(unsigned i=0; i<vec.size(); ++i)
{
if (::IsWindowVisible(vec[i])) // only for visible windows...
::SendMessage(vec[i], WM_CLOSE, 0, 0);
}
}
1. EnumWndInVector
This is a helper function, that uses EnumWindows, or EnumChildWindows, to enumerate all top-level, or all direct child windows into an STL-Array.
vec: Vector to be filled with HWND's
parent: Parent Window. If NULL, Top-Level-Windows will be enumerated
2. GetActiveFrame / GetParent:
In an MDI app, the window hierarchy depends on several features, such as docking toolbars. The safest way ist to get hold of one child frame, and then get it's parent.
3. IsWindowVisible
We will close only windows that are visible. Reason: MFC might add invisible helper windows (which it doesn't right now, to my knowledge...)
Additionally, we could even check if it's a CMDIChildWnd:
CWnd * wnd = CWnd::FromHandle(vec[i]);
bool closeMe = wnd!=NULL &&
wnd->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)) &&
wnd->IsWindowVisible();
if (closeMe) wnd->SendMessage(WM_CLOSE);
bitbucket c++ site © Peter Hauptmann. Questions
& Comments to cherea@cherea.de
page updated 29/02/04