Carapace

COM Events: Example

This example shows two COM objects which inter-communicate via 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:

  1. create the source and sink objects
  2. link the source and sink together -- to match up the events interfaces
  3. start the source thread which fires events
  4. wait for a bit
  5. stop the thread
  6. destroy the source and sink objects

Test Harness


    (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)

Script: 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 ())
    )

Script: 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