[ Pobierz całość w formacie PDF ]
.Once you have the dispatch ID,you can use it to call OlePropertyGet, OlePropertyPut, or OleFunction to access theserver objects properties and methods.Another way to use dispatch interfaces is to assign them to a Variant.This approachis taken by some VCL objects for properties or parameters whose values areinterfaces.The Variant type includes built-in support for calling dispatch interfaces,through its OlePropertyGet, OlePropertyPut, OleFunction, and OleProcedure methods,which correspond to the methods on a dispatch interface wrapper class.UsingVariants can be a bit slower than using the dispatch interface wrapper class, becausethe Variant methods dynamically look up the dispatch ID every time you call them.However, they have the advantage that you do not need to import the type library touse them.Warning Care must be taken when assigning an interface to a Variant instead of a dispatchinterface wrapper.While the wrapper automatically handles calls to AddRef andRelease, the Variant does not.Thus, for example, if you assign a Variant whose value isan interface to an interface wrapper, the interface wrapper does not call AddRef, butits destructor calls Release.Because of this, using Variants is not recommended exceptwhere they already appear as the property of a VCL object.For more information on dispatch interfaces, see Automation interfaces onpage 35-11.Handling events in an automation controllerIf you do not use a Component wrapper (or if the server uses COM+ events), youmust write the event sink code yourself.Handling Automation events programmaticallyBefore you can handle events, you must define an event sink.This is a class thatimplements the event dispatch interface that is defined in the server s type library.The event sink is a descendant of TEventDispatcher, which is a templatized class thatrequires two parameters, the class of your event sink and the GUID for the eventinterface that your event sink handles:class MyEventSinkClass: TEventDispatcher{.// declare the methods of DIID_TheServerEvents here}Once you have an instance of your event sink class, call its ConnectEvents method tolet the server know about your event sink.This method uses theIConnectionPointContainer and IConnectionPoint interfaces of the server to register theobject as an event sink.Now your object receives calls from the server when eventsoccur:pInterface = CoServerClassName.CreateRemote("Machine1");MyEventSinkClass ES;ES.ConnectEvents(pInterface);34-14 Dev el oper s Gui deCo n t r o l l i n g a n i mp o r t e d o b j e c tYou must terminate the connection before you free your event sink.To do this, callthe event sink s DisconnectEvents method:ES.DisconnectEvents(pInterface);Note You must be certain that the server has released its connection to your event sinkbefore you free it.Because you don t know how the server responds to the disconnectnotification initiated by DisconnectEvents, this may lead to a race condition if you freeyour event sink immediately after the call.TEventDispatcher guards against this foryou by maintaining its own reference count that is not decremented until the serverreleases the event sink s interface.Handling COM+ eventsUnder COM+, servers use a special helper object to generate events rather than a setof special interfaces (IConnectionPointContainer and IConnectionPoint).Because of this,you can t use an event sink that descends from TEventDispatcher.TEventDispatcher isdesigned to work with those interfaces, not COM+ event objects.Instead of defining an event sink, your client application defines a subscriber object.Subscriber objects, like event sinks, provide the implementation of the eventinterface.They differ from event sinks in that they subscribe to a particular eventobject rather than connecting to a server s connection point.To define a subscriber object, use the COM Object wizard, selecting the event object sinterface as the one you want to implement.The wizard generates an implementationunit with skeletal methods that you can fill in to create your event handlers.For moreinformation about using the COM Object wizard to implement an existing interface,see Using the COM object wizard on page 35-2.Note You may need to add the event object s interface to the registry using the wizard if itdoes not appear in the list of interfaces you can implement.Once you create the subscriber object, you must subscribe to the event object sinterface or to individual methods (events) on that interface.There are three types ofsubscriptions from which you can choose:" Transient subscriptions.Like traditional event sinks, transient subscriptions aretied to the lifetime of an object instance.When the subscriber object is freed, thesubscription ends and COM+ no longer forwards events to it." Persistent subscriptions.These are tied to the object class rather than a specificobject instance.When the event occurs, COM locates or launches an instance of thesubscriber object and calls its event handler.In-process objects (DLLs) use thistype of subscription." Per-user subscriptions.These subscriptions provide a more secure version oftransient subscriptions.Both the subscriber object and the server object that firesevents must be running under the same user account on the same machine.Cr eat i ng COM c l i ent s 34-15Cr e a t i n g Cl i e n t s f o r s e r v e r s t h a t d o n o t h a v e a t y p e l i b r a r yTo subscribe to an event object, use the global RegisterComPlusEventSubscriptionfunction.Note Objects that subscribe to COM+ events must be installed in a COM+ application.Creating Clients for servers that do not have a type librarySome older COM technologies, such as object linking and embedding (OLE), do notprovide type information in a type library.Instead, they rely on a standard set ofpredefined interfaces.To write clients that host such objects, you can use theTOleContainer component.This component appears on the System page of thecomponent palette.TOleContainer acts as a host site for an Ole2 object.It implements the IOleClientSiteinterface and, optionally, IOleDocumentSite.Communication is handled using OLEverbs.To use TOleContainer,1 Place a TOleContainer component on your form.2 Set the AllowActiveDoc property to true if you want to host an Active document.3 Set the AllowInPlace property to indicate whether the hosted object should appearin the TOleContainer, or in a separate window.4 Write event handlers to respond when the object is activated, deactivated, moved,or resized.5 To bind the TOleContainer object at design time, right click and choose InsertObject.In the Insert Object dialog, choose a server object to host.6 To bind the TOleContainer object at runtime, you have several methods to choosefrom, depending on how you want to identify the server object.These includeCreateObject, which takes a program id, CreateObjectFromFile, which takes thename of a file to which the object has been saved, CreateObjectFromInfo, whichtakes a struct containing information on how to create the object, orCreateLinkToFile, which takes the name of a file to which the object was saved andlinks to it rather than embeds it
[ Pobierz całość w formacie PDF ]