Putting all the previous elements together, the main program for an Automation server might look something like this:
define constant $my-class-id = make-GUID(...);
define method main-program () => ()
if (OLE-util-register-only?()) // [un]register and terminate
register-automation-server($my-class-id,
"Foo.Bar",
"Simple OLE Automation server");
else
initialize-my-application(); // create window etc.
// create and register the factory object:
with-class-factory (clsid: $my-class-id,
class: <my-dispatch-object>,
typeinfo: make(<disp-type-info>, ...))
// normal Windows event loop:
with-stack-structure (pmsg :: <PMSG>)
while(GetMessage(pmsg, $NULL-HWND, 0, 0))
TranslateMessage(pmsg);
DispatchMessage(pmsg);
end while;
end with-stack-structure;
end with-class-factory;
values()
end if;
end method main-program;
However, if the program uses DUIM to implement its user interface, the event loop will be provided by DUIM, so the main program will look something like:
define method main-program () => ()
if (OLE-util-register-only?()) // [un]register and terminate
register-automation-server($my-class-id, "Foo.Bar",
"a simple OLE Automation server example");
else
let frame = make(<my-frame>);
with-class-factory (clsid: $my-class-id,
class: <my-dispatch-object>,
typeinfo: ...))
start-frame(frame);
end with-class-factory;
end if;
end method main-program;
Some application programs can be used either interactively or by Automation control. In such a case, you might want to create a class factory only if the program was actually initiated by an Automation controller. For this purpose, you can do something like this:
... let factory = #f; if (OLE-util-automation?()) factory := make(<class-factory>, ...); end if; ... // body of program revoke-registration(factory); // does nothing if argument is #f ...