Windows Programming/MDI Programs

Multiple Document Interface (MDI) applications are a very common and popular type of application. MDI applications allow a single program window to contain multiple open workspaces simultaneously. Creating them isn't particularly tricky, and this chapter will attempt to explain the process in detail.

Steps to Making an MDI edit

These are the steps to making an MDI application. We will explain each of them.

  1. Register the Frame and Child window classes.
  2. Modify the message loop.
  3. Create the frame window.
  4. Create the MDI Client
  5. Create MDI child windows with the client.

Register the Window Classes edit

Like any other windows application, we need to register the window classes. The main window (the frame, or the "parent" window) needs to be created. Frame windows are just like any other window, but they generally have a background color of COLOR_APPWORKSPACE. Also, the child windows in an MDI application are not allowed to have their own menus, so the Frame window must manage the application menu. Remember, that different child windows usually require different menu choices (or different menus all together), so the Frame window needs to maintain a current record of the active child window, and set the menu accordingly.

The child window class (all of them) needs to be created with WS_CHILD class. An MDI application may have any number of different types of child windows (a famous example is the use of spreadsheets and charts in Microsoft Excel), and they all need to be registered before use.

Modify the Message Loop edit

MDI applications use an almost-normal message loop, but if you want to use accelerators in your program, you need to add a new step:

while(GetMessage(&msg, hwndFrame, 0, 0))
{
   if(!TranslateMDISysAccel(hwndClient, &msg) &&
      !TranslateAccelerator(hwndFrame, hAccel, &msg))
   {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
   }
}

This way the accelerators get routed to the correct destination among all the different child windows. If you are not using accelerators, you don't need to worry about this step.

The Frame Window edit

Frame Windows get created like any other windows. Remember, however, that frame windows are just a backdrop for the action that is happening in the child windows, so you shouldn't get to crazy or fancy with your background artwork.

The Client Window edit

You need to create a window of type "MDICLIENT". MDICLIENT windows are defined internally in Windows, so you don't need to worry about what it is or what it does. When you create an MDI client window, you first need to fill out the fields in the CLIENTCREATESTRUCT structure. You pass a pointer to this structure as the LPARAM data field in the CreateWindow function.

MDI Child Windows edit

Creating MDI child windows is a little bit different from creating normal windows. To create an MDI child window, you must fill out the MDICREATESTRUCT data structure. The MDICREATESTRUCT is very similar to the WNDCLASS structure, except it is more limited. After creating this structure, you must send it as a message to the MDICLIENT window:

hwndChild = (HWND)SendMessage(hwndClient, WM_MDICREATE, 0, (LPARAM)mdicreatestruct);

The message function will return a handle to the newly created child window.

The "Window" Menu edit

Many MDI applications will offer a "Window" popup menu on the menu bar, to manage the MDI child windows. This menu frequently has options to "Tile" or "Cascade" the child windows, and it frequently maintains a listing of the currently available child windows in the application. It turns out that the MDI Client window will manage this menu for you, if you just pass it the correct handle to the menu.

Next Chapter edit