How do I Create a Basic MDI Application?

Back Up Next

OWLWindows' Multiple Document Inteface (MDI) offers programmers a powerfull way to control the objects - especially the document windows - that make up an upplication. An MDI application not only creates a sort of mini-desctop on which user can orginize related windows and icons, but also provides the programmer with many easy-to-implement functions that automatically handle those windows.  MDI application requere a little more effort to programmer, but their advantages far outheight any extra labor involved.

Thanks to OWL, however, creating an MDI application is amazing easy. You need only to use the special OWL classes for MDI applications - including TMDIFrame(or TDecoratedMDIFrame), TMDIClient, and TMDIChild - and supplay an appropriate Window menu. The rest is almost automatic.

What exactly makes up an MDI application? Here's a list of the most impportant characteistics:

An MDI application's main window is called a frame window. The frame window doesn't provide a workspace for the display of data as does a conventional window; rather, it provides a deskot-like surface for the organization of the child (document)  windows.
When a new file is open in an MDI application, it is presented by a document window, which appears over the frame window's client area. An MDI application can have any number of document windows open simultaneously.
An MDI frame window alwas has a menu bar, which includes, but is not limited to, a Window menu for controlling MDI document window. From this menu, document windows can usually be selected, tiled, and cascaded, among other things.
MDI document windows have no menu. They receive commands from the applicatin's frame-window menu.
MDI document windows canno be  moved outside the frame window.
When an MDI document window is minimized, it's displayed as an icon at the bottom of the frame window.
When an MDI document window is maximized, it's takes over the entire frame window, and its controls merge with those of the frame window.
An MDI application's frame window is covered by an invisible client window, which acts as parent to windows and controls that appear over the frame window.

 

In your InitMainWindow() function, first construct the appplication's client window:

    TMDIClient* clientWnd = new TMDIClientWnd;

Every OWL MDI aplicationmust have a client window derived from the TMDIClient class (which means you must include the header file <owl/mdichild.h>,  as well as <owl/mdi.h>, in your program ). This programm has it's own client window class, which of cource, derived from OWL's TMDIClient class:

class TMDIClientWnd: public TMDIClient{
    public:
        TMDIClientWnd();
    protected:
        TMdiChild* InitChild();
};

TMDIClient is, in turn, derived from TWindow and provides message-response functions for the MDI commands in the Window menu, including CmCreateChild(), CmCloseChildrens(), CmCascadeChildren(), and CmTileChildren(). TMDIClient also features command enablers for the Window menu, so you don't need to fuss over enabling and disabling items in the Window menu. Finally, TMDIChild's member functions GetActiveMDIChild() and InitChild() enable you to get a pointer to the active child window and create custom child windows.

TMDIChild*  TMDIClientWnd::InitChild()
{
return new TMDIChild(*this, "An MDI Child");
}

After constructing the client window, construct the application's main window, which must be of the TMDIFrame  class (ot class derived from TMDIFrame) :

TMDIFrame* frame = new TMDIFrame("MDI App",MENU_1, *clientWnd);

TMDIFrame's constructor takes as parameter a title string, a menu resource ID, and a reference to a client window. The TMDIFrame class is derived from TFrameWindow and handles such task as finding and storing the position of the application's Window menu. In addition, this class provides the member functions GetClientWindow(), which returns a pointer to the frame window's client window, and SetMenu(), which you can call to update the position of the Window menu after you install a new menu bar.

Finally, when you create the menu IDs for your Window menu, you must use the values defined by OWL for the WIndow menu. The resource header file <owl/mdi.rh>,   defines a set constants that you can use for this purpose. This constants are CM_CASCADECHILDREN(24361), CM_TILECHILDREN(24362), CM_TILECHILDRENHORIZ(24363), CM_ARANGEICONS(24364), CM_CLOSECHILDREN(24365), and CM_CREATECHILD(24366). An OWL client window already has message-response functions that respond to these menu item IDs.

Sample program:

// sample.cpp
#include <owl\applicat.h>
#include <owl\mdi.h>
#include <owl\mdichild.h>
#include "mdiapp.rc"

//////////////////////////////////
// The application class.
class TMDIApp : public TApplication{
    public:
        TMDIApp() : TApplication() {}
        void InitMainWindow();
};

//////////////////////////////////
// The client window class.
class TMDIClientWnd : public TMDIClient{
    protected:
        int childNum;

    public:
        TMDIClientWnd();

    protected:
        TMDIChild *InitChild();
};

///////////////////////////////////////////////////////////
// TMDIClientWnd::TMDIClientWnd()
TMDIClientWnd::TMDIClientWnd()
:
    TMDIClient()
{
    childNum = 1;
}

///////////////////////////////////////////////////////////
// TMDIClientWnd::InitChild()
TMDIChild* TMDIClientWnd::InitChild()
{
    // Create a new child window caption.
    char s[20];
    wsprintf(s, "Child Window #%d", childNum);

    // Increment the MDI child window number.
    ++childNum;

    // Create and return a pointer to
    // a new MDI child window.
    return new TMDIChild(*this, s);
}

///////////////////////////////////////////////////////////
// TMDIApp::InitMainWindow()
void TMDIApp::InitMainWindow()
{
    // Create an MDI client window.
    TMDIClient *clientWnd = new TMDIClientWnd;

    // Create the MDI frame window.
    TMDIFrame *wndw = new TMDIFrame("MDI App", MENU_1, *clientWnd);

    SetMainWindow(wndw);
}

///////////////////////////////////////////////////////////
// OwlMain()
///////////////////////////////////////////////////////////
int OwlMain(int, char*[])
{
    return TMDIApp().Run();
}
////////////////////////////////////////////////////////
// sample.rc
#ifndef WORKSHOP_INVOKED
#include "windows.h"
#endif

#include <owl\mdi.rh>
#include <owl\window.rh>

#define MENU_1    100

#ifdef RC_INVOKED

MENU_1 MENU
{
    POPUP "&File"
    {
        MENUITEM "E&xit", CM_EXIT
    }

    POPUP "&Window"
    {
        MENUITEM "C&reate", CM_CREATECHILD
        MENUITEM "&Cascade", CM_CASCADECHILDREN
        MENUITEM "&Tile", CM_TILECHILDREN
        MENUITEM "Arrange &Icons", CM_ARRANGEICONS
        MENUITEM "C&lose All", CM_CLOSECHILDREN
    }
}

#endif

//////


Copyright © 1998-2001 Yura Bidus. All rights reserved.