Sometimes, you need to activate a particular document window in the MDI application. It has nothing in common with opening the same document. You need it when an event happens, or user changed something somewhere and you need to notify him that one of the opened documents received changes or finished computation or whatever I can’t even imagine. In this case, you need a way to pop the random document…
In the text below, you can find a weird code that was written while sequentially approaching the working solution. The code below contains only code that illustrates the technology, no error handling or complete function code provided.
In my case, I required documents which represents a filesystem folders which cannot be opened, changes since they were opened and, of course they must not be opened more than once. Don't ask me why I have to use an MDI (multiple document interface) MFC application for this purpose.
Using the Code
A long time ago, I got some experience in writing MFC applications. Windows was young and made first steps as a 32-bit operating system at that time. Moreover, most of my applications were SDI (single document interface) or dialog based. And I was more or less calm and happy that time.
However, returns to our
muttons MDI application. For my task, I have to use MDI interface and, after some iterations, I felt the need to activate the opened document when user did some action. I began with the document lookup (the easiest part):
POSITION pos = pApp->GetFirstDocTemplatePosition();
CDocTemplate* pDocTmpl = pApp->GetNextDocTemplate(pos);
POSITION posD = pDocTmpl->GetFirstDocPosition();
while (posD != NULL)
CDocument* pDoc = pDocTmpl->GetNextDoc(posD);
if (pDoc->GetTitle().CompareNoCase(path) == 0)
POSITION posW = pDoc->GetFirstViewPosition();
while (posW != NULL)
CView* pView = pDoc->GetNextView(posW);
if (pView && ::IsWindow(pView->GetSafeHwnd()))
It is easy to identify that you need, but the next steps were not easy to me. My first view activation code is shown below:
CWnd* pWnd = pView->SetActiveWindow();
Very naive, isn't' it? However, it doesn't have any visible effect on the application, because there is no easy way to impress the window at the bottom of the deep windows stack.
The next approach was found on Stack overflow (C++, MFC MDI, activate specific tab). It contains the code below:
CMDIChildWnd* pChild = (CMDIChildWnd*)pMainFrame->GetActiveFrame();
if (pChild && ::IsWindow(pChild->GetSafeHwnd()) && pChild->IsChild(pView))
This code is better than the previous one, it works when the document is selected :-).
After some investigations with Microsoft Spy++ (by default, Visual Studio runs a 32 bit Microsoft Spy++) tool, I discovered that we've got a stack of Windows which produced the unreadable amount of messages and there is no use to touch this stack of windows...
Finally, I was able to find the code at the CMDIFrameWnd Class | Microsoft Learn page I need and it looks like:
CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();
CMDIChildWnd* child = pMainFrame->MDIGetActive();
if (str == path)
child = (CMDIChildWnd*)child->GetWindow(GW_HWNDNEXT);
} while (child);
And it works!
Points of Interest
I have no words to express my impression.
- 8th December, 2022: Initial version
I came to the industry at the end of that times when the computer program executes as it was written. I saw a quite big machines, occupied more than 100 square meters for its central processor, but I started my professional activity as a programmer on IBM PC clones. There were different CPU architectures (68k, PowerPC, 386/486, SPARC...) when I began, but Intel defeated them all with Pentium CPU (marketing) family.
I saw the knowledge and technology fragmentation. I saw many technologies started, developed and retired. However, I have not seen many things yet.
I have some experience, but my experience is not perfectly comprehensive. I still have many things to learn and I still cannot make a poker face when I find out some aspects about how the things were designed and works. My experience does not make me an absolute expert in some areas, because these areas are changing. I know some things, but I also understand that some things I know could be useless for nowadays.