This example shows two COM objects which inter-communicate via COM events:
EventSource which generates COM events
EventSink which receives COM events
It also illustrates the use of the comLink
function which links the source and sink together.
For each COM object, we make separate COM servers -- these can be either in-process servers (i.e. dynamic link libraries) or local servers (which run as their own process).
| progID | script | in-proc server | local server | description |
|---|---|---|---|---|
| Carapace.EventSource | comsource.cpl | carasource.dll | carasource.exe | The EventSource object contains a thread which, once started, repeatedly displays a message box and then fires an event. |
| Carapace.EventSink | comsink.cpl | carasink.dll | carasink.exe | Whenever the EventSink object receives an event, it displays the text received in a message box. |
A small test harness shown below shows the following stages:
(global (::source Dispatch) (::sink Dispatch))
(printAux "creating source\n")
(set ::source (create Dispatch "Carapace.EventSource" "LocalServer"))
(printAux "creating sink\n")
(set ::sink (create Dispatch "Carapace.EventSink" "LocalServer"))
(printAux "linking\n")
(comLink ::source ::sink )
(printAux "starting...\n")
(::source.start)
(sleep 15000)
(printAux "stopping...\n")
(::source.stop)
(printAux "destroying...\n")
(unset ::source)
(unset ::sink)
comsource.cpl
# File: comsource.cpl
#
# $Id: comeventeg.htm,v 1.3 2002/01/29 14:52:21 ibi Exp $ (c) 1999-2001 Carapace Communications Ltd
#
# Example COM server having an events interface
(class EventSource
(guid "{0F2DD480-AA9C-11D5-8483-0050048C7269}")
(interface EventSource
(guid "{0F2DD481-AA9C-11D5-8483-0050048C7269}")
(progId "Carapace.EventSource")
(major 1)
(minor 0)
(properties
(thread Thread)
)
(methods
(NIL EventSource ())
(NIL ~EventSource ())
(NIL start ())
(NIL stop ())
)
)
(interface EventSourceEvents
(direction out)
(guid "{0F2DD482-AA9C-11D5-8483-0050048C7269}")
(progId "Carapace.EventSourceEvents")
(major 1)
(minor 0)
(methods
(NIL fire ( (info String) ) )
)
)
)
(defun NIL EventSource::EventSource ()
(printAux (threadId) " EventSource created\n")
)
(defun NIL EventSource::~EventSource ()
(this.stop)
)
(defun NIL EventSource::start ()
(local (conns List)
(strm ComStream)
)
# we pass this object to the thread across a COM stream so that
# any remote COM connections to this object are correctly marshalled
# across the thread boundary
#
(this.thread (create Thread "runner" (list (quote runner) (create ComStream this))))
)
(defun NIL EventSource::stop ()
(this.thread ())
)
(defun NIL runner ( (strm ComStream) )
(local (disp Dispatch)
(n Integer)
(max Integer)
(msg String)
(err Error)
)
(try
(do
# get the outbound interface Carapace.EventSourceEvents
(set disp (getInterface strm.dispatch "{0F2DD482-AA9C-11D5-8483-0050048C7269}"))
(set max 10)
(set n 0)
(while (< n max)
(sleep 1000)
(set msg ("Hello ".+ n.string))
(printAux "Source: firing '" msg "'\n")
(messageBox ("firing data '".+ msg "'") "Source" 73728)
(disp.fire msg)
(set n (+ n 1))
)
)
(catch -1
(messageBox ("EventDemo (runner thread): ".+ err.string))
)
)
)
(defun NIL register ()
(local (t TypeLibrary))
# we are going to make DLL and Local servers
(load "cservgen.cpl")
(makeComServer "carasource.dll")
(makeComServer "carasource.exe")
(set t (create TypeLibrary (join (list ::InstallDir "/typelibs/carasource.tlb"))))
(t.name "carapace events")
(t.guid "{0F2DD483-AA9C-11D5-8483-0050048C7269}")
(t.major 1)
(t.minor 0)
(t.description "Carapace event source library")
(t.addType "EventSource")
(t.localServer "carasource.exe")
(t.inprocServer "carasource.dll")
(t.script "comsource.cpl")
(t.save)
(t.register)
(return ())
)
comsink.cpl
# File: comsink.cpl
#
# $Id: comeventeg.htm,v 1.3 2002/01/29 14:52:21 ibi Exp $ (c) 1999-2001 Carapace Communications Ltd
#
# Sink for testing COM events
(class EventSink
(guid "{CCB1C9E2-AA02-11D5-8482-0050048C7269}")
(interface
(progId "Carapace.EventSink")
(guid "{CCB1C9E3-AA02-11D5-8482-0050048C7269}")
(major 1)
(minor 0)
(methods
(NIL EventSink ())
)
)
(interface Events
# this is Carapace.EventSourceEvents
(guid "{0F2DD482-AA9C-11D5-8483-0050048C7269}")
(progId "Carapace.EventSourceEvents")
(major 1)
(minor 0)
(methods
(NIL fire ( (info String) ) )
)
)
)
(defun NIL EventSink::EventSink ()
(printAux (threadId) " EventSink created\n")
)
(defun NIL EventSink:Events::fire ( (info String) )
(messageBox ("received '".+ info "'") "Sink" 73728)
(printAux "Received: '" info "'\n")
)
(defun NIL register ()
(local (t TypeLibrary))
# we are going to make DLL and Local servers
(load "cservgen.cpl")
(makeComServer "carasink.exe")
(makeComServer "carasink.dll")
(set t (create TypeLibrary (join (list ::InstallDir "/typelibs/carasink.tlb"))))
(t.name "Carapace sink")
(t.guid "{CCB1C9E0-AA02-11D5-8482-0050048C7269}")
(t.major 1)
(t.minor 0)
(t.description "Carapace event sink library")
(t.addType "EventSink")
(t.localServer "carasink.exe")
(t.inprocServer "carasink.dll")
(t.script "comsink.cpl")
(t.save)
(t.register)
(return ())
)
| Contents | Index | Current topic: COM | Related topics: objects, functions |