In this step, you'll expose some of the functionality of the drawing application, making it possible for OLE automation controllers to open new drawing documents, set pen attributes, and add lines.
It's a relatively simple task to turn a regular OLE server into an OLE automation server. You just make small changes to the application, document, and view classes.
#include
listing from the step15.cpp file and make the following changes:
/automation
command-line switch. Therefore, you must add the /automation
switch to the application registration table using the cmdline keyword.For the drawing application, you should also modify the description so it says ``..Automation Server'' instead of ``...Server.''
Your new registration table should look something like this:
BEGIN_REGISTRATION(AppReg) REGDATA(clsid, "{5E4BD320-8ABC-101B-A23B-CE4E85D07ED2}") REGDATA(description,"OWL Drawing Pad Automation Server") REGDATA(cmdline, "/automation") END_REGISTRATIONNote: Remember, never use a GUID or program identifier that another application uses.
In addition, for each member function that has parameters with one or more complex data types, you should create a new member function that has parameters with only basic data types. The new function should perform the necessary conversions between data types and then call the original function. By exposing member functions that take only basic data types, you make it easier for an automation controller to use them.
Finally, most OLE automation servers expose a set of standard properties and methods, including the following:
For example, the step16.h file contains declarations for the standard properties and methods in the private section of the TDrawApp class:
void SetShow(bool visible); // Sets the Visible property value. bool GetShow(); // Gets the Visible property value. TDrawDocument* OpenDoc; // Opens or creates a document.Note: You don't need to declare or implement a member function for the Quit method since these tasks are handled automatically by ObjectComponents if you use the EXPOSE_QUIT macro, as shown in the next section.
The step16.cpp file contains the implementations of these functions:
// Get the Visible property value. TDrawApp::SetShow(bool visible) { TFrameWindow* frame = GetMainWindow(); if (frame && frame->IsWindow()) {unsigned flags = visible ? SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE| SWP_SHOWWINDOW : SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER| SWP_HIDEWINDOW;
frame->SetWindowPos(HWND_TOP, 0,0,0,0, flags);} // Set the Visible property value. bool TDrawApp::GetShow() { TFrameWindow* frame = GetMainWindow(); return (frame && frame->IsWindow() && frame->IsWindowVisible()); } // Get the Fullname property value. const char far* TDrawApp::GetPath() { static char buf[_MAX_PATH]; GetModuleFileName(buf, sizeof(buf)-1); return buf; } // Open or create a document. extern TDocTemplate drawTpl; TDrawDocument* TDrawApp::OpenDoc(const char far* name) { long flags = name ? 0 : dtNewDoc; TDocManager* docManager = GetDocManager(); if (!docManager) return 0; HWND hWnd = ::GetFocus(); TDocument* doc = GetDocManager()->CreateDoc(&drawTpl, name, 0, flags); ::SetFocus(hWnd); return dynamic_cast<TDrawDocument*>(doc); }
The step16.h file contains declarations of the properties and methods for the application class of the drawing application:
DECLARE_AUTOAGGREGATE(TDrarwApp)
AUTOPROP (Visible, GetShow, SetShow, TBool)
AUTOFUNC0 (NewDoc, OpenDoc, TAutoObject<TDrawDocument>,)
AUTOFUNC1 (OpenDoc, OpenDoc, TAutoObject<TDrawDocument>, TAutoString,)
AUTOPROPRO (AppName, GetName, TAutoString,)
AUTOPROPRO (FullName, GetPath, TAut
oString,)
The step16.cpp file contains definitions of the properties and methods for the application class of the drawing application:
DEFINE_AUTOAGGREGATE(TDrawApp, OcApp->Aggregate)
EXPOSE_PROPRW(Visible, TAutoBool, "Visible", "Main window shown", 0)
EXPOSE_METHOD(NewDoc, TDrawDocument, "NewDocument", "Create new document", 0)
EXPOSE_METHOD(OpenDoc TDrawDocument, "OpenDocument", "Open existing document", 0)
REQUIRED_ARG( TAutoString, "Name")
EXPOSE_PROPRO(AppName, TAutoString, "Name", "Application name", 0)
EXPOSE_PROPRO(FullName,TAutoString, "FullName", "Complete path to application", 0)
EXPOSE_APPLICATION(TDrawApp, "Application", "Application object", 0)
EXPOSE_QUIT( "Quit", "Shutdown application", 0)
END_AUTOAGGREGATE(TDrawApp,tfAppObject|tfCanCreate,"T
DrawApp","Application class", 0)
#include
listing from the step15dv.cpp file and make the following changes:
In addition, for each member function that has parameters with one or more complex data types, you should create a new member function that has parameters with only basic data types. The new function should perform the necessary conversions between data types and then call the original function. By exposing member functions that take only basic data types, you make it easier for an automation controller to use them.
When you create new member functions, you may find that you need new data members as well.
For example, the step16dv.h file contains the declarations and implementations of eight new member functions of the document class:
long GetPenColor() // PenColor property. { return AutoPenColor; }void SetPenColor(long color) // PenColor property. { AutoPenColor = color; AutoLine->SetPen(TColor(color)); } short GetPenSize() // PenSize property. { return AutoPenSize; } void SetPenSize(short penSize) // PenSize property. { AutoPenSize = penSize; AutoLine->SetPen(penSize); } void AddPoint(short x, short y) // AddPoint method. { AutoLine->Add(TPoint(x,y)); } void AddLine() { AddLine(*AutoLine); ClearLine(); } void ClearLine() // ClearLine method. { delete AutoLine; AutoLine = new TLine(AutoPenColor, AutoPenSize); } In addition, the step16dv.h file contains the declarations of three new data members of the document class:
TLine* AutoLine; long AutoPenColor; short AutoPenSize;
For example, the step16dv.h file contains new lines of code in the constructor and destructor that initialize and destroy the new data members:
TDrawDocument::TDrawDocument(TDocument* parent) : TOleDocument(parent), UndoLine(0), UndoState(UndoNone) { Lines = new TLines(100, 0, 5); AutoPenSize = 1; AutoPenColor = RGB(0, 0, 0); AutoLine = new TLine(AutoPenColor, AutoPenSize); } TDrawDocument::~TDrawDocument() { delete AutoLine; delete Lines; delete UndoLine; }
The step16dv.h file contains declarations of the properties and methods for the document class of the drawing application:
DECLARE_AUTOCLASS(TDrawDocument) AUTOPROP(PenSize, GetPenSize, SetPenSize, short, ) AUTOPROP(PenColor, GetPenColor, SetPenColor, long, ) AUTOFUNC2V(AddPoint, AddPoint, short, short, ) AUTOFUNC0V(AddLine, AddLine, ) AUTOFUNC0V(ClearLine,ClearLine, )To define properties and methods for the document class, use the DEFINE_AUTOCLASS macro.
DEFINE_AUTOCLASS(TDrawDocument) EXPOSE_PROPRW(PenSize, TAutoShort, "PenSize", "Current pen size", 0) EXPOSE_PROPRW(PenColor, TAutoLong, "PenColor", "Current pen color", 0) EXPOSE_METHOD(AddPoint, TAutoVoid, "AddPoint", "Add a point to the current line", 0) REQUIRED_ARG( TAutoShort, "X") REQUIRED_ARG( TAutoShort, "Y") EXPOSE_METHOD(AddLine, TAutoVoid, "AddLine", "Add current line into drawing", 0) EXPOSE_METHOD(ClearLine, TAutoVoid, "ClearLine", "Erases current line", 0) EXPOSE_APPLICATION( TDrawApp, "Application","Application object", 0) END_AUTOCLASS(TDrawDocument, tfNormal, "TDrawDoc", "Draw document class", 0)