How do I Create a Basic MDI Application?
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
//////