23.7 Levels of Windows

Very many of the rectangular areas on your screen are officially windows, more of them than you realize. A toolbar is a window, a button on the toolbar is a window, a scrollbar is a window, your main view is a window, and so on. When one window always lives inside some other window, we speak of them as a child window and a parent window. Thus a toolbar button is a child window of the parent toolbar window, and the toolbar is in turn a child window of the parent window running the application. When a parent window has the form of a frame around the child window, we often speak of the child window as the client of the parent frame.

One possible source of confusion here is that we also use the words 'parent' and 'child' about classes. Consider the situation where a class ClassB has a declaration like

class ClassB : public ClassA 
{ . . . }; 

Here we say that class ClassB is a child of ClassA, or we say that ClassB inherits from ClassA. By the same token, we say that ClassA is a parent of ClassB, or that ClassB is derived from ClassA.

But when we talk about parent and child windows we mean something different. We are talking about the window positions in what is sometimes called the windows tree. As a window, the client area is a child of the frame. But as classes, the client window is perhaps a CView class, while the parent window is perhaps a CFrameWnd class or a CMDIChild class. As window class types, all three classes inherit from the basic CWnd class. But they are not in any class-type parent-child relationship to each other.

When we program an SDI (single document interface) or a MDI application in MFC, we usually speak of the window we are going to use for our input and output as the view. The view is an example of a CView object. Our code will include a special class to describe the behavior of our view; in the Pop program, for instance, this class will be called the CPopView class and is defined in the PopView.* files. The CPopView class is derived from a built-in MFC class called CView, which is in turn derived from a built-in MFC window class CWnd.

The outermost of your program's window rectangles is an object of your special type CMainFrame, and it's called the main frame. Your CMainFrame class is defined in your MainFrm.* files. As usual in this book, we focus on the MDI style of application, as opposed to the SDI. But it's worth mentioning that in an SDI app, your CMainFrame class is a child of the CFrameWnd class, and in an MDI program your CMainFrame class is a child of the CMDIFrameWnd class. Along with your underlying CWinApp program object, your CMainFrame main frame is 'mission control central'; it directs the shapes of the main window, the toolbar, the menu bar, the caption bar, and so on.

In a MDI program, you have the possibility of showing a variety of views. Each view has its own frame, which your program defines as a CChildFrame object. A MDI program's CChildFrame object inherits from the CMDIChildWnd class. And an actual view that you write in is the child or client of a CMDIChildWnd frame. We illustrate this 'window tree' in Table 23.3.

Table 23.3. The 'window tree' for a view in the multiple document interface.

Colloquial name

Pop name

MDI inherits from

Code is in

Main frame




Child frame




User view




The child frame window is the caption bar and the frame and parent of your View window. In a MDI application, you can see the child frame particularly clearly when a view is not maximized. The caption bar of the child frame will usually have a three buttons in the upper right corner. One button is for closing the window, and the other two are for either minimizing, restoring (to a non-maximized and non-minimized size), or maximizing your window. Whichever two options are different from the window's current state are what is offered; for instance, if the window is maximized, you'll have the minimize and the restore options.

If you maximize a view in a MDI application, the view's child frame merges into the big main frame. And the child view's Minimize, Restore, and Close buttons move up onto the menu bar of the main frame. When seen this way, a MDI program closely resembles an SDI program, which is why sometimes one doesn't notice the difference. But the double set of Minimize, Restore, and Close buttons are a tip-off. The top set is for the main frame and MDI client; the lower set is for the child frame and view.

For the sake of completeness and full disclosure, we should mention that there is one extra intermediate-level in MDI. It's called the MDI client window. This is the gray background window that you see in an MDI application if you repeatedly use File | Close to close all the open views. You also see part of the MDI client window if you resize all of your active child windows so that none of them is maximized. The gray MDI background is sort of like a local 'desktop' that the MDI app uses. Ordinarily we don't customize it, so we don't use any kind of special class for it, and it's not mentioned in our standard code.

How about getting from one window to another? Here's how you would do it in MDI. Table 23.4 lists the code to use to get a pointer to the classes listed in the top row from inside a method belonging to class in the left column. This table is a useful piece of information to have; it can save you a lot of grief.

For the sake of completeness, we should also mention how to get to the gray MDI client window, should you want to do something to it. Like maybe you'd want to make it start being green. Get hold of one of the CMDIChildWnd objects, and then have that object call GetParent(). Although the main frame is the parent frame of the child frames, the immediate parent of the child frames is the skulking MDI client. A call to GetParentFrame() moves up the chain of parent windows until it finds one that is of the CFrame type.

Table 23.4. How the view and frame windows can access each other.

Get to? From?

CMDIFrameWnd (main frame)

CMDIChildWnd (child frame)


CMDIFrameWnd (main frame)





CMDIChildWnd (child frame)




CView (client)




Our CPopDoc class defines a useful getActiveView method as follows.

CPopView* CPopDoc::getActiveView() 
    CMDIFrameWnd *pFrame =(CMDIFrameWnd*)AfxGetMainWnd(); 
    if (!pFrame) //In case things aren't initialized yet. 
        return NULL; 
    CMDIChildWnd *pChild = pFrame->MDIGetActive(); 
    if (!pChild) //In case things aren't initialized yet. 
        return NULL; 
    CPopView *pView = (CPopView *) pChild->GetActiveView(); 
    return pView; 

    Part I: Software Engineering and Computer Games
    Part II: Software Engineering and Computer Games Reference