The following script defines a Carapace class, called Collect
which is a well-formed COM collection.
# File: collect.cpl
#
# an example COM collection
(class "Collection"
(guid "{67E12011-7662-11d3-815B-0050048C7269}")
(interface
(guid "{67E12012-7662-11d3-815B-0050048C7269}")
(properties
# private properties
(content List)
(contentType String)
# public properties
(Count Integer readOnly)
(NewEnum Unknown readOnly)
)
(methods
(Object Item ( (index Integer) ) )
(Object Add ( (entry Object) ) )
(NIL Remove ( (index Object) ) )
(Object New () )
(NIL print () )
(NIL Collection ( ) )
)
)
)
# define the methods
(defun NIL Collection::Collection ( )
(this.Count 0)
(this.content ())
(this.contentType "String") # default is a collection of strings
)
(defun Object Collection::Item ( (index Integer) )
(local (tmp List) (result Object) )
(set result ())
(set tmp this.content)
(while tmp
(set result (headOf tmp))
(set tmp (tailOf tmp))
(if (== index 0) (break) )
(set index (- index 1) )
)
(if (!= index 0) (throw (create Error 1 1 "index out of range")))
(return result)
)
# add an item to the front
(defun Object Collection::Add ( (entry Object) )
(if (typeOf entry this.contentType)
(do
(this.content (cons entry this.content))
(this.Count ( + (this.Count) 1))
)
(throw (create Error 1 1 "cannot add this type to the collection"))
)
)
# remove an entry
(defun NIL Collection::Remove ( (index Object) )
(throw (create Error 1 1 "Collection::Remove - not yet implemented"))
)
# create a new item and add to the front
(defun Object Collection::New ( )
(local (entry Object) )
(set entry (createAux this.contentType) )
(this.content (cons entry this.content))
(this.Count ( + (this.Count) 1))
(return entry)
)
(defun NIL Collection::print ()
(print "Collection")
(print (this.Count))
(print (this.content))
(return ())
)
To access such a collection from COM, this class needs to be put into a Type Library and registered with the COM system.
The following makes a type library to hold just our Collect class:
(global (::t TypeLibrary))
# the absolute path of the type library - by convention, they
# use a .tlb extension
#
(set ::t (create TypeLibrary (join (list ::InstallDir "/typelibs/collect.tlb"))))
(::t.name "Carapace Collection Example")
(::t.guid "{B30214B5-8BB0-11d3-8180-0050048C7269}")
(::t.major 1)
(::t.minor 0)
(::t.description "a collection example")
(::t.addType "Collect")
# other .addType calls would go here to add further types
# these are the two, generic Carapace servers which will load up
# any scripted class and become a COM server for the class
#
(::t.inprocServer "caracom.dll")
(::t.localServer "caracom.exe")
# name the script which *defines* the Collect methods -
# this must also *declare* the Collect class
#
(::t.script "collect.cpl")
# since the script 'collect.cpl' lives in the standard
# Carapace scripts directory there is no need to record
# any other path information -- if it lives in a different
# directory, set the path property for the TypeLibrary
# accordingly
# save the type library to disk
(::t.save)
# register the type library - this updates the system registry
(::t.register)
| Contents | Index | Current topic: COM | Related topics: objects, functions |