home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
MDISTRM.PAK
/
MDISTRM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-29
|
7KB
|
257 lines
//----------------------------------------------------------------------------
// ObjectWindows - (C) Copyright 1993 by Borland International
//
// This example shows a persistent desktop using the MDI metaphor. It is
// identical to the owlapi\mdi example, but with streaming code added to
// implement persistence for the frame, parent (client) window, and children.
//
//----------------------------------------------------------------------------
#include <owl\owlpch.h>
#include <owl\applicat.h>
#include <owl\mdi.h>
#include <owl\mdichild.h>
#include <stdio.h>
#include "mdistrm.h"
const char DskFile[] = "MDISTRM.SAV";
const char AppName[] = "MDI Object Streaming Example";
//----------------------------------------------------------------------------
//
// Here's our client, it's fully streamable.
//
class TMyMDIClient : public TMDIClient {
public:
TMyMDIClient() : TMDIClient() {ChildNum = 0;}
TMDIChild* InitChild();
BOOL CanClose(); //virtual from TWindow
private:
WORD ChildNum;
DECLARE_STREAMABLE(, TMyMDIClient, 1);
};
IMPLEMENT_CASTABLE1(TMyMDIClient, TMDIClient);
IMPLEMENT_STREAMABLE1(TMyMDIClient, TMDIClient);
//
// Our application object is also fully streamable and
// we use it to stream out its client (which contains the
// MDI child windows) to achieve a persistent desktop.
//
class TMDIApp : public TApplication {
public:
TMDIApp() : TApplication(AppName) {}
void InitMainWindow();
void InitInstance();
void CmSaveState();
void CmRestoreState();
private:
TMyMDIClient* Client;
DECLARE_RESPONSE_TABLE(TMDIApp);
DECLARE_STREAMABLE(, TMDIApp, 1);
};
DEFINE_RESPONSE_TABLE1(TMDIApp, TApplication)
EV_COMMAND(CM_SAVESTATE, CmSaveState),
EV_COMMAND(CM_RESTORESTATE, CmRestoreState),
END_RESPONSE_TABLE;
IMPLEMENT_CASTABLE1(TMDIApp, TApplication);
IMPLEMENT_STREAMABLE1(TMDIApp, TApplication);
//----------------------------------------------------------------------------
TMDIChild*
TMyMDIClient::InitChild()
{
char childName[15];
// Create a unique (numbered) caption for our MDI child
sprintf(childName, "MDI Child %d", ChildNum++);
// and then create that child.
return new TMDIChild(*this, childName);
}
BOOL
TMyMDIClient::CanClose()
{
// Save our persistent desktop, before closing down the client.
// We have to (safely and dynamically) cast to our application
// object type so that we can call our save state routine.
//
TMDIApp *app = TYPESAFE_DOWNCAST(GetApplication(),TMDIApp);
if (app)
app->CmSaveState();
return TMDIClient::CanClose();
}
//
// Writes the TMyMDIClient instance to the passed opstream.
//
void
TMyMDIClient::Streamer::Write(opstream& os) const
{
WriteBaseObject((TMDIClient*)GetObject(), os);
// Write out the member data for our MDI Client.
os << GetObject()->ChildNum;
}
//
// Reads an instance of TMyMDIClient from the passed ipstream.
//
void *
TMyMDIClient::Streamer::Read(ipstream& is, uint32 /*version*/) const
{
ReadBaseObject((TMDIClient*)GetObject(), is);
// Read in the member data for our MDI Client.
is >> GetObject()->ChildNum;
return GetObject();
}
//----------------------------------------------------------------------------
//
// Construct the TMDIApp's MainWindow (frame) object and save
// a pointer to its client window in the Client data member.
// Restore the desktop if we've got one already streamed.
//
void
TMDIApp::InitMainWindow()
{
// Create MDI frame window, load its menu, and create its client.
MainWindow = new TMDIFrame(GetName(), "MDIMenu", *(Client=new TMyMDIClient));
}
void
TMDIApp::InitInstance()
{
TApplication::InitInstance();
// Restore our persistent desktop, if there's a stream that already exists.
ifpstream is(DskFile);
if (!is.bad())
{
is.close();
CmRestoreState();
}
}
//
// Save the the position and contents of the windows to the "desktop" file.
//
void
TMDIApp::CmSaveState()
{
ofpstream os(DskFile);
// Stream out 'this' object (our MDI application and children).
os << *this;
os.close();
if (os.bad()) {
unlink(DskFile);
MainWindow->MessageBox("Unable to write desktop file.", "Disk error",
MB_OK | MB_ICONEXCLAMATION);
}
}
//
// Read windows' positions and contents from the "desktop" file.
//
void
TMDIApp::CmRestoreState()
{
char* errorMsg = 0;
ifpstream is(DskFile);
if (is.bad())
errorMsg = "Unable to open desktop file.";
else {
// Close any MDI children we may have.
Client->CloseChildren();
try {
// Stream into 'this' object our (new) MDI application and children.
is >> *this;
if (is.bad())
errorMsg = "Error reading desktop file.";
}
catch (xalloc) {
if (Client->HWindow)
Client->CloseChildren();
errorMsg = "Not enough memory to open file.";
}
is.close();
}
if (errorMsg)
MainWindow->MessageBox(errorMsg, "Error", MB_OK | MB_ICONEXCLAMATION);
}
void
TMDIApp::Streamer::Write(opstream& os) const
{
// Stream out our app's mainwindow size/coordinates and our client
// window (the client will stream any child windows it may contain).
WriteBaseObject((TApplication*)GetObject(), os);
os << GetObject()->MainWindow->Attr.X;
os << GetObject()->MainWindow->Attr.Y;
os << GetObject()->MainWindow->Attr.W;
os << GetObject()->MainWindow->Attr.H;
os << *( GetObject()->Client );
os << GetObject()->Client->GetActiveMDIChild();
}
void *
TMDIApp::Streamer::Read(ipstream& is, uint32 /*version*/ ) const
{
// Stream in our app's mainwindow frame coordinates, updating its frame
// size, and stream in its client window.
ReadBaseObject((TApplication*)GetObject(), is);
is >> GetObject()->MainWindow->Attr.X;
is >> GetObject()->MainWindow->Attr.Y;
is >> GetObject()->MainWindow->Attr.W;
is >> GetObject()->MainWindow->Attr.H;
is >> *( GetObject()->Client );
TMDIChild* active;
is >> active;
// If our mainwindow already exists (i.e., we're restoring from the menu)
// then make sure it's redrawn correctly, with the 'new' extent attributes
// (what they were when they were last streamed to file).
if (GetObject()->MainWindow->HWindow)
GetObject()->MainWindow->MoveWindow(GetObject()->MainWindow->Attr.X,
GetObject()->MainWindow->Attr.Y,
GetObject()->MainWindow->Attr.W,
GetObject()->MainWindow->Attr.H,
TRUE);
// Finally, create the interface objects for our children,
// restoring the active window.
GetObject()->Client->CreateChildren();
if (active)
GetObject()->Client->HandleMessage(WM_MDIACTIVATE,(UINT)active->HWindow);
return GetObject();
}
int
OwlMain(int /*argc*/, char* /*argv*/ [])
{
return TMDIApp().Run();
}