Carapace

COM Collections: Example

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)

Click here to see a full description of the TypeLibrary class used above.

Contents Index Current topic: COM Related topics: objects, functions