import: tcom-3.10b9
authorPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 29 Jan 2009 22:22:19 +0000 (22:22 +0000)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 29 Jan 2009 22:22:19 +0000 (22:22 +0000)
108 files changed:
CHANGES
demos/Banking/Banking.idl [moved from samples/Banking/Banking.idl with 100% similarity]
demos/Banking/client.tcl [moved from samples/Banking/client.tcl with 100% similarity]
demos/chart.tcl [moved from samples/chart.tcl with 93% similarity]
demos/events.tcl [moved from samples/events.tcl with 85% similarity]
demos/excel.tcl [moved from samples/excel.tcl with 95% similarity]
demos/sendkeys.tcl [moved from samples/sendkeys.tcl with 86% similarity]
doc/Makefile
doc/article2html.xsl
doc/refentry2html.xsl
doc/server.html [deleted file]
doc/server.xml
doc/tcom.n.html [deleted file]
doc/tcom.n.xml
doc/xslt.tcl
lib/Banking/Banking.tlb [deleted file]
lib/Banking/pkgIndex.tcl
lib/Banking/server.itcl
lib/Banking/server.tcl
lib/TclScript/TclScript.dll
lib/TclScript/TclScript.itcl
lib/TclScript/TclScript.tlb
lib/TclScript/pkgIndex.tcl
lib/TclScript/register.tcl
lib/TclScript/unregister.tcl
lib/tcom/pkgIndex.tcl
lib/tcom/tcom.dll
lib/tcom/tcom.tcl
lib/tcom/tcominproc.dll
lib/tcom/tcomlocal.exe
src/ActiveScriptError.cpp
src/ActiveScriptError.h
src/Arguments.cpp
src/Arguments.h
src/ComModule.cpp
src/ComModule.h
src/ComObject.cpp
src/ComObject.h
src/ComObjectFactory.cpp
src/ComObjectFactory.h
src/DispatchAdapter.cpp [new file with mode: 0644]
src/DispatchAdapter.h [new file with mode: 0644]
src/DispatchImpl.cpp [new file with mode: 0644]
src/DispatchImpl.h [new file with mode: 0644]
src/Extension.cpp
src/Extension.h
src/HandleSupport.cpp
src/HandleSupport.h
src/HashTable.h
src/InterfaceAdapter.cpp
src/InterfaceAdapter.h
src/InterfaceAdapterVtbl.cpp
src/Makefile
src/NativeValue.cpp [new file with mode: 0644]
src/NativeValue.h [new file with mode: 0644]
src/Reference.cpp
src/Reference.h
src/RegistryKey.cpp
src/RegistryKey.h
src/Singleton.h
src/SupportErrorInfo.cpp
src/SupportErrorInfo.h
src/TclInterp.cpp
src/TclInterp.h
src/TclModule.cpp
src/TclModule.h
src/TclObject.cpp
src/TclObject.h
src/TclScript.cpp
src/TclScriptVersion.rc
src/ThreadLocalStorage.h
src/TypeInfo.cpp
src/TypeInfo.h
src/TypeLib.cpp
src/TypeLib.h
src/Uuid.cpp
src/Uuid.h
src/bindCmd.cpp
src/buildNumber.h
src/configureCmd.cpp
src/dllmain.cpp
src/dllserver.dsp
src/dllserverVersion.rc
src/exemain.cpp
src/exeserverVersion.rc
src/foreachCmd.cpp
src/importCmd.cpp
src/infoCmd.cpp
src/main.cpp
src/mutex.h
src/naCmd.cpp
src/nullCmd.cpp
src/objectCmd.cpp
src/refCmd.cpp
src/shortPathNameCmd.cpp
src/tclRunTime.h
src/tcom.dsp
src/tcomApi.h
src/tcomVersion.rc
src/typelibCmd.cpp
src/variantCmd.cpp
src/version.h
tests/all.tcl
tests/array.test
tests/eval.test
tests/foreach.test
tests/namedarg.test
tests/ref.test

diff --git a/CHANGES b/CHANGES
index 6edeffe7f36a239b70e86884e6340f31fe6b5907..99dedce6475a72c4ce12dd868aae4381df3718fa 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,16 @@
+Version 3.10
+- Workaround type mismatch error when passing VT_UINT | VT_BYREF parameters.
+- Added support for 64-bit integer arguments.
+- On type mismatch errors, the error result now indicates which argument cannot
+  be converted.
+- Added missing conversions from VT_DISPATCH | VT_BYREF, VT_UNKNOWN | VT_BYREF,
+  VT_VARIANT | VT_BYREF, and VT_ARRAY | VT_BYREF arguments.
+- Load type library using neutral language argument.
+- Replace -method option with -call option.
+- Fixed invalid pointer error when returned EXCEPINFO contains null
+  description.
+- Fixed passing SAFEARRAY(short) parameters.
+
 Version 3.9
 - Fixed defect where eval may trigger premature destruction of handle internal
   representation.
similarity index 93%
rename from samples/chart.tcl
rename to demos/chart.tcl
index fbfd15f6ee91ae04e0497acdab3101338a5402c7..b25174268a170cc9c2215b8c7ad8ddfe05e0d54c 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: chart.tcl,v 1.5 2004/02/26 18:07:38 cthuang Exp $
+# $Id: chart.tcl 5 2005-02-16 14:57:24Z cthuang $
 #
 # This example controls Excel.  It performs the following steps.
 #       - Start Excel application.
similarity index 85%
rename from samples/events.tcl
rename to demos/events.tcl
index 32e02d3daa2b401d5de34236bd8960570be534ce..e8190b4cb4ccd96e25dcd260dfd3fc0536bdb937 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: events.tcl,v 1.2 2001/06/30 18:42:58 cthuang Exp $
+# $Id: events.tcl 5 2005-02-16 14:57:24Z cthuang $
 
 package require tcom
 
similarity index 95%
rename from samples/excel.tcl
rename to demos/excel.tcl
index b00459e540c0cd8b112ebd7bbb52a30bb9f24b4e..69fe1b55dcab20b0077e70ed809327731a7469d0 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: excel.tcl,v 1.10 2002/09/27 22:11:03 cthuang Exp $
+# $Id: excel.tcl 5 2005-02-16 14:57:24Z cthuang $
 #
 # This example controls Excel.  It performs the following steps.
 #       - Start Excel application.
similarity index 86%
rename from samples/sendkeys.tcl
rename to demos/sendkeys.tcl
index e2705ab414c54a95bcb37f0326bf7e7fd7127b33..c485b1bb0593983b0c0defd3d25261d759066fa0 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: sendkeys.tcl,v 1.3 2001/06/30 18:42:58 cthuang Exp $
+# $Id: sendkeys.tcl 5 2005-02-16 14:57:24Z cthuang $
 #
 # This example demonstrates how to send keys to Windows applications.
 # It requires Windows Script Host 2.0 installed on the system.
index 40f59cf873361217afc61f596b4c8438176cd87b..e95879dbf5a68f97bcd6346a3fcdc6c0a702db15 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.6 2002/04/17 22:07:57 cthuang Exp $
+# $Id: Makefile 5 2005-02-16 14:57:24Z cthuang $
 
 all: tcom.n.html server.html
 
index 06c72addf85e4319d33cf22c53edf696943f344e..30c126dde753288b55c2f19a81de51ec27bba7d4 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!-- $Id: article2html.xsl,v 1.11 2002/06/29 15:34:52 cthuang Exp $ -->
+<!-- $Id: article2html.xsl 7 2005-02-24 05:18:47Z cthuang $ -->
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" encoding="UTF-8"
    doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
@@ -8,33 +8,35 @@
   <xsl:template match="article">
     <html>
       <head>
-        <title><xsl:value-of select="artheader/title"/></title>
+        <title><xsl:value-of select="title"/></title>
        <style type="text/css">
          .command
          { font-style: normal; font-weight: bold; }
          .option
          { font-style: normal; font-weight: bold; }
-         .replaceable
-         { font-style: italic; font-weight: normal; }
-         .listing
-         { font-size: 9pt; }
+         .programlisting
+         { background-color: #E8E8E8; font-size: 9pt; }
+         .screen
+         { background-color: #FFFFCC; }
        </style>
       </head>
       <body>
-        <h1><xsl:value-of select="artheader/title"/></h1>
        <xsl:apply-templates/>
       </body>
     </html>
   </xsl:template>
 
-  <xsl:template match="artheader"/>
+  <xsl:template match="article/title">
+    <h1><xsl:value-of select="text()"/></h1>
+  </xsl:template>
+
+  <xsl:template match="articleinfo"/>
 
   <xsl:template match="cmdsynopsis">
     <xsl:apply-templates/>
   </xsl:template>
 
   <xsl:template match="arg">
-    <var>
     <xsl:choose>
       <xsl:when test="@choice='plain'"></xsl:when>
       <xsl:otherwise>?</xsl:otherwise>
@@ -47,7 +49,6 @@
       <xsl:when test="@choice='plain'"></xsl:when>
       <xsl:otherwise>?</xsl:otherwise>
     </xsl:choose>
-    </var>
   </xsl:template>
 
   <xsl:template match="option">
   </xsl:template>
 
   <xsl:template match="programlisting">
-    <table bgcolor="#CCCCCC" width="100%"><tr><td><pre class="listing">
+    <pre class="programlisting">
     <xsl:apply-templates/>
-    </pre></td></tr></table>
+    </pre>
   </xsl:template>
 
   <xsl:template match="screen">
-    <table bgcolor="#FFFFCC" width="100%"><tr><td><pre>
+    <pre class="screen">
     <xsl:apply-templates/>
-    </pre></td></tr></table>
+    </pre>
   </xsl:template>
 
   <xsl:template match="userinput">
index 324d286af0d07647c7297dee91184941333e2010..dc0858c1026400e55a7d29a613e433486c67666a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!-- $Id: refentry2html.xsl,v 1.16 2002/06/29 15:34:52 cthuang Exp $ -->
+<!-- $Id: refentry2html.xsl 7 2005-02-24 05:18:47Z cthuang $ -->
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" encoding="UTF-8"
    doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
       <head>
         <title><xsl:value-of select="refnamediv/refname"/></title>
        <style type="text/css">
+         table
+         { margin-left: 2em; border-collapse: collapse; }
+         th
+         { color: white; background-color: navy; }
+         .cell
+         { border: 2px solid navy; padding: 1px 4px 1px 4px; }
          .command
          { font-style: normal; font-weight: bold; }
          .option
          { font-style: normal; font-weight: bold; }
-         .parameter
-         { font-style: italic; font-weight: normal; }
+         .programlisting
+         { background-color: #E8E8E8; }
        </style>
       </head>
       <body>
@@ -26,7 +32,7 @@
     </html>
   </xsl:template>
 
-  <xsl:template match="docinfo"/>
+  <xsl:template match="refentryinfo"/>
 
   <xsl:template match="refmeta"/>
 
@@ -42,7 +48,6 @@
   </xsl:template>
 
   <xsl:template match="arg">
-    <var>
     <xsl:choose>
       <xsl:when test="@choice='plain'"></xsl:when>
       <xsl:otherwise>?</xsl:otherwise>
       <xsl:when test="@choice='plain'"></xsl:when>
       <xsl:otherwise>?</xsl:otherwise>
     </xsl:choose>
-    </var>
+  </xsl:template>
+
+  <xsl:template match="replaceable">
+    <var><xsl:apply-templates/></var>
   </xsl:template>
 
   <xsl:template match="option">
   </xsl:template>
 
   <xsl:template match="table">
-    <blockquote>
-    <xsl:apply-templates/>
-    </blockquote>
+    <table class="cell">
+      <xsl:apply-templates/>
+    </table>
   </xsl:template>
 
   <xsl:template match="table/title">
-    <b><xsl:value-of select="."/></b><br/>
+    <caption><xsl:value-of select="."/></caption>
   </xsl:template>
 
   <xsl:template match="table/tgroup">
-    <table border="1">
     <xsl:apply-templates/>
-    </table>
   </xsl:template>
 
   <xsl:template match="thead">
   </xsl:template>
 
   <xsl:template match="thead/row/entry">
-    <td><b><xsl:value-of select="."/></b></td>
+    <th class="cell"><xsl:value-of select="."/></th>
   </xsl:template>
 
   <xsl:template match="tbody/row/entry">
-    <td><xsl:value-of select="."/></td>
+    <td class="cell"><xsl:value-of select="."/></td>
   </xsl:template>
 
   <xsl:template match="programlisting">
-    <table bgcolor="#CCCCCC" width="100%"><tr><td><pre>
+    <pre class="programlisting">
     <xsl:apply-templates/>
-    </pre></td></tr></table>
+    </pre>
   </xsl:template>
 
   <xsl:template match="*">
diff --git a/doc/server.html b/doc/server.html
deleted file mode 100644 (file)
index d4f1386..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>COM Object Implementation in Tcl</title>
-<style type="text/css">
-         .command
-         { font-style: normal; font-weight: bold; }
-         .option
-         { font-style: normal; font-weight: bold; }
-         .replaceable
-         { font-style: italic; font-weight: normal; }
-         .listing
-         { font-size: 9pt; }
-       </style>
-</head>
-<body>
-<h1>COM Object Implementation in Tcl</h1>
-  <h2>Introduction</h2>
-  <p>This article shows by example how to implement COM objects in
-  Tcl with the <span class="command">tcom</span> extension.  It shows how an object
-  can be implemented by an [incr Tcl] class or in just plain Tcl.
-  </p>
-  <div>
-   
-    <img src="bankingClassDiagram.png">
-   
-  </div>
-  <p>The class diagram shows the structure of server objects which implement
-   two COM interfaces.  The IAccount interface defines a Balance property, and
-   Deposit and Withdraw methods which modify the balance.  The Account class
-   implements the IAccount interface by delegating its operations to the
-   AccountImpl class, which is written in [incr Tcl] and actually implements
-   the operations.  The IBank interface defines a method to create an account.
-   Following the same pattern, the Bank class implements the IBank interface by
-   delegating to the BankImpl class, which provides the actual implementation.
-  </p>
-  <h2>Write MIDL Specification</h2>
-  <p> The file <tt>Banking.idl</tt> contains the MIDL
-   specification for the COM interfaces and classes.  The interfaces can be
-   declared <tt>dual</tt> because <span class="command">tcom</span> can
-   implement objects whose operations are invoked through the IDispatch
-   interface or the virtual function table.</p>
-  <table bgcolor="#CCCCCC" width="100%"><tr><td><pre class="listing">
-
-import "oaidl.idl";
-import "ocidl.idl";
-
-        [
-                object,
-                uuid(0A0059C4-E0B0-11D2-942A-00C04F7040AB),
-                dual,
-                helpstring("IAccount Interface"),
-                pointer_default(unique)
-        ]
-        interface IAccount: IDispatch
-        {
-                [id(1), propget, helpstring("property Balance")]
-                HRESULT Balance([out, retval] long *pValue);
-
-                [id(2), helpstring("method Deposit")]
-                HRESULT Deposit([in] long amount);
-
-                [id(3), helpstring("method Withdraw")]
-                HRESULT Withdraw([in] long amount);
-        };
-
-        [
-                object,
-                uuid(0A0059C4-E0B0-11D2-942A-00C04F7040AC),
-                dual,
-                helpstring("IBank Interface"),
-                pointer_default(unique)
-        ]
-        interface IBank: IDispatch
-        {
-                [id(1), helpstring("method CreateAccount")]
-                HRESULT CreateAccount([out, retval] IAccount **pAccount);
-        };
-
-[
-        uuid(0A0059B8-E0B0-11D2-942A-00C04F7040AB),
-        version(1.0),
-        helpstring("Banking 1.0 Type Library")
-]
-library Banking
-{
-        importlib("stdole32.tlb");
-
-        [
-                uuid(0A0059C5-E0B0-11D2-942A-00C04F7040AB),
-                helpstring("Account Class")
-        ]
-        coclass Account
-        {
-                [default] interface IAccount;
-        };
-
-        [
-                uuid(0A0059C5-E0B0-11D2-942A-00C04F7040AC),
-                helpstring("Bank Class")
-        ]
-        coclass Bank
-        {
-                [default] interface IBank;
-        };
-};
-</pre></td></tr></table>
-  <h2>Create Type Library</h2>
-  <p>Run this command to generate a type library file
-  <tt>Banking.tlb</tt> from the MIDL specification.</p>
-  <table bgcolor="#FFFFCC" width="100%"><tr><td><pre>
-
-<kbd>midl Banking.idl</kbd>
-</pre></td></tr></table>
-  <h2>Create Tcl Package</h2>
-  <p>The <span class="command">tcom</span> server implementation depends on the Tcl
-  package mechanism to provide the code that implements specific COM interfaces.
-  In this example, we'll create a package named Banking, which provides code
-  that implements the IBank and IAccount interfaces.</p>
-
-  <p>Create a directory for the package by making a subdirectory named
-  <tt>Banking</tt> under one of the directories in the
-  <tt>auto_path</tt> variable.  Create a
-  <tt>pkgIndex.tcl</tt> file in the package directory.</p>
-<table bgcolor="#CCCCCC" width="100%"><tr><td><pre class="listing">
-
-package ifneeded Banking 1.0 [list source [file join $dir server.itcl]]
-</pre></td></tr></table>
-
-  <p>Copy the <tt>Banking.tlb</tt> type library file into the
-  package directory.</p>
-
-  <p>Create the following <tt>server.itcl</tt> file in the package
-  directory.  This file defines [incr Tcl] classes that implement the
-  IBank and IAccount interfaces.</p>
-
-  <table bgcolor="#CCCCCC" width="100%"><tr><td><pre class="listing">
-
-package provide Banking 1.0
-
-package require Itcl
-namespace import ::itcl::*
-
-package require tcom
-::tcom::import [file join [file dirname [info script]] Banking.tlb]
-
-class AccountImpl {
-    private variable balance 0
-
-    public method _get_Balance {} {
-        return $balance
-    }
-
-    public method Deposit {amount} {
-        set balance [expr $balance + $amount]
-    }
-
-    public method Withdraw {amount} {
-        set balance [expr $balance - $amount]
-    }
-}
-
-class BankImpl {
-    public method CreateAccount {} {
-        set accountImpl [AccountImpl #auto]
-        return [::tcom::object create ::Banking::Account \
-            [code $accountImpl] {delete object}]                                ;# 1
-    }
-}
-
-::tcom::object registerfactory ::Banking::Bank {BankImpl #auto} {delete object} ;# 2
-</pre></td></tr></table>
-  
-  <p>On line 1, the <span class="command">::tcom::object create</span> command creates
-  a COM object that implements the IAccount interface by delegating its
-  operations to an [incr Tcl] object specified by an [incr Tcl] object handle.
-  Interface methods are mapped to a method with the same name.  Interface
-  properties are mapped to methods named by prepending <tt>_get_</tt>
-  and <tt>_set_</tt> to the property name.  When the last reference
-  to the COM object is released, <span class="command">tcom</span> invokes the
-  <tt>delete object</tt> command with the [incr Tcl] object handle as
-  an additional argument to clean up the [incr Tcl] object.</p>
-  
-  <p>Line 2 creates a factory for creating instances of the Bank class and
-   registers the factory with COM.  To create a COM object, the factory invokes
-   a command which returns a handle to an [incr Tcl] object that implements the
-   operations.  In this example, the factory invokes the <tt>BankImpl
-   #auto</tt> command which creates a BankImpl [incr Tcl] object and
-   returns a handle to that object.  To clean up when the COM object is
-   destroyed, <span class="command">tcom</span> invokes the <tt>delete
-   object</tt> command with the [incr Tcl] object handle as an additional
-   argument.</p>
-  <h2>Register Server</h2>
-  <p>Run these Tcl commands to create entries in the Windows registry
-  required by COM and the <span class="command">tcom</span> server implementation.
-  </p>
-  <table bgcolor="#FFFFCC" width="100%"><tr><td><pre>
-
-<kbd>package require tcom</kbd>
-<kbd>::tcom::server register Banking.tlb</kbd>
-</pre></td></tr></table>
-  <h2>Implement Client</h2>
-  <p>The <tt>client.tcl</tt> script implements a simple client.
-  It gets a reference to an object that implements the bank interface, creates
-  an account, and performs some operations on the account.</p>
-  <table bgcolor="#CCCCCC" width="100%"><tr><td><pre class="listing">
-
-package require tcom
-
-set bank [::tcom::ref createobject "Banking.Bank"]
-set account [$bank CreateAccount]
-puts [$account Balance]
-$account Deposit 20
-puts [$account Balance]
-$account Withdraw 10
-puts [$account Balance]
-</pre></td></tr></table>
-  <h2>Implement Objects In Plain Tcl</h2>
-   <p>You can implement objects in plain Tcl.  The servant command passed to
-    the <span class="command">::tcom::object create</span> command can be the name of any
-    object-style command.  Similarly, the factory command passed to the
-    <span class="command">::tcom::object registerfactory</span> command can return the
-    name of any object-style command.  The following Tcl script defines the
-    procedures <tt>accountImpl</tt> and <tt>bankImpl</tt>,
-    which have parameters in the style of a method name followed by any
-    arguments.</p>
-   <table bgcolor="#CCCCCC" width="100%"><tr><td><pre class="listing">
-
-package provide Banking 1.0
-
-package require tcom
-::tcom::import [file join [file dirname [info script]] Banking.tlb]
-
-proc accountImpl {method args} {
-    global balance
-
-    switch -- $method {
-        _get_Balance {
-            return $balance
-        }
-
-        Deposit {
-            set amount [lindex $args 0]
-            set balance [expr $balance + $amount]
-        }
-
-        Withdraw {
-            set amount [lindex $args 0]
-            set balance [expr $balance - $amount]
-        }
-        
-        default {
-            error "unknown method $method $args"
-        }
-    }
-}
-
-proc bankImpl {method args} {
-    global balance
-
-    switch -- $method {
-        CreateAccount {
-            set balance 0
-            return [::tcom::object create ::Banking::Account accountImpl]
-        }
-        
-        default {
-            error "unknown method $method $args"
-        }
-    }
-}
-
-::tcom::object registerfactory ::Banking::Bank {list bankImpl}
-</pre></td></tr></table>
-</body>
-</html>
index fec1814e97d7806f8e793ef8852cc821d45c6615..874115925d2616a954842e4029732f5936ac738c 100644 (file)
@@ -1,12 +1,13 @@
 <?xml version="1.0"?>
-<!-- $Id: server.xml,v 1.23 2002/06/29 15:34:52 cthuang Exp $ -->
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "docbookx.dtd">
+<!-- $Id: server.xml 12 2005-04-14 14:01:20Z cthuang $ -->
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <article>
- <artheader>
 <date>$Date: 2002/06/29 15:34:52 $</date>
-  <releaseinfo>$Revision: 1.23 $</releaseinfo>
-  <title>COM Object Implementation in Tcl</title>
- </artheader>
+ <title>COM Object Implementation in Tcl</title>
<articleinfo>
+  <date>$Date: 2005-04-14 10:01:20 -0400 (Thu, 14 Apr 2005) $</date>
+  <releaseinfo>$Revision: 12 $</releaseinfo>
+ </articleinfo>
  <sect1>
   <title>Introduction</title>
   <para>This article shows by example how to implement COM objects in
@@ -36,7 +37,6 @@
    implement objects whose operations are invoked through the IDispatch
    interface or the virtual function table.</para>
   <programlisting>
-
 import "oaidl.idl";
 import "ocidl.idl";
 
@@ -106,7 +106,6 @@ library Banking
   <para>Run this command to generate a type library file
   <literal>Banking.tlb</literal> from the MIDL specification.</para>
   <screen>
-
 <userinput>midl Banking.idl</userinput>
 </screen>
  </sect1>
@@ -122,7 +121,6 @@ library Banking
   <literal>auto_path</literal> variable.  Create a
   <literal>pkgIndex.tcl</literal> file in the package directory.</para>
 <programlisting>
-
 package ifneeded Banking 1.0 [list source [file join $dir server.itcl]]
 </programlisting>
 
@@ -134,7 +132,6 @@ package ifneeded Banking 1.0 [list source [file join $dir server.itcl]]
   IBank and IAccount interfaces.</para>
 
   <programlisting>
-
 package provide Banking 1.0
 
 package require Itcl
@@ -196,7 +193,6 @@ class BankImpl {
   required by COM and the <command>tcom</command> server implementation.
   </para>
   <screen>
-
 <userinput>package require tcom</userinput>
 <userinput>::tcom::server register Banking.tlb</userinput>
 </screen>
@@ -207,7 +203,6 @@ class BankImpl {
   It gets a reference to an object that implements the bank interface, creates
   an account, and performs some operations on the account.</para>
   <programlisting>
-
 package require tcom
 
 set bank [::tcom::ref createobject "Banking.Bank"]
@@ -230,7 +225,6 @@ puts [$account Balance]
     which have parameters in the style of a method name followed by any
     arguments.</para>
    <programlisting>
-
 package provide Banking 1.0
 
 package require tcom
diff --git a/doc/tcom.n.html b/doc/tcom.n.html
deleted file mode 100644 (file)
index 518d762..0000000
+++ /dev/null
@@ -1,598 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>tcom</title>
-<style type="text/css">
-         .command
-         { font-style: normal; font-weight: bold; }
-         .option
-         { font-style: normal; font-weight: bold; }
-         .parameter
-         { font-style: italic; font-weight: normal; }
-       </style>
-</head>
-<body>
-<h2>Name</h2>
-<p>tcom -- Access COM objects from Tcl</p>
- <h2>Synopsis</h2>
-  
-   <span class="command">package require tcom</span>
-   <var>?<span class="option">3.9</span>?</var>
-   <br>
-   <span class="command">::tcom::ref</span>
-   <span class="command">createobject</span>
-   <var>?<span class="option">-inproc</span>?</var>
-   <var>?<span class="option">-local</span>?</var>
-   <var>?<span class="option">-remote</span>?</var>
-   <var>?<span class="option">-clsid</span>?</var>
-   <var>progID</var>
-   <var>?hostName?</var>
-   <br>
-   <span class="command">::tcom::ref</span>
-   <span class="command">getactiveobject</span>
-   <var>?<span class="option">-clsid</span>?</var>
-   <var>progID</var>
-   <br>
-   <span class="command">::tcom::ref</span>
-   <span class="command">getobject</span>
-   <var>pathName</var>
-   <br>
-   <span class="command">::tcom::ref</span>
-   <span class="command">equal</span>
-   <var>handle1</var>
-   <var>handle2</var>
-   <br>
-   <var>handle</var>
-   <var>?<span class="option">-method</span>?</var>
-   <var>method</var>
-   <var>?argument ...?</var>
-   <br>
-   <var>handle</var>
-   <var><span class="option">-namedarg</span></var>
-   <var>method</var>
-   <var>?argumentName argumentValue ...?</var>
-   <br>
-   <var>handle</var>
-   <var>?<span class="option">-get</span>?</var>
-   <var>?<span class="option">-set</span>?</var>
-   <var>property</var>
-   <var>?index ...?</var>
-   <var>?value?</var>
-   <br>
-   <span class="command">::tcom::foreach</span>
-   <var>varname</var>
-   <var>collectionHandle</var>
-   <var>body</var>
-   <br>
-   <span class="command">::tcom::foreach</span>
-   <var>varlist</var>
-   <var>collectionHandle</var>
-   <var>body</var>
-   <br>
-   <span class="command">::tcom::bind</span>
-   <var>handle</var>
-   <var>command</var>
-   <var>?eventIID?</var>
-   <br>
-   <span class="command">::tcom::unbind</span>
-   <var>handle</var>
-   <br>
-   <span class="command">::tcom::na</span>
-   <br>
-   <span class="command">::tcom::info interface</span>
-   <var>handle</var>
-   <br>
-   <span class="command">::tcom::configure</span>
-   <var>name</var>
-   <var>?value?</var>
-   <br>
-   <span class="command">::tcom::import</span>
-   <var>typeLibrary</var>
-   <var>?namespace?</var>
-   <br>
-  
-  <h2>Description</h2>
-  <p>The <span class="command">tcom</span> package provides commands to access COM
-  objects through IDispatch and IUnknown derived interfaces.</p>
-  <h2>Commands</h2>
-  <dl>
-   
-    <dt>
-     
-      <span class="command">::tcom::ref</span>
-      <span class="command">createobject</span>
-      <var>?<span class="option">-inproc</span>?</var>
-      <var>?<span class="option">-local</span>?</var>
-      <var>?<span class="option">-remote</span>?</var>
-      <var>?<span class="option">-clsid</span>?</var>
-      <var>progID</var>
-      <var>?hostName?</var>
-      <br>
-      <span class="command">::tcom::ref</span>
-      <span class="command">getactiveobject</span>
-      <var>?<span class="option">-clsid</span>?</var>
-      <var>progID</var>
-     
-    </dt>
-    <dd>
-     <p>These commands return a handle representing a reference to a COM
-     object through an interface pointer.  The handle can be used as a Tcl
-     command to invoke operations on the object.  In practice, you should store
-     the handle in a Tcl variable or pass it as an argument to another command.
-     </p>
-     <p>References to COM objects are automatically released.  If you store
-     the handle in a local variable, the reference is released when execution
-     leaves the variable's scope.  If you store the handle in a global
-     variable, you can release the reference by unsetting the variable, setting
-     the variable to another value, or exiting the Tcl interpreter.</p>
-     <p>The <span class="command">createobject</span> subcommand creates an instance
-     of the object.  The <span class="option">-inproc</span> option requests the object be
-     created in the same process.  The <span class="option">-local</span> option requests
-     the object be created in another process on the local machine.  The
-     <span class="option">-remote</span> option requests the object be created on a remote
-     machine.  The <var>progID</var> parameter is the programmatic
-     identifier of the object class.  Use the <span class="option">-clsid</span> option if
-     you want to specify the class using a class ID instead.  The
-     <var>hostName</var> parameter specifies the machine where you
-     want to create the object instance.</p>
-     <p>The <span class="command">getactiveobject</span> subcommand gets a reference
-     to an already existing object.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <span class="command">::tcom::ref</span>
-      <span class="command">getobject</span>
-      <var>pathName</var>
-     
-    </dt>
-    <dd>
-     <p>This command returns a reference to a COM object from a file.  The
-     <var>pathName</var> parameter is the full path and name of the
-     file containing the object.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <span class="command">::tcom::ref</span>
-      <span class="command">equal</span>
-      <var>handle1</var>
-      <var>handle2</var>
-     
-    </dt>
-    <dd>
-     <p>This command compares the interface pointers represented by two
-     handles for COM identity, returning 1 if the interface pointers refer to
-     the same COM object, or 0 if not.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <var>handle</var>
-      <var>?<span class="option">-method</span>?</var>
-      <var>method</var>
-      <var>?argument ...?</var>
-     
-    </dt>
-    <dd>
-     <p>This command invokes a method on the object represented by the
-     <var>handle</var>.  The return value of the method is returned
-     as a Tcl value.  A Tcl error will be raised if the method returns a
-     failure HRESULT code.  Parameters with the [in] attribute are passed by
-     value.  For each parameter with the [out] or [in, out] attributes, pass
-     the name of a Tcl variable as the argument.  After the method returns, the
-     variables will contain the output values.  In some cases where
-     <span class="command">tcom</span> cannot get information about the object's
-     interface, you may have to use the <span class="option">-method</span> option to
-     specify you want to invoke a method.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <var>handle</var>
-      <var><span class="option">-namedarg</span></var>
-      <var>method</var>
-      <var>?argumentName argumentValue ...?</var>
-     
-    </dt>
-    <dd>
-     <p>Use the <span class="option">-namedarg</span> option to invoke a method
-     with named arguments.  This only works with objects that implement
-     IDispatch.  You specify arguments by passing name and value pairs.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <var>handle</var>
-      <var>?<span class="option">-get</span>?</var>
-      <var>?<span class="option">-set</span>?</var>
-      <var>property</var>
-      <var>?index ...?</var>
-      <var>?value?</var>
-     
-    </dt>
-    <dd>
-     <p>This command gets or sets a property of the object represented by
-     the <var>handle</var>.  If you supply a
-     <var>value</var> argument, this command sets the named
-     property to the value, otherwise it returns the property value.  For
-     indexed properties, you must specify one or more
-     <var>index</var> values.  The command raises a Tcl error if
-     you specify an invalid property name or if you try to set a value that
-     cannot be converted to the property's type.  In some cases where
-     <span class="command">tcom</span> cannot get information about the object's
-     interface, you may have to use the <span class="option">-get</span> or
-     <span class="option">-set</span> option to specify you want to get or set a property
-     respectively.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <span class="command">::tcom::foreach</span>
-      <var>varname</var>
-      <var>collectionHandle</var>
-      <var>body</var>
-      <br>
-      <span class="command">::tcom::foreach</span>
-      <var>varlist</var>
-      <var>collectionHandle</var>
-      <var>body</var>
-     
-    </dt>
-    <dd>
-     <p>This command implements a loop where the loop variable(s) take on
-     values from a collection object represented by
-     <var>collectionHandle</var>.  In the simplest case, there
-     is one loop variable, <var>varname</var>.  The
-     <var>body</var> argument is a Tcl script.  For each
-     element of the collection, the command assigns the contents of the element
-     to <var>varname</var>, then calls the Tcl interpreter to
-     execute <var>body</var>.</p>
-     <p>In the general case, there can be more than one loop variable.
-     During each iteration of the loop, the variables of
-     <var>varlist</var> are assigned consecutive elements from
-     the collection.  Each element is used exactly once.  The total number of
-     loop iterations is large enough to use up all the elements from the
-     collection.  On the last iteration, if the collection does not contain
-     enough elements for each of the loop variables, empty values are used for
-     the missing elements.</p>
-     <p>The <span class="command">break</span> and <span class="command">continue</span>
-     statements may be invoked inside <var>body</var>, with the
-     same effect as in the <span class="command">for</span> command.  The
-     <span class="command">::tcom::foreach</span> command returns an empty string.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <span class="command">::tcom::bind</span>
-      <var>handle</var>
-      <var>command</var>
-      <var>?eventIID?</var>
-     
-    </dt>
-    <dd>
-     <p>This command specifies a Tcl command that will be executed when
-     events are received from an object.  The <var>command</var>
-     will be called with additional arguments: the event name and the event
-     arguments.  By default, the event interface is the default event source
-     interface of the object's class.  Use the <var>eventIID</var>
-     parameter to specify the IID of another event interface.  If an error
-     occurs while executing the command then the bgerror mechanism is used to
-     report the error.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <span class="command">::tcom::unbind</span>
-      <var>handle</var>
-     
-    </dt>
-    <dd>
-     <p>This command tears down all event connections to the object that
-     were set up by the <span class="command">::tcom::bind</span> command.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <span class="command">::tcom::na</span>
-     
-    </dt>
-    <dd>
-     <p>Objects that implement the IDispatch interface allow some method
-     parameters to be optional.  This command returns a token representing a
-     missing optional argument.  In practice, you would pass this token as a
-     method argument in place of a missing optional argument.</p>
-    </dd>
-   
-   
-    <dt>
-     
-      <span class="command">::tcom::info interface</span>
-      <var>handle</var>
-     
-    </dt>
-    <dd>
-     <p>This command returns a handle representing a description of the
-     interface exposed by the object.  The handle supports the following
-     commands.</p>
-     <dl>
-      
-       <dt>
-        
-         <var>interfaceHandle</var>
-        <span class="command">iid</span>
-        
-       </dt>
-       <dd>
-        <p>This command returns an interface identifier code.</p>
-       </dd>
-      
-      
-       <dt>
-        
-         <var>interfaceHandle</var>
-        <span class="command">methods</span>
-        
-       </dt>
-       <dd>
-       <p>This command returns a list of method descriptions for methods
-       defined in the interface.  Each method description is a list.  The
-       first element is the member ID.  The second element is the return type.
-       The third element is the method name.  The fourth element is a list of
-       parameter descriptions.</p>
-       </dd>
-      
-      
-       <dt>
-        
-         <var>interfaceHandle</var>
-        <span class="command">name</span>
-        
-       </dt>
-       <dd>
-        <p>This command returns the interface's name.</p>
-       </dd>
-      
-      
-       <dt>
-        
-         <var>interfaceHandle</var>
-        <span class="command">properties</span>
-        
-       </dt>
-       <dd>
-       <p>This command returns a list of property descriptions for
-       properties defined in the interface.  Each property description is a
-       list.  The first element is the member ID.  The second element is the
-       property read/write mode.  The third element is the property data type.
-       The fourth element is the property name.  If the property is an indexed
-       property, there is a fifth element which is a list of parameter
-       descriptions.</p>
-       </dd>
-      
-     </dl>
-    </dd>
-   
-   
-    <dt>
-     
-      <span class="command">::tcom::configure</span>
-      <var>name</var>
-      <var>?value?</var>
-     
-    </dt>
-    <dd>
-     <p>This command sets and retrieves options for the package.  If
-     <var>name</var> is supplied but no
-     <var>value</var> then the command returns the current
-     value of the given option.  If one or more pairs of
-     <var>name</var> and <var>value</var> are
-     supplied, the command sets each of the named options to the corresponding
-     value; in this case the return value is an empty string.</p>
-     <dl>
-      
-       <dt>
-        
-         <var><span class="option">-concurrency</span></var>
-        <var>?concurrencyModel?</var>
-        
-       </dt>
-       <dd>
-       <p>This option sets the concurrency model, which can be
-       <span class="option">apartmentthreaded</span> or <span class="option">multithreaded</span>.
-       The default is <span class="option">apartmentthreaded</span>.  You must configure
-       this option before performing any COM operations such as getting a
-       reference to an object.  After a COM operation has been done, changing
-       this option has no effect.</p>
-       </dd>
-      
-     </dl>
-    </dd>
-   
-  </dl>
-  <h2>Importing Type Library Information</h2>
-  
-   <span class="command">::tcom::import</span>
-   <var>typeLibrary</var>
-   <var>?namespace?</var>
-  
-  <p>Use the <span class="command">::tcom::import</span> command to convert type
-  information from a type library into Tcl commands to access COM classes and
-  interfaces.  The <var>typeLibrary</var> argument specifies a
-  type library file.  By default, the commands are defined in a namespace named
-  after the type library, but you may specify another namespace by supplying a
-  <var>namespace</var> argument.  This command returns the
-  library name stored in the type library file.</p>
-  
-   <h3>Commands</h3>
-   <dl>
-    
-     <dt>
-      
-       <var>class</var>
-       <var>?<span class="option">-inproc</span>?</var>
-       <var>?<span class="option">-local</span>?</var>
-       <var>?<span class="option">-remote</span>?</var>
-       <var>?hostName?</var>
-      
-     </dt>
-     <dd>
-      <p>For each class in the type library,
-      <span class="command">::tcom::import</span> defines a Tcl command with the same
-      name as the class.  The class command creates an object of the class and
-      returns a handle representing an interface pointer to the object.  The
-      command accepts an optional <var>hostName</var> argument
-      to specify the machine where you want to create the object.  You can use
-      the returned handle to invoke methods and access properties of the
-      object.  In practice, you should store this handle in a Tcl variable or
-      pass it as an argument to a Tcl command.</p>
-     </dd>
-    
-    
-     <dt>
-      
-       <var>interface</var>
-       <var>handle</var>
-      
-     </dt>
-     <dd>
-      <p>For each interface in the type library,
-      <span class="command">::tcom::import</span> defines a Tcl command with the same
-      name as the interface.  The interface command queries the object
-      represented by <var>handle</var> for an interface pointer
-      to that specific interface.  The command returns a handle representing
-      the interface pointer.  You can use the returned handle to invoke methods
-      and access properties of the object.  In practice, you should store this
-      handle in a Tcl variable or pass it as an argument to a Tcl
-      command.</p>
-     </dd>
-    
-   </dl>
-  
-  
-   <h3>Enumerations</h3>
-   <p>The <span class="command">::tcom::import</span> command generates a Tcl array
-   for each enumeration defined in the type library.  The array name is the
-   enumeration name.  To get an enumerator value, use an enumerator name as an
-   index into the array.</p>
-  
-  <h2>Tcl Value to VARIANT Mapping</h2>
-  <p>Each Tcl value has two representations.  A Tcl value has a string
-  representation and also has an internal representation that can be
-  manipulated more efficiently.  For example, a Tcl list is represented as an
-  object that holds the list's string representation as well as an array of
-  pointers to the objects for each list element.  The two representations are a
-  cache of each other and are computed lazily.  That is, each representation is
-  only computed when necessary, is computed from the other representation, and,
-  once computed, is saved.  In addition, a change in one representation
-  invalidates the other one.  As an example, a Tcl program doing integer
-  calculations can operate directly on a variable's internal machine integer
-  representation without having to constantly convert between integers and
-  strings.  Only when it needs a string representing the variable's value, say
-  to print it, will the program regenerate the string representation from the
-  integer.  The internal representations built into Tcl include boolean,
-  integer and floating point types.</p>
-  <p>When invoking COM object methods, <span class="command">tcom</span> tries to
-  convert each Tcl argument to the parameter type specified by the method
-  interface.  For example, if a method accepts an <tt>int</tt>
-  parameter, <span class="command">tcom</span> tries to convert the argument to that
-  type.  If the parameter type is a VARIANT, the conversion has an extra
-  complication because a VARIANT is designed to hold many different data types.
-  One approach might be to simply copy the Tcl value's string representation
-  to a string in the VARIANT, and hope the method's implementation can correctly
-  interpret the string, but this doesn't work in general because some
-  implementations expect certain VARIANT types.</p>
-  <p><span class="command">Tcom</span> uses the Tcl value's internal representation
-  type as a hint to choose the resulting VARIANT type.</p>
-  <blockquote>
-   <b>Tcl value to VARIANT mapping</b><br>
-   <table border="1">
-    
-     <tr>
-      <td><b>Tcl internal representation</b></td>
-      <td><b>VARIANT type</b></td>
-     </tr>
-    
-    
-     <tr>
-      <td>boolean</td>
-      <td>VT_BOOL</td>
-     </tr>
-     <tr>
-      <td>int</td>
-      <td>VT_I4</td>
-     </tr>
-     <tr>
-      <td>double</td>
-      <td>VT_R8</td>
-     </tr>
-     <tr>
-      <td>list</td>
-      <td>one-dimensional array of VT_VARIANT</td>
-     </tr>
-     <tr>
-      <td>bytearray</td>
-      <td>one-dimensional array of VT_UI1</td>
-     </tr>
-     <tr>
-      <td>other</td>
-      <td>VT_BSTR</td>
-     </tr>
-    
-   </table>
-  </blockquote>
-  
-   <h3>Invoking Methods With VARIANT Parameters</h3>
-   <p>The internal representation of a Tcl value may become significant when
-   it is passed to a VARIANT parameter of a method.  For example, the standard
-   interface for COM collections defines the <span class="command">Item</span> method for
-   getting an element by specifying an index.  Many implementations of the
-   method allow the index to be an integer value (usually based from 1) or a
-   string key.  If the index parameter is a VARIANT, you must account for the
-   internal representation type of the Tcl argument passed to that
-   parameter.</p>
-   <table bgcolor="#CCCCCC" width="100%"><tr><td><pre>
-
-# Assume $collection is a handle to a collection.
-set element [$collection Item 1]
-</pre></td></tr></table>
-   <p>This command passes a string consisting of the single character "1"
-   to the Item method.  The method may return an error because it can't find an
-   element with that string key.</p>
-<table bgcolor="#CCCCCC" width="100%"><tr><td><pre>
-
-set numElements [$collection Count]
-for {set i 1} {$i &lt;= $numElements} {incr i} {  ;# 1
-    set element [$collection Item $i]  ;# 2
-}
-</pre></td></tr></table>
-   <p>In line 1, the <span class="command">for</span> command sets the internal
-   representation of <tt>$i</tt> to an int type as a side effect of
-   evaluating the condition expression <tt>{$i &lt;=
-   $numElements}</tt>.  The command in line 2 passes the integer value in
-   <tt>$i</tt> to the Item method, which should succeed if the method
-   can handle integer index values.</p>
-  
-</body>
-</html>
index 4794bad1af2ac84269ead2b6e91e1e3eb8788300..c25414a75bdb42cf3d48ab1acc58a1e60e8cc274 100644 (file)
@@ -1,11 +1,12 @@
 <?xml version="1.0"?>
-<!-- $Id: tcom.n.xml,v 1.65 2002/10/22 22:07:55 cthuang Exp $ -->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "docbookx.dtd">
+<!-- $Id: tcom.n.xml 12 2005-04-14 14:01:20Z cthuang $ -->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <refentry id="tcom">
- <docinfo>
-  <date>$Date: 2002/10/22 22:07:55 $</date>
-  <releaseinfo>$Revision: 1.65 $</releaseinfo>
- </docinfo>
+ <refentryinfo>
+  <date>$Date: 2005-04-14 10:01:20 -0400 (Thu, 14 Apr 2005) $</date>
+  <releaseinfo>$Revision: 12 $</releaseinfo>
+ </refentryinfo>
  <refmeta>
   <refentrytitle>tcom</refentrytitle>
   <manvolnum>n</manvolnum>
  <refsynopsisdiv>
   <cmdsynopsis>
    <command>package require tcom</command>
-   <arg><option>3.9</option></arg>
+   <arg>3.10</arg>
    <sbr/>
-   <command>::tcom::ref</command>
-   <command>createobject</command>
-   <arg><option>-inproc</option></arg>
-   <arg><option>-local</option></arg>
-   <arg><option>-remote</option></arg>
-   <arg><option>-clsid</option></arg>
-   <arg choice="plain">progID</arg>
-   <arg>hostName</arg>
+   <command>::tcom::ref createobject</command>
+   <arg>-inproc</arg>
+   <arg>-local</arg>
+   <arg>-remote</arg>
+   <arg>-clsid</arg>
+   <arg choice="plain"><replaceable>progID</replaceable></arg>
+   <arg><replaceable>hostName</replaceable></arg>
    <sbr/>
-   <command>::tcom::ref</command>
-   <command>getactiveobject</command>
-   <arg><option>-clsid</option></arg>
-   <arg choice="plain">progID</arg>
+   <command>::tcom::ref getactiveobject</command>
+   <arg>-clsid</arg>
+   <arg choice="plain"><replaceable>progID</replaceable></arg>
    <sbr/>
-   <command>::tcom::ref</command>
-   <command>getobject</command>
-   <arg choice="plain">pathName</arg>
+   <command>::tcom::ref getobject</command>
+   <arg choice="plain"><replaceable>pathName</replaceable></arg>
    <sbr/>
-   <command>::tcom::ref</command>
-   <command>equal</command>
-   <arg choice="plain">handle1</arg>
-   <arg choice="plain">handle2</arg>
+   <command>::tcom::ref equal</command>
+   <arg choice="plain"><replaceable>handle1</replaceable></arg>
+   <arg choice="plain"><replaceable>handle2</replaceable></arg>
    <sbr/>
-   <arg choice="plain">handle</arg>
-   <arg><option>-method</option></arg>
-   <arg choice="plain">method</arg>
-   <arg rep="repeat">argument</arg>
+   <arg choice="plain"><replaceable>handle</replaceable></arg>
+   <arg>-call</arg>
+   <arg choice="plain"><replaceable>method</replaceable></arg>
+   <arg rep="repeat"><replaceable>argument</replaceable></arg>
    <sbr/>
-   <arg choice="plain">handle</arg>
-   <arg choice="plain"><option>-namedarg</option></arg>
-   <arg choice="plain">method</arg>
-   <arg rep="repeat">argumentName argumentValue</arg>
+   <arg choice="plain"><replaceable>handle</replaceable></arg>
+   <arg choice="plain">-namedarg</arg>
+   <arg choice="plain"><replaceable>method</replaceable></arg>
+   <arg rep="repeat"><replaceable>argumentName argumentValue</replaceable></arg>
    <sbr/>
-   <arg choice="plain">handle</arg>
-   <arg><option>-get</option></arg>
-   <arg><option>-set</option></arg>
-   <arg choice="plain">property</arg>
-   <arg rep="repeat">index</arg>
-   <arg>value</arg>
+   <arg choice="plain"><replaceable>handle</replaceable></arg>
+   <arg>-get</arg>
+   <arg>-set</arg>
+   <arg choice="plain"><replaceable>property</replaceable></arg>
+   <arg rep="repeat"><replaceable>index</replaceable></arg>
+   <arg><replaceable>value</replaceable></arg>
    <sbr/>
    <command>::tcom::foreach</command>
-   <arg choice="plain">varname</arg>
-   <arg choice="plain">collectionHandle</arg>
-   <arg choice="plain">body</arg>
+   <arg choice="plain"><replaceable>varname</replaceable></arg>
+   <arg choice="plain"><replaceable>collectionHandle</replaceable></arg>
+   <arg choice="plain"><replaceable>body</replaceable></arg>
    <sbr/>
    <command>::tcom::foreach</command>
-   <arg choice="plain">varlist</arg>
-   <arg choice="plain">collectionHandle</arg>
-   <arg choice="plain">body</arg>
+   <arg choice="plain"><replaceable>varlist</replaceable></arg>
+   <arg choice="plain"><replaceable>collectionHandle</replaceable></arg>
+   <arg choice="plain"><replaceable>body</replaceable></arg>
    <sbr/>
    <command>::tcom::bind</command>
-   <arg choice="plain">handle</arg>
-   <arg choice="plain">command</arg>
-   <arg>eventIID</arg>
+   <arg choice="plain"><replaceable>handle</replaceable></arg>
+   <arg choice="plain"><replaceable>command</replaceable></arg>
+   <arg><replaceable>eventIID</replaceable></arg>
    <sbr/>
    <command>::tcom::unbind</command>
-   <arg choice="plain">handle</arg>
+   <arg choice="plain"><replaceable>handle</replaceable></arg>
    <sbr/>
    <command>::tcom::na</command>
    <sbr/>
    <command>::tcom::info interface</command>
-   <arg choice="plain">handle</arg>
+   <arg choice="plain"><replaceable>handle</replaceable></arg>
    <sbr/>
    <command>::tcom::configure</command>
-   <arg choice="plain">name</arg>
-   <arg>value</arg>
+   <arg choice="plain"><replaceable>name</replaceable></arg>
+   <arg><replaceable>value</replaceable></arg>
    <sbr/>
    <command>::tcom::import</command>
-   <arg choice="plain">typeLibrary</arg>
-   <arg>namespace</arg>
+   <arg choice="plain"><replaceable>typeLibrary</replaceable></arg>
+   <arg><replaceable>namespace</replaceable></arg>
    <sbr/>
   </cmdsynopsis>
  </refsynopsisdiv>
    <varlistentry>
     <term>
      <cmdsynopsis id="ref_createobject">
-      <command>::tcom::ref</command>
-      <command>createobject</command>
-      <arg><option>-inproc</option></arg>
-      <arg><option>-local</option></arg>
-      <arg><option>-remote</option></arg>
-      <arg><option>-clsid</option></arg>
-      <arg choice="plain">progID</arg>
-      <arg>hostName</arg>
+      <command>::tcom::ref createobject</command>
+      <arg>-inproc</arg>
+      <arg>-local</arg>
+      <arg>-remote</arg>
+      <arg>-clsid</arg>
+      <arg choice="plain"><replaceable>progID</replaceable></arg>
+      <arg><replaceable>hostName</replaceable></arg>
       <sbr/>
-      <command>::tcom::ref</command>
-      <command>getactiveobject</command>
-      <arg><option>-clsid</option></arg>
-      <arg choice="plain">progID</arg>
+      <command>::tcom::ref getactiveobject</command>
+      <arg>-clsid</arg>
+      <arg choice="plain"><replaceable>progID</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
    <varlistentry>
     <term>
      <cmdsynopsis id="ref_getobject">
-      <command>::tcom::ref</command>
-      <command>getobject</command>
-      <arg choice="plain">pathName</arg>
+      <command>::tcom::ref getobject</command>
+      <arg choice="plain"><replaceable>pathName</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
    <varlistentry>
     <term>
      <cmdsynopsis id="ref_equal">
-      <command>::tcom::ref</command>
-      <command>equal</command>
-      <arg choice="plain">handle1</arg>
-      <arg choice="plain">handle2</arg>
+      <command>::tcom::ref equal</command>
+      <arg choice="plain"><replaceable>handle1</replaceable></arg>
+      <arg choice="plain"><replaceable>handle2</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
    <varlistentry>
     <term>
      <cmdsynopsis id="handle_method">
-      <arg choice="plain">handle</arg>
-      <arg><option>-method</option></arg>
-      <arg choice="plain">method</arg>
-      <arg rep="repeat">argument</arg>
+      <arg choice="plain"><replaceable>handle</replaceable></arg>
+      <arg>-call</arg>
+      <arg choice="plain"><replaceable>method</replaceable></arg>
+      <arg rep="repeat"><replaceable>argument</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
      the name of a Tcl variable as the argument.  After the method returns, the
      variables will contain the output values.  In some cases where
      <command>tcom</command> cannot get information about the object's
-     interface, you may have to use the <option>-method</option> option to
+     interface, you may have to use the <option>-call</option> option to
      specify you want to invoke a method.</para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term>
      <cmdsynopsis id="namedarg">
-      <arg choice="plain">handle</arg>
-      <arg choice="plain"><option>-namedarg</option></arg>
-      <arg choice="plain">method</arg>
-      <arg rep="repeat">argumentName argumentValue</arg>
+      <arg choice="plain"><replaceable>handle</replaceable></arg>
+      <arg choice="plain">-namedarg</arg>
+      <arg choice="plain"><replaceable>method</replaceable></arg>
+      <arg rep="repeat">
+       <replaceable>argumentName argumentValue</replaceable>
+      </arg>
      </cmdsynopsis>
     </term>
     <listitem>
    <varlistentry>
     <term>
      <cmdsynopsis id="handle_property">
-      <arg choice="plain">handle</arg>
-      <arg><option>-get</option></arg>
-      <arg><option>-set</option></arg>
-      <arg choice="plain">property</arg>
-      <arg rep="repeat">index</arg>
-      <arg>value</arg>
+      <arg choice="plain"><replaceable>handle</replaceable></arg>
+      <arg>-get</arg>
+      <arg>-set</arg>
+      <arg choice="plain"><replaceable>property</replaceable></arg>
+      <arg rep="repeat"><replaceable>index</replaceable></arg>
+      <arg><replaceable>value</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
     <term>
      <cmdsynopsis id="foreach">
       <command>::tcom::foreach</command>
-      <arg choice="plain">varname</arg>
-      <arg choice="plain">collectionHandle</arg>
-      <arg choice="plain">body</arg>
+      <arg choice="plain"><replaceable>varname</replaceable></arg>
+      <arg choice="plain"><replaceable>collectionHandle</replaceable></arg>
+      <arg choice="plain"><replaceable>body</replaceable></arg>
       <sbr/>
       <command>::tcom::foreach</command>
-      <arg choice="plain">varlist</arg>
-      <arg choice="plain">collectionHandle</arg>
-      <arg choice="plain">body</arg>
+      <arg choice="plain"><replaceable>varlist</replaceable></arg>
+      <arg choice="plain"><replaceable>collectionHandle</replaceable></arg>
+      <arg choice="plain"><replaceable>body</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
     <term>
      <cmdsynopsis id="bind">
       <command>::tcom::bind</command>
-      <arg choice="plain">handle</arg>
-      <arg choice="plain">command</arg>
-      <arg>eventIID</arg>
+      <arg choice="plain"><replaceable>handle</replaceable></arg>
+      <arg choice="plain"><replaceable>command</replaceable></arg>
+      <arg><replaceable>eventIID</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
     <term>
      <cmdsynopsis id="unbind">
       <command>::tcom::unbind</command>
-      <arg choice="plain">handle</arg>
+      <arg choice="plain"><replaceable>handle</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
     <term>
      <cmdsynopsis id="info">
       <command>::tcom::info interface</command>
-      <arg choice="plain">handle</arg>
+      <arg choice="plain"><replaceable>handle</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
       <varlistentry>
        <term>
         <cmdsynopsis id="interface_iid">
-         <arg choice="plain">interfaceHandle</arg>
+         <arg choice="plain"><replaceable>interfaceHandle</replaceable></arg>
         <command>iid</command>
         </cmdsynopsis>
        </term>
       <varlistentry>
        <term>
         <cmdsynopsis id="interface_methods">
-         <arg choice="plain">interfaceHandle</arg>
+         <arg choice="plain"><replaceable>interfaceHandle</replaceable></arg>
         <command>methods</command>
         </cmdsynopsis>
        </term>
       <varlistentry>
        <term>
         <cmdsynopsis id="interface_name">
-         <arg choice="plain">interfaceHandle</arg>
+         <arg choice="plain"><replaceable>interfaceHandle</replaceable></arg>
         <command>name</command>
         </cmdsynopsis>
        </term>
       <varlistentry>
        <term>
         <cmdsynopsis id="interface_properties">
-         <arg choice="plain">interfaceHandle</arg>
+         <arg choice="plain"><replaceable>interfaceHandle</replaceable></arg>
         <command>properties</command>
         </cmdsynopsis>
        </term>
     <term>
      <cmdsynopsis id="configure">
       <command>::tcom::configure</command>
-      <arg choice="plain">name</arg>
-      <arg>value</arg>
+      <arg choice="plain"><replaceable>name</replaceable></arg>
+      <arg><replaceable>value</replaceable></arg>
      </cmdsynopsis>
     </term>
     <listitem>
       <varlistentry>
        <term>
         <cmdsynopsis id="configure_concurrency">
-         <arg choice="plain"><option>-concurrency</option></arg>
-        <arg>concurrencyModel</arg>
+         <arg choice="plain">-concurrency</arg>
+         <arg><replaceable>concurrencyModel</replaceable></arg>
         </cmdsynopsis>
        </term>
        <listitem>
   <title>Importing Type Library Information</title>
   <cmdsynopsis id="import">
    <command>::tcom::import</command>
-   <arg choice="plain">typeLibrary</arg>
-   <arg>namespace</arg>
+   <arg choice="plain"><replaceable>typeLibrary</replaceable></arg>
+   <arg><replaceable>namespace</replaceable></arg>
   </cmdsynopsis>
   <para>Use the <command>::tcom::import</command> command to convert type
   information from a type library into Tcl commands to access COM classes and
     <varlistentry>
      <term>
       <cmdsynopsis id="import_class">
-       <arg choice="plain">class</arg>
-       <arg><option>-inproc</option></arg>
-       <arg><option>-local</option></arg>
-       <arg><option>-remote</option></arg>
-       <arg>hostName</arg>
+       <arg choice="plain"><replaceable>class</replaceable></arg>
+       <arg>-inproc</arg>
+       <arg>-local</arg>
+       <arg>-remote</arg>
+       <arg><replaceable>hostName</replaceable></arg>
       </cmdsynopsis>
      </term>
      <listitem>
     <varlistentry>
      <term>
       <cmdsynopsis id="import_interface">
-       <arg choice="plain">interface</arg>
-       <arg choice="plain">handle</arg>
+       <arg choice="plain"><replaceable>interface</replaceable></arg>
+       <arg choice="plain"><replaceable>handle</replaceable></arg>
       </cmdsynopsis>
      </term>
      <listitem>
    internal representation type of the Tcl argument passed to that
    parameter.</para>
    <programlisting>
-
 # Assume $collection is a handle to a collection.
 set element [$collection Item 1]
 </programlisting>
@@ -577,7 +571,6 @@ set element [$collection Item 1]
    to the Item method.  The method may return an error because it can't find an
    element with that string key.</para>
 <programlisting>
-
 set numElements [$collection Count]
 for {set i 1} {$i &lt;= $numElements} {incr i} {  ;# 1
     set element [$collection Item $i]  ;# 2
index 696998555a0c7042247afe4e47bbfa1fe2277bc8..f28e4dcf1debf95399983c07165fcb24e6352d5e 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: xslt.tcl,v 1.2 2002/09/05 22:10:25 cthuang Exp $
+# $Id: xslt.tcl 7 2005-02-24 05:18:47Z cthuang $
 #
 # Run an XML document through an XSLT processor.
 
@@ -12,6 +12,7 @@ package require tcom
 set domProgId "Msxml2.DOMDocument"
 
 set source [::tcom::ref createobject $domProgId]
+$source async 0
 $source preserveWhiteSpace 1
 $source validateOnParse 0
 $source resolveExternals 0
@@ -26,6 +27,7 @@ if {![$source load $sourceUrl]} {
 }
 
 set xslt [::tcom::ref createobject $domProgId]
+$xslt async 0
 $xslt preserveWhiteSpace 1
 $xslt validateOnParse 0
 set xsltUrl [lindex $argv 1]
@@ -39,7 +41,7 @@ if {![$xslt load $xsltUrl]} {
 }
 
 regsub {<META http-equiv="Content-Type"[^>]*>} [$source transformNode $xslt] \
-    {<META http-equiv="Content-Type" content="text/html; charset=UTF-8">} \
+    {<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">} \
     resultHtml
 
 set out [open [lindex $argv 2] "w"]
diff --git a/lib/Banking/Banking.tlb b/lib/Banking/Banking.tlb
deleted file mode 100644 (file)
index 83694de..0000000
Binary files a/lib/Banking/Banking.tlb and /dev/null differ
index 1c3601c19ed9a6c381ab67f5fc2f214dbcd6a2fb..8aafe6598d9d1b5dd3be09746275f6ea9d79d39e 100644 (file)
@@ -1,2 +1,2 @@
-# $Id: pkgIndex.tcl,v 1.3 2001/07/04 03:36:16 cthuang Exp $
+# $Id: pkgIndex.tcl 5 2005-02-16 14:57:24Z cthuang $
 package ifneeded Banking 1.0 [list source [file join $dir server.tcl]]
index 7b9540d6a6b8e8e8574acfaa60555019a16caf23..ae628a1adc3f4803b2d543a666802cec69db823a 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: server.itcl,v 1.7 2002/06/29 15:34:52 cthuang Exp $
+# $Id: server.itcl 5 2005-02-16 14:57:24Z cthuang $
 package provide Banking 1.0
 
 package require Itcl
index f31894fa26f851f52c5b239c9d13094b883e404b..bc72ff7f1e817227fe1ad1b6e7f04dc3ddd74c45 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: server.tcl,v 1.4 2003/03/07 00:03:00 cthuang Exp $
+# $Id: server.tcl 5 2005-02-16 14:57:24Z cthuang $
 package provide Banking 1.0
 
 package require tcom
index a214bbdf208352a703b0ee5e6bc1a97aa84df932..db25d4dac1507b5a59d4cbdfc8186a001c3c8da3 100644 (file)
Binary files a/lib/TclScript/TclScript.dll and b/lib/TclScript/TclScript.dll differ
index 1d6f28776de083d13a365c5acff774155c4c6a2d..5b503898263d1a62e5b71f3db2489d2abb417182 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: TclScript.itcl,v 1.6 2003/11/08 17:38:09 cthuang Exp $
+# $Id: TclScript.itcl 5 2005-02-16 14:57:24Z cthuang $
 
 package require Itcl
 namespace import itcl::*
index 871d6948fe5881441fcda6f68b479efcd2c9e3e1..d17a1ba64e0388cb299db28c1060944a06a1cd1e 100644 (file)
Binary files a/lib/TclScript/TclScript.tlb and b/lib/TclScript/TclScript.tlb differ
index 74d19b953d4ad52516d332f2b7772b1e1d1790cb..efb1c13215f1d41e261702be8e55c04f52b8efff 100644 (file)
@@ -1,3 +1,3 @@
-# $Id: pkgIndex.tcl,v 1.2 2002/03/30 18:49:10 cthuang Exp $
+# $Id: pkgIndex.tcl 5 2005-02-16 14:57:24Z cthuang $
 package ifneeded TclScript 1.0 \
 [list load [file join $dir TclScript.dll]]\n[list source [file join $dir TclScript.itcl]]
index 807ee291238c5e55bcdbd7eb9c03b68ae7905343..8b8e0335d9a6559733800e552d4050c50510a5c5 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: register.tcl,v 1.3 2002/03/20 23:52:35 cthuang Exp $
+# $Id: register.tcl 5 2005-02-16 14:57:24Z cthuang $
 #
 # This script registers the Tcl Active Scripting engine.
 
index 906114abee762e1c3fe34c7d622e0546a0969f14..9e7695b06c9712e8a0cf715e679d9d45b1bf5e03 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: unregister.tcl,v 1.1 2003/03/20 00:12:14 cthuang Exp $
+# $Id: unregister.tcl 5 2005-02-16 14:57:24Z cthuang $
 #
 # This script unregisters the Tcl Active Scripting engine.
 
index aa90f9b76cf8dece99ee177dc2acd944ef71ecbf..27a04a8082060547e504fcddcbad63119cbc9aba 100644 (file)
@@ -1,3 +1,3 @@
-# $Id: pkgIndex.tcl,v 1.16 2003/04/17 03:17:30 cthuang Exp $
+# $Id: pkgIndex.tcl 5 2005-02-16 14:57:24Z cthuang $
 package ifneeded tcom 3.9 \
 [list load [file join $dir tcom.dll]]\n[list source [file join $dir tcom.tcl]]
index 3c689014ddfd00653020fc68756ed29647402cb1..9f60aa03cdc75915f9098f8d557bd2a02360e6e1 100644 (file)
Binary files a/lib/tcom/tcom.dll and b/lib/tcom/tcom.dll differ
index 58eaab4b4ff5b58c243bb4fe2a2d5173a8632c2d..6ae6e432cf03533d9b20bd742fe10e170a4c4233 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: tcom.tcl,v 1.17 2003/04/02 22:46:51 cthuang Exp $
+# $Id: tcom.tcl 5 2005-02-16 14:57:24Z cthuang $
 
 namespace eval ::tcom {
     # Tear down all event connections to the object.
index 519a611acaa08c35c3f9e36d74fe1d3801426287..95fcfca9ed38dad8601f054bb173a91df6be4565 100644 (file)
Binary files a/lib/tcom/tcominproc.dll and b/lib/tcom/tcominproc.dll differ
index 42df14c8aee3a98b6b9f5aa2ac3eec29334d10f7..e83568bb88e388471c176d765ecacb979198d8e8 100644 (file)
Binary files a/lib/tcom/tcomlocal.exe and b/lib/tcom/tcomlocal.exe differ
index fe219b3440df1f8b6832b68354d23f03e6f9c534..e71a002f06a63413e7da41cca57da00c889f5b34 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ActiveScriptError.cpp,v 1.1 2002/03/30 18:49:53 cthuang Exp $
+// $Id: ActiveScriptError.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "ActiveScriptError.h"
 
 STDMETHODIMP
index 38c542fa42625f32bdba1d4ed5cbd848e334b4c5..9c1723c6a066133fc010c6d73bb6f3e975a7b961 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ActiveScriptError.h,v 1.2 2002/04/12 02:55:27 cthuang Exp $
+// $Id: ActiveScriptError.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef ACTIVESCRIPTERROR_H
 #define ACTIVESCRIPTERROR_H
 
index b92e4a71bfad4e76d7170396e1112664f2be92ee..73a055bc1dd8651371ac0fb8dffb5db553be2927 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: Arguments.cpp,v 1.35 2003/03/15 01:32:09 cthuang Exp $
+// $Id: Arguments.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "Arguments.h"
 #include "Extension.h"
 #include "TclObject.h"
@@ -45,13 +45,23 @@ TypedArguments::initArgument (
         // For out parameters, set a pointer to where the out value
         // will be stored.
 
-        if (vt == VT_INT) {
+        switch (vt) {
+        case VT_INT:
             // IDispatch::Invoke returns DISP_E_TYPEMISMATCH on
             // VT_INT | VT_BYREF parameters.
             vt = VT_I4;
-        } else if (vt == VT_USERDEFINED) {
+            break;
+
+        case VT_UINT:
+            // IDispatch::Invoke returns DISP_E_TYPEMISMATCH on
+            // VT_UINT | VT_BYREF parameters.
+            vt = VT_UI4;
+            break;
+
+        case VT_USERDEFINED:
             // Assume user defined types derive from IUnknown.
             vt = VT_UNKNOWN;
+            break;
         }
 
         if (vt == VT_SAFEARRAY) {
@@ -81,7 +91,7 @@ TypedArguments::initArgument (
 
             // If the argument is an interface pointer, increment its reference
             // count because the _variant_t destructor will release it.
-            value.toVariant(
+            value.toNativeValue(
                 &m_outValues[argIndex], parameter.type(), interp, true);
         } else {
             if (vt == VT_UNKNOWN) {
@@ -103,7 +113,8 @@ TypedArguments::initArgument (
     } else {
         // If the argument is an interface pointer, increment its reference
         // count because the _variant_t destructor will release it.
-        argument.toVariant(&m_args[argIndex], parameter.type(), interp, true);
+        argument.toNativeValue(
+            &m_args[argIndex], parameter.type(), interp, true);
     }
 
     return TCL_OK;
@@ -149,21 +160,22 @@ PositionalArguments::initialize (
     }
 
     if (method.vararg() && inputCount > 0) {
-        m_args = new _variant_t[inputCount];
+        m_args = new NativeValue[inputCount];
 
         // Convert the arguments actually provided.
         int inputIndex = 0;
         int argIndex = inputCount - 1;
         for (; inputIndex < inputCount; ++inputIndex, --argIndex) {
             TclObject value(objv[inputIndex]);
-            value.toVariant(&m_args[argIndex], Type::variant(), interp, true);
+            value.toNativeValue(
+                &m_args[argIndex], Type::variant(), interp, true);
         }
 
         paramCount = inputCount;
 
     } else if (paramCount > 0) {
-        m_args = new _variant_t[paramCount];
-        m_outValues = new _variant_t[paramCount];
+        m_args = new NativeValue[paramCount];
+        m_outValues = new NativeValue[paramCount];
 
         int j = paramCount - 1;
         Method::Parameters::const_iterator p = parameters.begin();
@@ -186,7 +198,7 @@ PositionalArguments::initialize (
         if (dispatchFlags == DISPATCH_PROPERTYPUT
          || dispatchFlags == DISPATCH_PROPERTYPUTREF) {
             TclObject value = objv[i];
-            value.toVariant(&m_args[j], method.type(), interp, true);
+            value.toNativeValue(&m_args[j], method.type(), interp, true);
         }
     }
 
@@ -244,8 +256,8 @@ NamedArguments::initialize (
 
     int cArgs = objc / 2;
     if (cArgs > 0) {
-        m_args = new _variant_t[cArgs];
-        m_outValues = new _variant_t[cArgs];
+        m_args = new NativeValue[cArgs];
+        m_outValues = new NativeValue[cArgs];
         m_namedDispids = new DISPID[cArgs];
 
         int j = cArgs - 1;
@@ -284,7 +296,7 @@ UntypedArguments::initialize (
     WORD dispatchFlags)
 {
     if (objc > 0) {
-        m_args = new _variant_t[objc];
+        m_args = new NativeValue[objc];
 
         int j = objc - 1;
         for (int i = 0; i < objc; ++i, --j) {
@@ -292,7 +304,7 @@ UntypedArguments::initialize (
 
             // If the argument is an interface pointer, increment its reference
             // count because the _variant_t destructor will release it.
-            value.toVariant(&m_args[j], Type::variant(), interp, true);
+            value.toNativeValue(&m_args[j], Type::variant(), interp, true);
         }
     }
 
index 50e57f9d384e5fc260d460a8cf64fe32538f8086..fbbea6efa945f0948d9444f5458966b10f79f689 100644 (file)
@@ -1,8 +1,9 @@
-// $Id: Arguments.h,v 1.8 2001/10/13 17:56:14 Administrator Exp $
+// $Id: Arguments.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef ARGUMENTS_H
 #define ARGUMENTS_H
 
 #include "TypeInfo.h"
+#include "NativeValue.h"
 
 class Arguments
 {
@@ -10,7 +11,7 @@ protected:
     DISPPARAMS m_dispParams;
 
     // argument values
-    _variant_t *m_args;
+    NativeValue *m_args;
 
     Arguments();
 
@@ -29,7 +30,7 @@ class TypedArguments: public Arguments
 {
 protected:
     // used to hold values returned from out parameters
-    _variant_t *m_outValues;
+    NativeValue *m_outValues;
 
     TypedArguments();
 
index 9ff5224c3b4023f025e442d39d9f73089e760358..f4b18ad52f4a8bac9bda5ba92e912acb4bc36a17 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ComModule.cpp,v 1.15 2002/05/31 04:03:06 cthuang Exp $
+// $Id: ComModule.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "ComObjectFactory.h"
 #include "ComModule.h"
index 21816f47416929048b14d3c518265a454481f593..8a7abed285eb89d254a08c197231e8214b8a7ab7 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ComModule.h,v 1.13 2002/04/13 03:53:56 cthuang Exp $
+// $Id: ComModule.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef COMMODULE_H
 #define COMMODULE_H
 
index beb4e9b350581caa2f35079ce3572bbb873fdf4a..89e693e2c86c00fe13f6677c97a773b5e8253106 100644 (file)
@@ -1,9 +1,12 @@
-// $Id: ComObject.cpp,v 1.41 2003/04/04 23:55:04 cthuang Exp $
+// $Id: ComObject.cpp 13 2005-04-18 12:24:14Z cthuang $
 #pragma warning(disable: 4786)
 #include "ComObject.h"
 #include <stdexcept>
 #include "ComModule.h"
+#include "DispatchAdapter.h"
+#ifdef TCOM_VTBL_SERVER
 #include "InterfaceAdapter.h"
+#endif
 #include "Reference.h"
 #include "Extension.h"
 
@@ -76,10 +79,16 @@ ComObject::registerActiveObject (REFCLSID clsid)
     m_registeredActiveObject = true;
 }
 
-InterfaceAdapter *
+void *
 ComObject::implementInterface (const Interface &interfaceDesc)
 {
-    InterfaceAdapter *pAdapter = new InterfaceAdapter(*this, interfaceDesc);
+    void *pAdapter =
+#ifdef TCOM_VTBL_SERVER
+        new InterfaceAdapter(*this, interfaceDesc);
+#else
+        new DispatchAdapter(*this, interfaceDesc);
+#endif
+
     m_iidToAdapterMap.insert(interfaceDesc.iid(), pAdapter);
     return pAdapter;
 }
@@ -203,7 +212,7 @@ ComObject::queryInterface (REFIID iid, void **ppvObj)
     if (IsEqualIID(iid, IID_IDispatch)) {
         // Expose the operations of the default interface through IDispatch.
         if (m_pDispatch == 0) {
-            m_pDispatch = new InterfaceAdapter(*this, m_defaultInterface, true);
+            m_pDispatch = new DispatchAdapter(*this, m_defaultInterface);
         }
         *ppvObj = m_pDispatch;
         addRef();
@@ -216,7 +225,7 @@ ComObject::queryInterface (REFIID iid, void **ppvObj)
         return S_OK;
     }
 
-    InterfaceAdapter *pAdapter = m_iidToAdapterMap.find(iid);
+    void *pAdapter = m_iidToAdapterMap.find(iid);
     if (pAdapter == 0) {
         const Interface *pInterface = m_supportedInterfaceMap.find(iid);
         if (pInterface != 0) {
@@ -364,14 +373,22 @@ putOutVariant (Tcl_Interp *interp,
         }
         break;
 
+    case VT_SAFEARRAY:
+        if (*V_ARRAYREF(pDest) != 0) {
+            SafeArrayDestroy(*V_ARRAYREF(pDest));
+        }
+        *V_ARRAYREF(pDest) =
+            tclObject.getSafeArray(type.elementType(), interp);
+        break;
+
     default:
         *V_I4REF(pDest) = tclObject.getLong();
     }
 }
 
 HRESULT
-ComObject::invoke (InterfaceAdapter *pAdapter,
-                   DISPID dispid,
+ComObject::invoke (const Method &method,
+                   bool isProperty,
                    REFIID /*riid*/,
                    LCID /*lcid*/,
                    WORD wFlags,
@@ -380,11 +397,6 @@ ComObject::invoke (InterfaceAdapter *pAdapter,
                    EXCEPINFO *pExcepInfo,
                    UINT *pArgErr)
 {
-    // Get the method description for method being invoked.
-    const Method *pMethod = pAdapter->findDispatchMethod(dispid);
-    if (pMethod == 0) {
-        return DISP_E_MEMBERNOTFOUND;
-    }
 
     HRESULT hresult;
 
@@ -394,15 +406,14 @@ ComObject::invoke (InterfaceAdapter *pAdapter,
 
         // Get the method or property to invoke on the servant.
         std::string operation;
-        if ((wFlags & DISPATCH_PROPERTYGET) != 0
-         && pAdapter->isProperty(dispid)) {
-            operation = getPrefix + pMethod->name();
+        if ((wFlags & DISPATCH_PROPERTYGET) != 0 && isProperty) {
+            operation = getPrefix + method.name();
 
         } else if (wFlags & (DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF)) {
-            operation = setPrefix + pMethod->name();
+            operation = setPrefix + method.name();
 
         } else if (wFlags & DISPATCH_METHOD) {
-            operation = pMethod->name();
+            operation = method.name();
 
         } else {
             return DISP_E_MEMBERNOTFOUND;
@@ -420,7 +431,7 @@ ComObject::invoke (InterfaceAdapter *pAdapter,
         // Convert arguments to Tcl values.
         // TODO: Should handle named arguments differently than positional
         // arguments.
-        const Method::Parameters &parameters = pMethod->parameters();
+        const Method::Parameters &parameters = method.parameters();
 
         int argIndex = pDispParams->cArgs - 1;
         Method::Parameters::const_iterator pParam;
@@ -440,7 +451,7 @@ ComObject::invoke (InterfaceAdapter *pAdapter,
         if (wFlags & (DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF)) {
             VARIANT *pArg = &(pDispParams->rgvarg[argIndex]);
             try {
-                TclObject value(pArg, pMethod->type(), m_interp);
+                TclObject value(pArg, method.type(), m_interp);
                 script.lappend(value);
             }
             catch (_com_error &) {
@@ -474,27 +485,24 @@ ComObject::invoke (InterfaceAdapter *pAdapter,
         argIndex = pDispParams->cArgs - 1;
         for (pParam = parameters.begin(); pParam != parameters.end();
          ++pParam, --argIndex) {
-            if (pParam->flags() & PARAMFLAG_FOUT) {
+            VARIANT *pArg = &(pDispParams->rgvarg[argIndex]);
+            if ((pParam->flags() & PARAMFLAG_FOUT) && (V_VT(pArg) & VT_BYREF)) {
                 // Get name of Tcl variable that holds out value.
                 TclObject varName = getOutVariableName(*pParam);
 
                 // Copy variable value to out argument.
                 TclObject value;
                 if (getVariable(varName, value) == TCL_OK) {
-                    putOutVariant(
-                        m_interp,
-                        &pDispParams->rgvarg[argIndex],
-                        value,
-                        pParam->type());
+                    putOutVariant(m_interp, pArg, value, pParam->type());
                 }
             }
         }
 
         // Convert return value.
-        if (pReturnValue != 0 && pMethod->type().vartype() != VT_VOID) {
+        if (pReturnValue != 0 && method.type().vartype() != VT_VOID) {
             // Must increment reference count of interface pointers returned
             // from methods.
-            result.toVariant(pReturnValue, pMethod->type(), m_interp, true);
+            result.toVariant(pReturnValue, method.type(), m_interp, true);
         }
     }
     catch (_com_error &e) {
@@ -504,6 +512,8 @@ ComObject::invoke (InterfaceAdapter *pAdapter,
     return hresult;
 }
 
+#ifdef TCOM_VTBL_SERVER
+
 // Convert the native value that the va_list points to into a Tcl object.
 // Returns a va_list pointing to the next argument.
 
@@ -584,6 +594,13 @@ convertNativeToTclObject (va_list pArg,
             interp);
         break;
 
+    case VT_SAFEARRAY:
+        tclObject = TclObject(
+            byRef ? *va_arg(pArg, SAFEARRAY **) : va_arg(pArg, SAFEARRAY *),
+            type,
+            interp);
+        break;
+
     default:
         tclObject = Tcl_NewLongObj(
             byRef ? *va_arg(pArg, int *) : va_arg(pArg, int));
@@ -703,6 +720,11 @@ putArgument (va_list pArg,
         }
         break;
 
+    case VT_SAFEARRAY:
+        *static_cast<SAFEARRAY **>(pDest) =
+            tclObject.getSafeArray(type.elementType(), interp);
+        break;
+
     default:
         *static_cast<int *>(pDest) = tclObject.getLong();
     }
@@ -870,3 +892,5 @@ invokeComObjectFunction (volatile HRESULT hresult,
 
     va_end(pArg);
 }
+
+#endif
index 3868e2f8ffbf659ce93588d0bfb71b6e0789df3d..386d13287bdb41537720b06c437936a53dbf0fe0 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ComObject.h,v 1.15 2002/10/22 22:07:55 cthuang Exp $
+// $Id: ComObject.h 13 2005-04-18 12:24:14Z cthuang $
 #ifndef COMOBJECT_H
 #define COMOBJECT_H
 
@@ -49,17 +49,17 @@ class TCOM_API ComObject
     SupportedInterfaceMap m_supportedInterfaceMap;
 
     // collection of implemented interface adapters
-    typedef HashTable<IID, InterfaceAdapter *> IidToAdapterMap;
+    typedef HashTable<IID, void *> IidToAdapterMap;
     IidToAdapterMap m_iidToAdapterMap;
 
     // implements default interface
-    InterfaceAdapter *m_pDefaultAdapter;
+    void *m_pDefaultAdapter;
 
     // implements ISupportErrorInfo
     SupportErrorInfo m_supportErrorInfo;
 
     // implements IDispatch
-    InterfaceAdapter *m_pDispatch;
+    void *m_pDispatch;
 
     // token returned from RegisterActiveObject
     unsigned long m_activeObjectHandle;
@@ -81,7 +81,7 @@ class TCOM_API ComObject
     void operator=(const ComObject &);  // not implemented
 
     // Create an adapter which implements the specified interface.
-    InterfaceAdapter *implementInterface(const Interface &interfaceDesc);
+    void *implementInterface(const Interface &interfaceDesc);
 
     // Convert IDispatch argument to Tcl value.
     TclObject getArgument(VARIANT *pArg, const Parameter &param);
@@ -136,15 +136,15 @@ public:
 
     // IDispatch implementation
     HRESULT invoke(
-        InterfaceAdapter *pThis,
-        DISPID dispidMember,
-        REFIID riid,
+        const Method &method,
+        bool isProperty,
+        REFIID iid,
         LCID lcid,
         WORD wFlags,
-        DISPPARAMS *pdispparams,
-        VARIANT *pvarResult,
-        EXCEPINFO *pexcepinfo,
-        UINT *puArgErr);
+        DISPPARAMS *pDispParams,
+        VARIANT *pReturnValue,
+        EXCEPINFO *pExcepInfo,
+        UINT *pArgErr);
 };
 
 #endif 
index 8176be50e8c0ac5980346205c9615b5584b9d788..710f2610ea2e7d577da3c17393a95333bb3176a1 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ComObjectFactory.cpp,v 1.17 2002/05/31 04:03:06 cthuang Exp $
+// $Id: ComObjectFactory.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "ComModule.h"
 #include "ComObject.h"
index 6bf8e141d35ea919abbcca7314e40ca410b4debf..67268134a3e55918d1eec89971eb6a858e4c6f75 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ComObjectFactory.h,v 1.11 2002/04/13 03:53:56 cthuang Exp $
+// $Id: ComObjectFactory.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef COMOBJECTFACTORY_H
 #define COMOBJECTFACTORY_H
 
diff --git a/src/DispatchAdapter.cpp b/src/DispatchAdapter.cpp
new file mode 100644 (file)
index 0000000..9459c7f
--- /dev/null
@@ -0,0 +1,84 @@
+// $Id: DispatchAdapter.cpp 14 2005-04-18 14:14:12Z cthuang $
+#pragma warning(disable: 4786)
+#include "DispatchAdapter.h"
+#include <stdexcept>
+#include "ComObject.h"
+#include "Reference.h"
+#include "Extension.h"
+
+// Implement IUnknown methods
+
+STDMETHODIMP
+DispatchAdapter::QueryInterface (REFIID iid, void **ppvObj)
+{
+   return m_dispatchImpl.object().queryInterface(iid, ppvObj);
+}
+
+STDMETHODIMP_(ULONG)
+DispatchAdapter::AddRef ()
+{
+    return m_dispatchImpl.object().addRef();
+}
+
+STDMETHODIMP_(ULONG)
+DispatchAdapter::Release ()
+{
+    return m_dispatchImpl.object().release();
+}
+
+// Implement IDispatch methods
+
+STDMETHODIMP
+DispatchAdapter::GetTypeInfoCount (UINT *pCount)
+{
+    *pCount = 1;
+    return S_OK;
+}
+
+STDMETHODIMP
+DispatchAdapter::GetTypeInfo (UINT index, LCID, ITypeInfo **ppTypeInfo)
+{
+    if (index != 0) {
+        *ppTypeInfo = 0;
+        return DISP_E_BADINDEX;
+    }
+
+    ITypeInfo *pTypeInfo = m_dispatchImpl.typeInfo();
+    pTypeInfo->AddRef();
+    *ppTypeInfo = pTypeInfo;
+    return S_OK;
+}
+
+STDMETHODIMP
+DispatchAdapter::GetIDsOfNames (
+    REFIID,
+    OLECHAR **rgszNames,
+    UINT cNames,
+    LCID,
+    DISPID *rgDispId)
+{
+    ITypeInfo *pTypeInfo = m_dispatchImpl.typeInfo();
+    return pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId);
+}
+
+STDMETHODIMP
+DispatchAdapter::Invoke (
+    DISPID dispid,
+    REFIID iid,
+    LCID lcid,
+    WORD wFlags,
+    DISPPARAMS *pDispParams,
+    VARIANT *pReturnValue,
+    EXCEPINFO *pExcepInfo,
+    UINT *pArgErr)
+{
+    return m_dispatchImpl.invoke(
+        dispid,
+        iid,
+        lcid,
+        wFlags,
+        pDispParams,
+        pReturnValue,
+        pExcepInfo,
+        pArgErr);
+}
diff --git a/src/DispatchAdapter.h b/src/DispatchAdapter.h
new file mode 100644 (file)
index 0000000..f09544a
--- /dev/null
@@ -0,0 +1,52 @@
+// $Id: DispatchAdapter.h 14 2005-04-18 14:14:12Z cthuang $
+#ifndef DISPATCHADAPTER_H
+#define DISPATCHADAPTER_H
+
+#include "tcomApi.h"
+#include "DispatchImpl.h"
+
+// This class implements an IDispatch interface and delegates the operations to
+// the ComObject class.
+
+class TCOM_API DispatchAdapter: public IDispatch
+{
+    // provides IDispatch implementation
+    DispatchImpl m_dispatchImpl;
+
+    // not implemented
+    DispatchAdapter(const DispatchAdapter &);
+    void operator=(const DispatchAdapter &);
+
+public:
+    DispatchAdapter (
+        ComObject &object,
+        const Interface &interfaceDesc):
+            m_dispatchImpl(object, interfaceDesc)
+    { }
+
+    // IUnknown functions
+    STDMETHODIMP QueryInterface(REFIID iid, void **ppvObj);
+    STDMETHODIMP_(ULONG) AddRef();
+    STDMETHODIMP_(ULONG) Release();
+
+    // IDispatch functions
+    STDMETHODIMP GetTypeInfoCount(UINT *pctinfo);
+    STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo);
+    STDMETHODIMP GetIDsOfNames(
+        REFIID iid,
+        OLECHAR **rgszNames,
+        UINT cNames,
+        LCID lcid,
+        DISPID *rgdispid);
+    STDMETHODIMP Invoke(
+        DISPID dispidMember,
+        REFIID iid,
+        LCID lcid,
+        WORD flags,
+        DISPPARAMS *pParams,
+        VARIANT *pResult,
+        EXCEPINFO *pExcepInfo,
+        UINT *pArgErr);
+};
+
+#endif 
diff --git a/src/DispatchImpl.cpp b/src/DispatchImpl.cpp
new file mode 100644 (file)
index 0000000..02f544b
--- /dev/null
@@ -0,0 +1,66 @@
+// $Id: DispatchImpl.cpp 14 2005-04-18 14:14:12Z cthuang $
+#pragma warning(disable: 4786)
+#include "DispatchImpl.h"
+#include <stdexcept>
+#include "ComObject.h"
+
+DispatchImpl::DispatchImpl (
+    ComObject &object,
+    const Interface &interfaceDesc):
+        m_object(object),
+        m_interface(interfaceDesc)
+{
+    // Initialize dispatch member ID to method description map.
+    const Interface::Methods &methods = m_interface.methods();
+    for (Interface::Methods::const_iterator pMethod = methods.begin();
+     pMethod != methods.end(); ++pMethod) {
+        m_dispIdToMethodMap.insert(DispIdToMethodMap::value_type(
+            pMethod->memberid(), &(*pMethod)));
+    }
+
+    // Initialize set of property dispatch member ID's.
+    const Interface::Properties &properties = m_interface.properties();
+    for (Interface::Properties::const_iterator pProp = properties.begin();
+     pProp != properties.end(); ++pProp) {
+        m_propertyDispIds.insert(pProp->memberid());
+    }
+}
+
+const Method *
+DispatchImpl::findDispatchMethod (DISPID dispid)
+{
+    DispIdToMethodMap::const_iterator p = m_dispIdToMethodMap.find(dispid);
+    if (p == m_dispIdToMethodMap.end()) {
+        return 0;
+    }
+    return p->second;
+}
+
+HRESULT
+DispatchImpl::invoke (
+    DISPID dispid,
+    REFIID iid,
+    LCID lcid,
+    WORD wFlags,
+    DISPPARAMS *pDispParams,
+    VARIANT *pReturnValue,
+    EXCEPINFO *pExcepInfo,
+    UINT *pArgErr)
+{
+    // Get the method description for method being invoked.
+    const Method *pMethod = findDispatchMethod(dispid);
+    if (pMethod == 0) {
+        return DISP_E_MEMBERNOTFOUND;
+    }
+
+    return m_object.invoke(
+        *pMethod,
+        isProperty(dispid),
+        iid,
+        lcid,
+        wFlags,
+        pDispParams,
+        pReturnValue,
+        pExcepInfo,
+        pArgErr);
+}
diff --git a/src/DispatchImpl.h b/src/DispatchImpl.h
new file mode 100644 (file)
index 0000000..275d436
--- /dev/null
@@ -0,0 +1,67 @@
+// $Id: DispatchImpl.h 14 2005-04-18 14:14:12Z cthuang $
+#ifndef DISPATCHIMPL_H
+#define DISPATCHIMPL_H
+
+#include <map>
+#include <set>
+#include "tcomApi.h"
+#include "TypeInfo.h"
+
+class TCOM_API ComObject;
+
+// This class implements an IDispatch interface and delegates the operations to
+// the ComObject class.
+
+class TCOM_API DispatchImpl
+{
+    // delegate operations to this object
+    ComObject &m_object;
+
+    // description of the interface to implement
+    const Interface &m_interface;
+
+    // dispatch member ID to method description map
+    typedef std::map<DISPID, const Method *> DispIdToMethodMap;
+    DispIdToMethodMap m_dispIdToMethodMap;
+
+    // dispatch member ID's which are actually properties
+    typedef std::set<DISPID> DispIdSet;
+    DispIdSet m_propertyDispIds;
+
+    // not implemented
+    DispatchImpl(const DispatchImpl &);
+    void operator=(const DispatchImpl &);
+
+    // Get dispatch method description.
+    const Method *findDispatchMethod(DISPID dispid);
+
+    // Return true if the dispatch member ID identifies a property.
+    bool isProperty (DISPID dispid) const
+    { return m_propertyDispIds.count(dispid) != 0; }
+
+public:
+    DispatchImpl(
+        ComObject &object,
+        const Interface &interfaceDesc);
+
+    // Get object for delegating operations.
+    ComObject &object () const
+    { return m_object; }
+
+    // Get ITypeInfo for the interface that is implemented.
+    ITypeInfo *typeInfo () const
+    { return m_interface.typeInfo(); }
+
+    // Implement IDispatch::Invoke function.
+    HRESULT invoke(
+        DISPID dispidMember,
+        REFIID iid,
+        LCID lcid,
+        WORD flags,
+        DISPPARAMS *pParams,
+        VARIANT *pResult,
+        EXCEPINFO *pExcepInfo,
+        UINT *pArgErr);
+};
+
+#endif 
index 85d4abe2a7a3863ca356fb2436a580591fee9900..01c20372918d548e6a260bc9c11fada0278e96db 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: Extension.cpp,v 1.3 2003/04/02 22:46:51 cthuang Exp $
+// $Id: Extension.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "Extension.h"
 #include "ComModule.h"
index 7eb71165d36cbd50fb02fa6c5a57d90f9e025a39..a354e988ba7b5a05ff294029ea05a55aebfc28f4 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: Extension.h,v 1.5 2003/04/02 22:46:51 cthuang Exp $
+// $Id: Extension.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef EXTENSION_H
 #define EXTENSION_H
 
index d4d75dff6c15c2fb9332b73c16e3a7cf479bd4e1..a1a5d5264993f51935d83ede6d37ebdbc3d3e5de 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: HandleSupport.cpp,v 1.19 2003/07/17 22:33:31 cthuang Exp $
+// $Id: HandleSupport.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "HandleSupport.h"
 #include <sstream>
 #include "ThreadLocalStorage.h"
index d96a1fb2c1f90b01dcf581d0e9bfdf22c0d8acd2..d3a8d2d4db9574c9cf90bf4d97217e8cba5ade4a 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: HandleSupport.h,v 1.29 2003/07/17 22:33:31 cthuang Exp $
+// $Id: HandleSupport.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef HANDLESUPPORT_H
 #define HANDLESUPPORT_H
 
index 120b02906e8dcab8dbc89276489ad5c2ba30c0df..25f694931371aee522690094f8abfb901f11b18a 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: HashTable.h,v 1.22 2003/07/17 22:33:31 cthuang Exp $
+// $Id: HashTable.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef HASHTABLE_H
 #define HASHTABLE_H
 
index f1117e3899536ca9224c95a3e685192ffbd782db..1b644f2153d2d22290339ad5b2c7fa56b75b553d 100644 (file)
@@ -1,43 +1,28 @@
-// $Id: InterfaceAdapter.cpp,v 1.3 2002/02/27 01:58:45 cthuang Exp $
+// $Id: InterfaceAdapter.cpp 16 2005-04-19 14:47:52Z cthuang $
+#ifdef TCOM_VTBL_SERVER
+
 #pragma warning(disable: 4786)
-#include "ComObject.h"
 #include "InterfaceAdapter.h"
+#include "ComObject.h"
 
 InterfaceAdapter::InterfaceAdapter (
     ComObject &object,
     const Interface &interfaceDesc,
     bool forceDispatch):
-        m_object(object),
-        m_interface(interfaceDesc)
+        m_dispatchImpl(object, interfaceDesc)
 {
     // Initialize virtual function index to method description map.
-    const Interface::Methods &methods = m_interface.methods();
+    const Interface::Methods &methods = interfaceDesc.methods();
     for (Interface::Methods::const_iterator p = methods.begin();
      p != methods.end(); ++p) {
         m_vtblIndexToMethodMap.insert(VtblIndexToMethodMap::value_type(
             p->vtblIndex(), &(*p)));
     }
 
-    if (m_interface.dispatchable() || forceDispatch) {
-        m_pVtbl = dispatchVtbl;
-
-        // Initialize dispatch member ID to method description map.
-        const Interface::Methods &methods = m_interface.methods();
-        for (Interface::Methods::const_iterator pMethod = methods.begin();
-         pMethod != methods.end(); ++pMethod) {
-            m_dispIdToMethodMap.insert(DispIdToMethodMap::value_type(
-                pMethod->memberid(), &(*pMethod)));
-        }
-
-        // Initialize set of property dispatch member ID's.
-        const Interface::Properties &properties = m_interface.properties();
-        for (Interface::Properties::const_iterator pProp = properties.begin();
-         pProp != properties.end(); ++pProp) {
-            m_propertyDispIds.insert(pProp->memberid());
-        }
-
+    if (interfaceDesc.dispatchable() || forceDispatch) {
+        m_pVtbl = dualVtbl;
     } else {
-        m_pVtbl = unknownVtbl;
+        m_pVtbl = customVtbl;
     }
 }
 
@@ -52,35 +37,25 @@ InterfaceAdapter::findComMethod (int funcIndex)
     return p->second;
 }
 
-const Method *
-InterfaceAdapter::findDispatchMethod (DISPID dispid)
-{
-    DispIdToMethodMap::const_iterator p = m_dispIdToMethodMap.find(dispid);
-    if (p == m_dispIdToMethodMap.end()) {
-        return 0;
-    }
-    return p->second;
-}
-
 // Implement IUnknown methods
 
 STDMETHODIMP
 InterfaceAdapter::QueryInterface (
     InterfaceAdapter *pThis, REFIID iid, void **ppvObj)
 {
-   return pThis->m_object.queryInterface(iid, ppvObj);
+   return pThis->m_dispatchImpl.object().queryInterface(iid, ppvObj);
 }
 
 STDMETHODIMP_(ULONG)
 InterfaceAdapter::AddRef (InterfaceAdapter *pThis)
 {
-    return pThis->m_object.addRef();
+    return pThis->m_dispatchImpl.object().addRef();
 }
 
 STDMETHODIMP_(ULONG)
 InterfaceAdapter::Release (InterfaceAdapter *pThis)
 {
-    return pThis->m_object.release();
+    return pThis->m_dispatchImpl.object().release();
 }
 
 // Implement IDispatch methods
@@ -101,7 +76,7 @@ InterfaceAdapter::GetTypeInfo (
         return DISP_E_BADINDEX;
     }
 
-    ITypeInfo *pTypeInfo = pThis->m_interface.typeInfo();
+    ITypeInfo *pTypeInfo = pThis->m_dispatchImpl.typeInfo();
     pTypeInfo->AddRef();
     *ppTypeInfo = pTypeInfo;
     return S_OK;
@@ -116,7 +91,7 @@ InterfaceAdapter::GetIDsOfNames (
     LCID,
     DISPID *rgDispId)
 {
-    ITypeInfo *pTypeInfo = pThis->m_interface.typeInfo();
+    ITypeInfo *pTypeInfo = pThis->m_dispatchImpl.typeInfo();
     return pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId);
 }
 
@@ -132,8 +107,7 @@ InterfaceAdapter::Invoke (
     EXCEPINFO *pExcepInfo,
     UINT *pArgErr)
 {
-    return pThis->m_object.invoke(
-        pThis,
+    return pThis->m_dispatchImpl.invoke(
         dispid,
         iid,
         lcid,
@@ -143,3 +117,5 @@ InterfaceAdapter::Invoke (
         pExcepInfo,
         pArgErr);
 }
+
+#endif
index 19bc8e02079ce292e0722bc9603037d29683c206..6d6b3305e8ada767ee61f86f8babfe8b8fd36f8b 100644 (file)
@@ -1,11 +1,11 @@
-// $Id: InterfaceAdapter.h,v 1.3 2002/02/27 01:58:45 cthuang Exp $
+// $Id: InterfaceAdapter.h 16 2005-04-19 14:47:52Z cthuang $
 #ifndef INTERFACEADAPTER_H
 #define INTERFACEADAPTER_H
 
 #include <map>
 #include <set>
 #include "tcomApi.h"
-#include "TypeInfo.h"
+#include "DispatchImpl.h"
 
 class TCOM_API ComObject;
 
@@ -22,31 +22,21 @@ class TCOM_API InterfaceAdapter
     const void *m_pVtbl;
 
     // delegate operations to this object
-    ComObject &m_object;
-
-    // description of the interface to implement
-    const Interface &m_interface;
+    DispatchImpl m_dispatchImpl;
 
     // virtual function index to method description map
     typedef std::map<short, const Method *> VtblIndexToMethodMap;
     VtblIndexToMethodMap m_vtblIndexToMethodMap;
 
-    // dispatch member ID to method description map
-    typedef std::map<DISPID, const Method *> DispIdToMethodMap;
-    DispIdToMethodMap m_dispIdToMethodMap;
-
-    // dispatch member ID's which are actually properties
-    typedef std::set<DISPID> DispIdSet;
-    DispIdSet m_propertyDispIds;
-
-    // virtual function table for IUnknown derived interfaces
-    static const void *unknownVtbl[];
+    // virtual function table for custom (IUnknown derived) interfaces
+    static const void *customVtbl[];
 
-    // virtual function table for IDispatch derived interfaces
-    static const void *dispatchVtbl[];
+    // virtual function table for dual (IDispatch derived) interfaces
+    static const void *dualVtbl[];
 
-    InterfaceAdapter(const InterfaceAdapter &); // not implemented
-    void operator=(const InterfaceAdapter &);   // not implemented
+     // not implemented
+    InterfaceAdapter(const InterfaceAdapter &);
+    void operator=(const InterfaceAdapter &);
 
 public:
     InterfaceAdapter(
@@ -56,18 +46,11 @@ public:
 
     // Get delegate object.
     ComObject &object () const
-    { return m_object; }
+    { return m_dispatchImpl.object(); }
 
     // Get COM method description.
     const Method *findComMethod(int funcIndex);
 
-    // Get dispatch method description.
-    const Method *findDispatchMethod(DISPID dispid);
-
-    // Return true if the dispatch member ID identifies a property.
-    bool isProperty (DISPID dispid) const
-    { return m_propertyDispIds.count(dispid) != 0; }
-
     // IUnknown implementation
     static STDMETHODIMP QueryInterface(
         InterfaceAdapter *pThis, REFIID iid, void **ppvObj);
index 896f36dd5f64030e17bd051180308db9df2fbc3d..8ab5ce57872dbff96a4b3c7d393e8013fa86753b 100644 (file)
@@ -1,4 +1,6 @@
-// $Id: InterfaceAdapterVtbl.cpp,v 1.3 2001/10/13 17:56:14 Administrator Exp $
+// $Id: InterfaceAdapterVtbl.cpp 16 2005-04-19 14:47:52Z cthuang $
+#ifdef TCOM_VTBL_SERVER
+
 #pragma warning(disable: 4786)
 #include "InterfaceAdapter.h"
 #include "ComObject.h"
@@ -1076,7 +1078,7 @@ FUNCTION_ENTRY_POINT(1021)
 FUNCTION_ENTRY_POINT(1022)
 FUNCTION_ENTRY_POINT(1023)
 
-const void *InterfaceAdapter::unknownVtbl[] = {
+const void *InterfaceAdapter::customVtbl[] = {
     InterfaceAdapter::QueryInterface,
     InterfaceAdapter::AddRef,
     InterfaceAdapter::Release,
@@ -2103,7 +2105,7 @@ const void *InterfaceAdapter::unknownVtbl[] = {
     function_1023
 };
 
-const void *InterfaceAdapter::dispatchVtbl[] = {
+const void *InterfaceAdapter::dualVtbl[] = {
     InterfaceAdapter::QueryInterface,
     InterfaceAdapter::AddRef,
     InterfaceAdapter::Release,
@@ -3129,3 +3131,5 @@ const void *InterfaceAdapter::dispatchVtbl[] = {
     function_1022,
     function_1023
 };
+
+#endif
index 9c9c30960605c487909fefcaace7982296632b9b..5d9375ec9e6b6417e292cd97cc8832306c12acca 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.12 2003/07/24 22:46:35 cthuang Exp $
+# $Id: Makefile 5 2005-02-16 14:57:24Z cthuang $
 
 debug:
        tclsh &&|
diff --git a/src/NativeValue.cpp b/src/NativeValue.cpp
new file mode 100644 (file)
index 0000000..b171e9a
--- /dev/null
@@ -0,0 +1,12 @@
+// $Id: NativeValue.cpp 5 2005-02-16 14:57:24Z cthuang $
+#include "NativeValue.h"
+
+void
+NativeValue::fixInvalidVariantType ()
+{
+    if (vt == VT_I8 || vt == VT_UI8) {
+        // 64-bit integers are not valid VARIANT types.  Change the VARIANT
+        // type to something valid so VariantClear does not return an error.
+        vt = VT_EMPTY;
+    }
+}
diff --git a/src/NativeValue.h b/src/NativeValue.h
new file mode 100644 (file)
index 0000000..8e8df33
--- /dev/null
@@ -0,0 +1,25 @@
+// $Id: NativeValue.h 5 2005-02-16 14:57:24Z cthuang $
+#ifndef NATIVEVALUE_H
+#define NATIVEVALUE_H
+
+#include <comdef.h>
+
+// This is a value in the native machine format.
+
+class NativeValue: public _variant_t
+{
+public:
+    NativeValue ()
+    { }
+
+    ~NativeValue ()
+    { fixInvalidVariantType(); }
+
+    NativeValue &operator= (const _variant_t &rhs)
+    { _variant_t::operator=(rhs); return *this; }
+
+    // Change the variant type if it is invalid.
+    void fixInvalidVariantType();
+};
+
+#endif
index 9a7f44835c1de5045caae45bdce31f1072ebb3b5..3e210470fab204fb13e932c3828d8e5448fc0a43 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: Reference.cpp,v 1.73 2003/11/06 15:29:01 cthuang Exp $
+// $Id: Reference.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include <string.h>
 #include "ComObject.h"
@@ -231,6 +231,8 @@ Reference::invokeDispatch (
 
     if (hr == DISP_E_EXCEPTION) {
         throwDispatchException(excepInfo);
+    } else if (hr == DISP_E_TYPEMISMATCH || hr == DISP_E_PARAMNOTFOUND) {
+        throw InvokeException(hr, pParams->cArgs - argErr);
     }
 
     return hr;
@@ -264,6 +266,8 @@ Reference::invoke (MEMBERID memberid,
 
         if (hr == DISP_E_EXCEPTION) {
             throwDispatchException(excepInfo);
+        } else if (hr == DISP_E_TYPEMISMATCH || hr == DISP_E_PARAMNOTFOUND) {
+            throw InvokeException(hr, arguments.dispParams()->cArgs - argErr);
         }
     }
 
index fc4693111631a52cd0028ffeaa6e0a1f3646f833..003b8f19eaad1b500a89117e84206f66207cb6f0 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: Reference.h,v 1.42 2003/11/06 15:29:01 cthuang Exp $
+// $Id: Reference.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef REFERENCE_H
 #define REFERENCE_H
 
@@ -29,6 +29,26 @@ public:
     { return m_description; }
 };
 
+// Throw this exception when invoke returns error about an argument.
+
+class InvokeException
+{
+    HRESULT m_hresult;
+    unsigned m_argIndex;
+
+public:
+    InvokeException (HRESULT hresult, unsigned argIndex):
+        m_hresult(hresult),
+        m_argIndex(argIndex)
+    { }
+
+    HRESULT hresult () const
+    { return m_hresult; }
+
+    unsigned argIndex () const
+    { return m_argIndex; }
+};
+
 // This class holds an interface pointer and the interface description needed
 // to invoke methods on it.
 
index 4a9f3be1040e3c0cf5080143eeba0b74a0fe973a..02aeb7aa41b280d67e36405d73cd34e06755985f 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: RegistryKey.cpp,v 1.6 2001/11/28 16:10:57 cthuang Exp $
+// $Id: RegistryKey.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "RegistryKey.h"
 
 void
index e1b06daa4bca7f7b93eeb1779593f9467d478b02..819ae6de915dd99be098c560e25fb43ceeb875cd 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: RegistryKey.h,v 1.5 2001/11/28 16:10:57 cthuang Exp $
+// $Id: RegistryKey.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef REGISTRYKEY_H
 #define REGISTRYKEY_H
 
index 7a6543ae10594f3ac0881f99e96d2b1543e33869..078d93d9855d5688b9d96756a03e3181ace0ef88 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: Singleton.h,v 1.9 2002/04/13 03:53:56 cthuang Exp $
+// $Id: Singleton.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef SINGLETON_H
 #define SINGLETON_H
 
index e2dd645d164b3b6fd37fef06c357c3c1f6e8b19c..a8e132ca82a28dc3a75e86106cf9e6aef4a7282a 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: SupportErrorInfo.cpp,v 1.3 2001/07/17 02:24:08 cthuang Exp $
+// $Id: SupportErrorInfo.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "ComObject.h"
 #include "SupportErrorInfo.h"
 
index 40d94b549e96cf5566c5d624e40b593489f59652..806049f07c05fe37d80d58999ab8a3ba47a0d2ca 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: SupportErrorInfo.h,v 1.3 2001/07/17 02:24:08 cthuang Exp $
+// $Id: SupportErrorInfo.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef SUPPORTERRORINFO_H
 #define SUPPORTERRORINFO_H
 
index 0a2f93acf935cea87708863ee5ccea99c6244cf2..6e9aa0d9a4158d7391969edccc5fdf902639f93c 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TclInterp.cpp,v 1.12 2002/04/13 03:53:56 cthuang Exp $
+// $Id: TclInterp.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include <sstream>
 #include "RegistryKey.h"
 #include "TclObject.h"
index bbfa522568ddcd9d554fe4e9b3653f5183327853..350695c1a456f9396c699e0bbb48538b33121fb1 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TclInterp.h,v 1.8 2002/04/13 03:53:56 cthuang Exp $
+// $Id: TclInterp.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef TCLINTERP_H
 #define TCLINTERP_H
 
index 3a4f05c253a0710a6a5cd91173c70025669613ef..7c8513620b5eaaa9d2e5478564387e3a2e43d8bf 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TclModule.cpp,v 1.5 2002/04/13 03:53:56 cthuang Exp $
+// $Id: TclModule.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "TclObject.h"
 #include "TclModule.h"
index af95d6b4ce5e1eee0393d2850f6429ce52b189a6..37097654604e036556d009644d19c1c189e2968d 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TclModule.h,v 1.4 2002/04/13 03:53:56 cthuang Exp $
+// $Id: TclModule.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef TCLMODULE_H
 #define TCLMODULE_H
 
index 8c24d8a611f41393d37e894e1085900302ba2142..2a924b6fd0ff193c1e7aab95430278559a164a5d 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TclObject.cpp,v 1.35 2003/05/12 23:30:43 cthuang Exp $
+// $Id: TclObject.cpp 18 2005-05-03 00:40:40Z cthuang $
 #include "TclObject.h"
 #include <vector>
 #ifdef WIN32
@@ -158,7 +158,7 @@ TclObject::lappend (Tcl_Obj *pElement)
 static Tcl_Obj *
 convertFromSafeArray (
     SAFEARRAY *psa,
-    VARTYPE vt,
+    VARTYPE elementType,
     unsigned dim,
     long *pIndices,
     const Type &type,
@@ -185,14 +185,14 @@ convertFromSafeArray (
         pResult = Tcl_NewListObj(0, 0);
         for (long i = lowerBound; i <= upperBound; ++i) {
             pIndices[dim - 1] = i;
-            Tcl_Obj *pElement =
-                convertFromSafeArray(psa, vt, dim + 1, pIndices, type, interp);
+            Tcl_Obj *pElement = convertFromSafeArray(
+                psa, elementType, dim + 1, pIndices, type, interp);
             Tcl_ListObjAppendElement(interp, pResult, pElement);
         }
         return pResult;
     }
 
-    if (vt == VT_UI1 && SafeArrayGetDim(psa) == 1) {
+    if (elementType == VT_UI1 && SafeArrayGetDim(psa) == 1) {
         unsigned char *pData;
         hr = SafeArrayAccessData(psa, reinterpret_cast<void **>(&pData));
         if (FAILED(hr)) {
@@ -218,14 +218,14 @@ convertFromSafeArray (
         // Create list of Tcl values.
         pResult = Tcl_NewListObj(0, 0);
         for (long i = lowerBound; i <= upperBound; ++i) {
-            _variant_t elementVar;
+            NativeValue elementVar;
 
             pIndices[dim - 1] = i;
-            if (vt == VT_VARIANT) {
+            if (elementType == VT_VARIANT) {
                 hr = SafeArrayGetElement(psa, pIndices, &elementVar);
             } else {
                 // I hope the element can be contained in a VARIANT.
-                V_VT(&elementVar) = vt;
+                V_VT(&elementVar) = elementType;
                 hr = SafeArrayGetElement(psa, pIndices, &elementVar.punkVal);
             }
             if (FAILED(hr)) {
@@ -284,8 +284,8 @@ fillSafeArray (
     } else {
         for (int i = 0; i < numElements; ++i) {
             TclObject element(pElements[i]); 
-            _variant_t elementVar;
-            element.toVariant(&elementVar, Type::variant(), interp, addRef);
+            NativeValue elementVar;
+            element.toNativeValue(&elementVar, Type::variant(), interp, addRef);
 
             pIndices[dim1] = i;
             hr = SafeArrayPutElement(psa, pIndices, &elementVar);
@@ -296,15 +296,28 @@ fillSafeArray (
     }
 }
 
+static Tcl_Obj *
+convertFromUnknown (IUnknown *pUnknown, REFIID iid, Tcl_Interp *interp)
+{
+    if (pUnknown == 0) {
+        return Tcl_NewObj();
+    }
+
+    const Interface *pInterface = InterfaceManager::instance().find(iid);
+    return Extension::referenceHandles.newObj(
+        interp,
+        Reference::newReference(pUnknown, pInterface));
+}
+
 TclObject::TclObject (VARIANT *pSrc, const Type &type, Tcl_Interp *interp)
 {
-    if (V_VT(pSrc) & VT_ARRAY) {
-        SAFEARRAY *psa = V_ARRAY(pSrc);
-        VARTYPE vt = V_VT(pSrc) & VT_TYPEMASK;
+    if (V_ISARRAY(pSrc)) {
+        SAFEARRAY *psa = V_ISBYREF(pSrc) ? *V_ARRAYREF(pSrc) : V_ARRAY(pSrc);
+        VARTYPE elementType = V_VT(pSrc) & VT_TYPEMASK;
         unsigned numDimensions = SafeArrayGetDim(psa);
         std::vector<long> indices(numDimensions);
         m_pObj = convertFromSafeArray(
-            psa, vt, 1, &indices[0], type, interp);
+            psa, elementType, 1, &indices[0], type, interp);
 
     } else if (vtMissing == pSrc) {
         m_pObj = Extension::newNaObj();
@@ -315,6 +328,10 @@ TclObject::TclObject (VARIANT *pSrc, const Type &type, Tcl_Interp *interp)
             m_pObj = Tcl_NewBooleanObj(V_BOOL(pSrc));
             break;
 
+        case VT_ERROR:
+            m_pObj = Tcl_NewLongObj(V_ERROR(pSrc));
+            break;
+
         case VT_I1:
         case VT_UI1:
             m_pObj = Tcl_NewLongObj(V_I1(pSrc));
@@ -332,6 +349,13 @@ TclObject::TclObject (VARIANT *pSrc, const Type &type, Tcl_Interp *interp)
             m_pObj = Tcl_NewLongObj(V_I4(pSrc));
             break;
 
+#ifdef V_I8
+        case VT_I8:
+        case VT_UI8:
+            m_pObj = Tcl_NewWideIntObj(V_I8(pSrc));
+            break;
+#endif
+
         case VT_R4:
             m_pObj = Tcl_NewDoubleObj(V_R4(pSrc));
             break;
@@ -342,27 +366,25 @@ TclObject::TclObject (VARIANT *pSrc, const Type &type, Tcl_Interp *interp)
             break;
 
         case VT_DISPATCH:
-            if (V_DISPATCH(pSrc) == 0) {
-                m_pObj = Tcl_NewObj();
-            } else {
-                const Interface *pInterface =
-                    InterfaceManager::instance().find(type.iid());
-                m_pObj = Extension::referenceHandles.newObj(
-                    interp,
-                    Reference::newReference(V_DISPATCH(pSrc), pInterface));
-            }
+            m_pObj = convertFromUnknown(V_DISPATCH(pSrc), type.iid(), interp);
+            break;
+
+        case VT_DISPATCH | VT_BYREF:
+            m_pObj = convertFromUnknown(
+                (V_DISPATCHREF(pSrc) != 0) ? *V_DISPATCHREF(pSrc) : 0,
+                type.iid(),
+                interp);
             break;
 
         case VT_UNKNOWN:
-            if (V_UNKNOWN(pSrc) == 0) {
-                m_pObj = Tcl_NewObj();
-            } else {
-                const Interface *pInterface =
-                    InterfaceManager::instance().find(type.iid());
-                m_pObj = Extension::referenceHandles.newObj(
-                    interp,
-                    Reference::newReference(V_UNKNOWN(pSrc), pInterface));
-            }
+            m_pObj = convertFromUnknown(V_UNKNOWN(pSrc), type.iid(), interp);
+            break;
+
+        case VT_UNKNOWN | VT_BYREF:
+            m_pObj = convertFromUnknown(
+                (V_UNKNOWNREF(pSrc) != 0) ? *V_UNKNOWNREF(pSrc) : 0,
+                type.iid(),
+                interp);
             break;
 
         case VT_NULL:
@@ -392,6 +414,10 @@ TclObject::TclObject (VARIANT *pSrc, const Type &type, Tcl_Interp *interp)
                 m_pObj = Tcl_NewStringObj(
                     const_cast<char *>(uuid.toString().c_str()), -1);
             } else {
+                if (V_VT(pSrc) == (VT_VARIANT | VT_BYREF)) {
+                    pSrc = V_VARIANTREF(pSrc);
+                }
+
                 _bstr_t str(pSrc);
 #if TCL_MINOR_VERSION >= 2
                 // Uses Unicode function introduced in Tcl 8.2.
@@ -408,6 +434,33 @@ TclObject::TclObject (VARIANT *pSrc, const Type &type, Tcl_Interp *interp)
     Tcl_IncrRefCount(m_pObj);
 }
 
+TclObject::TclObject (const _bstr_t &src)
+{
+    if (src.length() > 0) {
+#if TCL_MINOR_VERSION >= 2
+        // Uses Unicode functions introduced in Tcl 8.2.
+        m_pObj = Tcl_NewUnicodeObj(src, -1);
+#else
+        m_pObj = Tcl_NewStringObj(src, -1);
+#endif
+    } else {
+        m_pObj = Tcl_NewObj();
+    }
+
+    Tcl_IncrRefCount(m_pObj);
+}
+
+TclObject::TclObject (
+    SAFEARRAY *psa, const Type &type, Tcl_Interp *interp)
+{
+    unsigned numDimensions = SafeArrayGetDim(psa);
+    std::vector<long> indices(numDimensions);
+    m_pObj = convertFromSafeArray(
+        psa, type.elementType().vartype(), 1, &indices[0], type, interp);
+
+    Tcl_IncrRefCount(m_pObj);
+}
+
 BSTR
 TclObject::getBSTR () const
 {
@@ -453,6 +506,83 @@ newByteSafeArray (Tcl_Obj *pObj)
 }
 #endif
 
+SAFEARRAY *
+TclObject::getSafeArray (const Type &elementType, Tcl_Interp *interp) const
+{
+    SAFEARRAY *psa;
+
+    if (elementType.vartype() == VT_UI1) {
+        psa = newByteSafeArray(m_pObj);
+    } else {
+        // Convert Tcl list to SAFEARRAY.
+        int numElements;
+        Tcl_Obj **pElements;
+        if (Tcl_ListObjGetElements(interp, m_pObj, &numElements, &pElements)
+          != TCL_OK) {
+            _com_issue_error(E_INVALIDARG);
+        }
+
+        psa = SafeArrayCreateVector(elementType.vartype(), 0, numElements);
+        if (psa == 0) {
+            _com_issue_error(E_OUTOFMEMORY);
+        }
+
+        void *pData;
+        HRESULT hr;
+        hr = SafeArrayAccessData(psa, &pData);
+        if (FAILED(hr)) {
+            _com_issue_error(hr);
+        }
+
+        for (int i = 0; i < numElements; ++i) {
+            TclObject value(pElements[i]);
+
+            switch (elementType.vartype()) {
+            case VT_BOOL:
+                static_cast<VARIANT_BOOL *>(pData)[i] =
+                    value.getBool() ? VARIANT_TRUE : VARIANT_FALSE;
+                break;
+
+            case VT_I2:
+            case VT_UI2:
+                static_cast<short *>(pData)[i] = value.getLong();
+                break;
+
+            case VT_R4:
+                static_cast<float *>(pData)[i] =
+                    static_cast<float>(value.getDouble());
+                break;
+
+            case VT_R8:
+                static_cast<double *>(pData)[i] = value.getDouble();
+                break;
+
+            case VT_BSTR:
+                static_cast<BSTR *>(pData)[i] = value.getBSTR();
+                break;
+
+            case VT_VARIANT:
+                {
+                    VARIANT *pDest = static_cast<VARIANT *>(pData) + i;
+                    VariantInit(pDest);
+                    value.toVariant(pDest, elementType, interp);
+                }
+                break;
+
+            default:
+                static_cast<int *>(pData)[i] = value.getLong();
+            }
+        }
+
+        hr = SafeArrayUnaccessData(psa);
+        if (FAILED(hr)) {
+            _com_issue_error(hr);
+        }
+    }
+
+    return psa;
+}
+
 void
 TclObject::toVariant (VARIANT *pDest,
                       const Type &type,
@@ -493,75 +623,10 @@ TclObject::toVariant (VARIANT *pDest,
         V_UNKNOWN(pDest) = pUnknown;
 
     } else if (vt == VT_SAFEARRAY) {
-        SAFEARRAY *psa;
-        const Type &elementType = type.elementType();
-
-        if (elementType.vartype() == VT_UI1) {
-            psa = newByteSafeArray(m_pObj);
-        } else {
-            // Convert Tcl list to SAFEARRAY.
-            int numElements;
-            Tcl_Obj **pElements;
-            if (Tcl_ListObjGetElements(interp, m_pObj, &numElements, &pElements)
-              != TCL_OK) {
-                _com_issue_error(E_INVALIDARG);
-            }
-
-            psa = SafeArrayCreateVector(elementType.vartype(), 0, numElements);
-            if (psa == 0) {
-                _com_issue_error(E_OUTOFMEMORY);
-            }
-
-            void *pData;
-            HRESULT hr;
-            hr = SafeArrayAccessData(psa, &pData);
-            if (FAILED(hr)) {
-                _com_issue_error(hr);
-            }
-
-            for (int i = 0; i < numElements; ++i) {
-                TclObject value(pElements[i]);
-
-                switch (elementType.vartype()) {
-                case VT_BOOL:
-                    static_cast<VARIANT_BOOL *>(pData)[i] =
-                        value.getBool() ? VARIANT_TRUE : VARIANT_FALSE;
-                    break;
-
-                case VT_R4:
-                    static_cast<float *>(pData)[i] =
-                        static_cast<float>(value.getDouble());
-                    break;
-
-                case VT_R8:
-                    static_cast<double *>(pData)[i] = value.getDouble();
-                    break;
-
-                case VT_BSTR:
-                    static_cast<BSTR *>(pData)[i] = value.getBSTR();
-                    break;
-
-                case VT_VARIANT:
-                    {
-                        VARIANT *pDest = static_cast<VARIANT *>(pData) + i;
-                        VariantInit(pDest);
-                        value.toVariant(pDest, elementType, interp);
-                    }
-                    break;
-
-                default:
-                    static_cast<int *>(pData)[i] = value.getLong();
-                }
-            }
-
-            hr = SafeArrayUnaccessData(psa);
-            if (FAILED(hr)) {
-                _com_issue_error(hr);
-            }
-        }
 
+        const Type &elementType = type.elementType();
         V_VT(pDest) = VT_ARRAY | elementType.vartype();
-        V_ARRAY(pDest) = psa;
+        V_ARRAY(pDest) = getSafeArray(elementType, interp);
 
     } else if (m_pObj->typePtr == TclTypes::listType()) {
         // Convert Tcl list to array of VARIANT.
@@ -678,4 +743,26 @@ TclObject::toVariant (VARIANT *pDest,
     }
 }
 
+
+void
+TclObject::toNativeValue (NativeValue *pDest,
+                          const Type &type,
+                          Tcl_Interp *interp,
+                          bool addRef)
+{
+#ifdef V_I8
+    VARTYPE vt = type.vartype();
+    if (vt == VT_I8 || vt == VT_UI8) {
+        pDest->fixInvalidVariantType();
+        VariantClear(pDest);
+        V_VT(pDest) = vt;
+        Tcl_GetWideIntFromObj(interp, m_pObj, &V_I8(pDest));
+        return;
+    }
+#endif
+
+    pDest->fixInvalidVariantType();
+    toVariant(pDest, type, interp, addRef);
+}
+
 #endif
index 9a715029d91ae6970fe6de3ebc440d6f5a6d3294..35c3cb206faaf1195ca679bdf52e59b4deb156ee 100644 (file)
@@ -1,9 +1,10 @@
-// $Id: TclObject.h,v 1.12 2002/04/12 02:55:28 cthuang Exp $
+// $Id: TclObject.h 16 2005-04-19 14:47:52Z cthuang $
 #ifndef TCLOBJECT_H
 #define TCLOBJECT_H
 
 #ifdef WIN32
 #include "TypeInfo.h"
+#include "NativeValue.h"
 #endif
 #include <tcl.h>
 #include <string>
@@ -101,12 +102,21 @@ public:
     TclObject &lappend(Tcl_Obj *pElement);
 
 #ifdef WIN32
-    // Construct Tcl object from VARIANT value.
+    // Construct Tcl object from native machine value.
     TclObject(
-        VARIANT *pSrc,          // VARIANT value to convert from
+        VARIANT *pSrc,          // value to convert from
         const Type &type,       // expected type for interface pointers
         Tcl_Interp *interp);
 
+    // Construct Tcl object from _bstr_t.
+    TclObject(const _bstr_t &src);
+
+    // Construct Tcl object from SAFEARRAY.
+    TclObject(
+        SAFEARRAY *psa,         // value to convert from
+        const Type &type,       // array type
+        Tcl_Interp *interp);
+
     // Convert Tcl object to VARIANT value.
     void toVariant(
         VARIANT *pDest,         // converted value put here
@@ -114,9 +124,20 @@ public:
         Tcl_Interp *interp,
         bool addRef=false);     // call AddRef on interface pointer
 
+    // Convert Tcl object to native machine value.
+    void toNativeValue(
+        NativeValue *pDest,     // converted value put here
+        const Type &type,       // desired data type
+        Tcl_Interp *interp,
+        bool addRef=false);     // call AddRef on interface pointer
+
     // Get BSTR representation.  Caller is responsible for freeing the
     // returned BSTR.
     BSTR getBSTR() const;
+
+    // Get SAFEARRAY representation.  Caller is responsible for freeing the
+    // returned array.
+    SAFEARRAY *getSafeArray(const Type &elementType, Tcl_Interp *interp) const;
 #endif
 };
 
index df521430a340d6a41432c8566e6930daaa2304c9..1f43bf1c3d84ca093a99fe2e86fdb6e522fc5971 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TclScript.cpp,v 1.12 2003/04/02 22:46:51 cthuang Exp $
+// $Id: TclScript.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "ActiveScriptError.h"
 #include "Reference.h"
 #include "TypeInfo.h"
index 914a68838c8cb163af7bfc9584d63dd8647cbb22..7208227f9ec50cba444478dafe6c15aeae34c434 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TclScriptVersion.rc,v 1.3 2002/04/27 18:15:24 cthuang Exp $
+// $Id: TclScriptVersion.rc 5 2005-02-16 14:57:24Z cthuang $
 #include <winres.h>
 #include "version.h"
 #include "buildNumber.h"
index 71770d1cbbf6ce8c512c6b52b86e9cad82df82a9..804dc954c21cc85abf6ece7ecd4897b9795ed6e6 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ThreadLocalStorage.h,v 1.1 2002/04/20 15:43:57 cthuang Exp $
+// $Id: ThreadLocalStorage.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef THREADLOCALSTORAGE_H
 #define THREADLOCALSTORAGE_H
 
index 39b5fda6e19cefa1f7e49438d744198beb4079a0..04775ed6080a4a1ae12e3f69813ddd7b806d754d 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TypeInfo.cpp,v 1.58 2002/04/20 06:11:32 cthuang Exp $
+// $Id: TypeInfo.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include <sstream>
 #include <map>
@@ -35,7 +35,7 @@ static VarTypeStringAssoc varTypeStringAssocs[] = {
     { VT_DATE, "DATE" },
     { VT_BSTR, "BSTR" },
     { VT_DISPATCH, "DISPATCH" },
-    { VT_ERROR, "ERROR" },
+    { VT_ERROR, "SCODE" },
     { VT_BOOL, "BOOL" },
     { VT_VARIANT, "VARIANT" },
     { VT_UNKNOWN, "UNKNOWN" },
index 2794e1a9e9f7c09dfe70d2888e1a57b73a308009..1dd13a2e6f446db7a740ceb0124f675fde9d5279 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TypeInfo.h,v 1.41 2002/04/20 06:11:32 cthuang Exp $
+// $Id: TypeInfo.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef TYPEINFO_H
 #define TYPEINFO_H
 
index 37f4591b3a8887d72a4f08ead47ced977225fc17..8bc99ae2f62310b12fd1b46bd28c51aa8b9127a1 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TypeLib.cpp,v 1.29 2002/03/09 16:40:24 cthuang Exp $
+// $Id: TypeLib.cpp 9 2005-04-07 14:14:37Z cthuang $
 #pragma warning(disable: 4786)
 #include <sstream>
 #include "RegistryKey.h"
@@ -148,7 +148,7 @@ TypeLib::loadByLibid (const std::string &libidStr, const std::string &version)
 
     ITypeLibPtr pTypeLib;
     HRESULT hr = LoadRegTypeLib(
-        libid, majorVersion, minorVersion, LOCALE_USER_DEFAULT, &pTypeLib);
+        libid, majorVersion, minorVersion, LOCALE_NEUTRAL, &pTypeLib);
     if (FAILED(hr)) {
         _com_issue_error(hr);
     }
index 8d989a198cd2e689f3133b4f5dd6e1c9ed267cd8..417f4a30dbd4a4e8466cf4427269cebb20893360 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: TypeLib.h,v 1.21 2002/03/09 16:40:24 cthuang Exp $
+// $Id: TypeLib.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef TYPELIB_H
 #define TYPELIB_H
 
index a45e74088de6f163735dd610fced2d70e64d60f8..cbc078225cb20e6b916d1742ae44e2d1379c2503 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: Uuid.cpp,v 1.2 2000/04/20 18:37:40 chuang Exp $
+// $Id: Uuid.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "Uuid.h"
 
 std::string
index ab01674a47911980360ea36e2d268f18c0f7909c..6aa1d2177bff3d461b89dfb420556fba2a685979 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: Uuid.h,v 1.3 2000/04/28 19:37:53 chuang Exp $
+// $Id: Uuid.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef UUID_H
 #define UUID_H
 
index 7b0c253a04c556a631bbe838cc41bf1361e9ff5e..80b80faf93875d61adf6a27bcc7899e9c3657f1f 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: bindCmd.cpp,v 1.53 2003/04/02 22:46:51 cthuang Exp $
+// $Id: bindCmd.cpp 13 2005-04-18 12:24:14Z cthuang $
 #pragma warning(disable: 4786)
 #include "Extension.h"
 #include "Reference.h"
index 7fe11cc39a8fdb8f42ddd39202a294a85b21e89c..e5f4509c6537b97cefa94878e143ddf866587a9a 100644 (file)
@@ -1 +1 @@
-#define BUILD_NUMBER 28
+#define BUILD_NUMBER 33
index 7e8ee1c4470115c8b78eab37d2b9e4cfc710e680..633e33d2e7a81f8d66c8868f950a90ded2292543 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: configureCmd.cpp,v 1.7 2002/04/13 03:53:57 cthuang Exp $
+// $Id: configureCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "Extension.h"
 
index 537d1c17352a97f23d1c0da657569e4562680705..a88805fc04becf3fbb8cfedc54b437fa3f73d770 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: dllmain.cpp,v 1.16 2002/07/14 18:42:57 cthuang Exp $
+// $Id: dllmain.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "Uuid.h"
 #include "HandleSupport.h"
index 34ad2593c17db46496a93f549a2bc345e71273db..eb1662c0443510c417dfd65a3c589b6092b3aae2 100644 (file)
@@ -43,7 +43,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DLLSERVER_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "\tcl\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DLLSERVER_EXPORTS" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "\tcl\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -69,7 +69,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DLLSERVER_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "\tcl\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DLLSERVER_EXPORTS" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "\tcl\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /GZ /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
index 484be115fc3ea10c303b0523ab80a56efd784dd3..1de70de086932bb1cf54d42a6db6159fd3213039 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: dllserverVersion.rc,v 1.5 2002/04/27 18:15:24 cthuang Exp $
+// $Id: dllserverVersion.rc 5 2005-02-16 14:57:24Z cthuang $
 #include <winres.h>
 #include "version.h"
 #include "buildNumber.h"
index abd3919412e47a643f126940ceb1bba0ca09189e..0dee0b86ea064dbadd19ed64002ec620006b7e6d 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: exemain.cpp,v 1.12 2002/07/14 18:42:57 cthuang Exp $
+// $Id: exemain.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "TclModule.h"
 #include "tclRunTime.h"
index 711106b60461ca7a468e7453091b07ee77832e2d..78753ce6e87c1c2e7688dabb6ad8b155040fde57 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: exeserverVersion.rc,v 1.5 2002/04/27 18:15:24 cthuang Exp $
+// $Id: exeserverVersion.rc 5 2005-02-16 14:57:24Z cthuang $
 #include <winres.h>
 #include "version.h"
 #include "buildNumber.h"
index d61e3bbc09f26bcadce9867414ffe04149b1e1fe..f6e57589db267b8add570bc879aa25aab2653e36 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: foreachCmd.cpp,v 1.10 2002/05/31 04:03:06 cthuang Exp $
+// $Id: foreachCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "Extension.h"
 #include <sstream>
 #include "Reference.h"
index 2682c14a1eaff5483818439eb69906e2b13c3f4a..b3d5c8bb1cb0b3bc8a7fca0a1c7a0619d700c104 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: importCmd.cpp,v 1.26 2002/05/31 04:03:06 cthuang Exp $
+// $Id: importCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "Extension.h"
 #include <sstream>
index 2a3dffd006e9660bff0f31a1ae107525dd0fbcaa..ac6fb14eaa2fb59ea210bcc3676c23b9c2e53a61 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: infoCmd.cpp,v 1.31 2002/04/13 03:53:57 cthuang Exp $
+// $Id: infoCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "Extension.h"
 #include "TclObject.h"
 #include "Reference.h"
index 160c5155ff4c89f0bf6a0f20dce3dfd0628a7c07..eff5738485fbf679ca1146f24c0a767977e55c46 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: main.cpp,v 1.70 2002/07/14 18:42:57 cthuang Exp $
+// $Id: main.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "ComModule.h"
 #include "Extension.h"
index 3ee1f721f0eebf988accc833582e3df06a9e8ca3..2e132a81e0c0631521514a053af61c03fe03b5dc 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: mutex.h,v 1.7 2002/04/13 03:53:57 cthuang Exp $
+// $Id: mutex.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef MUTEX_H
 #define MUTEX_H
 
index 8cc47b04b89c4db76b117e9aacf390b70768fd69..328390765b9d22cbd57ef28032751c4c0cc96642 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: naCmd.cpp,v 1.7 2003/03/07 00:17:30 cthuang Exp $
+// $Id: naCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "Extension.h"
 #include <string.h>
 
index 28e669e3fddc50226b998c55c500c1f71ef31e1c..d268a2098cee1d8c9a65a2e3668ec42be09eb24b 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: nullCmd.cpp,v 1.10 2003/03/07 00:17:30 cthuang Exp $
+// $Id: nullCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "Extension.h"
 #include <string.h>
 
index 5dc95603f81318e6755af9e1cde41c128b705633..ca4931478045dacaadd95b116c841de4185fe30c 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: objectCmd.cpp,v 1.31 2003/03/07 00:24:04 cthuang Exp $
+// $Id: objectCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "Extension.h"
 #include <sstream>
index eac808da2f2345ce7069caeeda8c6c2cf8989cc0..a21daeffbd4725b22fc277078ba3c47e9c8faaa0 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: refCmd.cpp,v 1.46 2003/11/06 15:29:01 cthuang Exp $
+// $Id: refCmd.cpp 16 2005-04-19 14:47:52Z cthuang $
 #pragma warning(disable: 4786)
 #include "Extension.h"
 #include <sstream>
@@ -10,6 +10,8 @@
 static int referenceObjCmd(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []);
 HandleSupport<Reference> Extension::referenceHandles(referenceObjCmd);
 
+static const char unknownErrorDescription[] = "Unknown error";
+
 // Check if the object implements ISupportErrorInfo.  If it does, get the
 // error information.  Return true if successful.
 
@@ -36,6 +38,59 @@ getErrorInfo (Reference *pReference, IErrorInfo **ppErrorInfo)
     return GetErrorInfo(0, ppErrorInfo) == S_OK;
 }
 
+// Get description text for an HRESULT.
+
+static Tcl_Obj *
+formatMessage (HRESULT hresult)
+{
+#if TCL_MINOR_VERSION >= 2
+    // Uses Unicode functions introduced in Tcl 8.2.
+    wchar_t *pMessage;
+    DWORD nLen = FormatMessageW(
+        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+        NULL,
+        hresult,
+        0,
+        reinterpret_cast<LPWSTR>(&pMessage),
+        0,
+        NULL);
+#else
+    char *pMessage;
+    DWORD nLen = FormatMessageA(
+        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+        NULL,
+        hresult,
+        0,
+        reinterpret_cast<LPSTR>(&pMessage),
+        0,
+        NULL);
+#endif
+
+    Tcl_Obj *pDescription;
+    if (nLen > 0) {
+        if (nLen > 1 && pMessage[nLen - 1] == '\n') {
+            --nLen;
+            if (nLen > 1 && pMessage[nLen - 1] == '\r') {
+                --nLen;
+            }
+        }
+        pMessage[nLen] = '\0';
+
+        
+#if TCL_MINOR_VERSION >= 2
+        // Uses Unicode functions introduced in Tcl 8.2.
+        pDescription = Tcl_NewUnicodeObj(pMessage, nLen);
+#else
+        pDescription = Tcl_NewStringObj(pMessage, nLen);
+#endif
+    } else {
+        pDescription = Tcl_NewStringObj(unknownErrorDescription, -1);
+    }
+    LocalFree(pMessage);
+
+    return pDescription;
+}
+
 // Set the Tcl errorCode variable and the Tcl interpreter result.
 // Returns TCL_ERROR.
 
@@ -43,7 +98,7 @@ static int
 setErrorCodeAndResult (
     Tcl_Interp *interp,
     HRESULT hresult,
-    const _bstr_t &description,
+    Tcl_Obj *pDescription,
     const char *file,
     int line)
 {
@@ -60,13 +115,8 @@ setErrorCodeAndResult (
     result.lappend(hrObj);
 
     // Append description.
-    const wchar_t *pWide = static_cast<const wchar_t *>(description);
-    if (pWide == 0) {
-        pWide = L"Unknown error";
-    }
-    TclObject descriptionObj(pWide);
-    errorCode.lappend(descriptionObj);
-    result.lappend(descriptionObj);
+    errorCode.lappend(pDescription);
+    result.lappend(pDescription);
 
 #ifndef NDEBUG
     // Append file and line number.
@@ -81,45 +131,29 @@ setErrorCodeAndResult (
     return TCL_ERROR;
 }
 
+static int
+setErrorCodeAndResult (
+    Tcl_Interp *interp,
+    HRESULT hresult,
+    const _bstr_t &description,
+    const char *file,
+    int line)
+{
+    TclObject descriptionObj;
+    int length;
+    Tcl_GetStringFromObj(descriptionObj, &length);
+    if (length == 0) {
+        descriptionObj = Tcl_NewStringObj(unknownErrorDescription, -1);
+    }
+    return setErrorCodeAndResult(interp, hresult, descriptionObj, file, line);
+}
+
 int
 Extension::setComErrorResult (
     Tcl_Interp *interp, _com_error &e, const char *file, int line)
 {
-    // Get description.
-    _bstr_t description;
-
-#if TCL_MINOR_VERSION >= 2
-    // Uses Unicode functions introduced in Tcl 8.2.
-    wchar_t *pMessage;
-    DWORD nLen = FormatMessageW(
-        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-        NULL,
-        e.Error(),
-        0,
-        reinterpret_cast<LPWSTR>(&pMessage),
-        0,
-        NULL);
-
-    if (nLen > 0) {
-        if (nLen > 1 && pMessage[nLen - 1] == '\n') {
-            --nLen;
-            if (nLen > 1 && pMessage[nLen - 1] == '\r') {
-                --nLen;
-            }
-        }
-        pMessage[nLen] = '\0';
-
-        description = _bstr_t(pMessage);
-    } else {
-        // FormatMessageW doesn't seem to work on Windows 95/98.
-        description = _bstr_t(e.ErrorMessage());
-    }
-    LocalFree(pMessage);
-#else
-    description = _bstr_t(e.ErrorMessage());
-#endif
-
-    return setErrorCodeAndResult(interp, e.Error(), description, file, line);
+    return setErrorCodeAndResult(
+        interp, e.Error(), formatMessage(e.Error()), file, line);
 }
 
 // Invoke a method or property.
@@ -135,7 +169,7 @@ invoke (Tcl_Interp *interp,
         WORD dispatchFlags)
 {
     // Set up return value.
-    _variant_t returnValue;
+    NativeValue returnValue;
     VARIANT *pReturnValue = (pMethod->type().vartype() == VT_VOID)
         ? 0 : &returnValue;
 
@@ -286,7 +320,7 @@ invokeWithoutInterfaceDesc (
     }
 
     // Set up return value.
-    _variant_t varReturnValue;
+    NativeValue varReturnValue;
     VARIANT *pReturnValue =
         (dispatchFlags & DISPATCH_PROPERTYPUT) ? 0 : &varReturnValue;
 
@@ -339,10 +373,10 @@ referenceObjCmd (
     int i = 1;
     for (; i < objc; ++i) {
         static char *options[] = {
-           "-get", "-method", "-namedarg", "-set", NULL
+           "-call", "-get", "-method", "-namedarg", "-set", NULL
         };
         enum OptionEnum {
-            OPTION_GET, OPTION_METHOD, OPTION_NAMEDARG, OPTION_SET
+            OPTION_CALL, OPTION_GET, OPTION_METHOD, OPTION_NAMEDARG, OPTION_SET
         };
 
         int index;
@@ -352,12 +386,13 @@ referenceObjCmd (
         }
 
         switch (index) {
-        case OPTION_GET:
-            dispatchFlags = DISPATCH_PROPERTYGET;
-            break;
+        case OPTION_CALL:
         case OPTION_METHOD:
             dispatchFlags = DISPATCH_METHOD;
             break;
+        case OPTION_GET:
+            dispatchFlags = DISPATCH_PROPERTYGET;
+            break;
         case OPTION_NAMEDARG:
             namedArgOpt = true;
             break;
@@ -460,6 +495,18 @@ referenceObjCmd (
         result = setErrorCodeAndResult(
             interp, e.scode(), e.description(), __FILE__, __LINE__);
     }
+    catch (InvokeException &e) {
+        std::ostringstream argOut;
+        argOut << "Argument " << e.argIndex() << ": ";
+        TclObject descriptionObj(argOut.str());
+
+        TclObject messageObj(formatMessage(e.hresult()));
+        Tcl_AppendObjToObj(descriptionObj, messageObj);
+
+        result = setErrorCodeAndResult(
+            interp, e.hresult(), descriptionObj, __FILE__, __LINE__);
+    }
+
     return result;
 }
 
index a885e227ffa8b35ce172dac2e3559cd11b595c8c..f0e5fe8f236a89885df00c73de76eb2188e2199c 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: shortPathNameCmd.cpp,v 1.3 2002/04/13 03:53:57 cthuang Exp $
+// $Id: shortPathNameCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "Extension.h"
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
index 4c89f3c6d2f8ea1284ca62ae97728e41bbd0b727..3bac0cbd50040dbe925826c5f526c0bc49132182 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: tclRunTime.h,v 1.1 2002/07/15 04:03:54 cthuang Exp $
+// $Id: tclRunTime.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef TCLRUNTIME_H
 #define TCLRUNTIME_H
 
index b05665d1204a62f06a8a7140d323d8a94a4ddfc7..e7cc1eee4d2b6b430444474c1819d3fc4b935b33 100644 (file)
@@ -45,7 +45,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "\tcl\include" /D "NDEBUG" /D "_WIN32_DCOM" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "\tcl\include" /D "NDEBUG" /D "_WIN32_DCOM" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "TCOM_VTBL_SERVER" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -71,7 +71,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "\tcl\include" /D "_DEBUG" /D "_WIN32_DCOM" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "\tcl\include" /D "_DEBUG" /D "_WIN32_DCOM" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "TCOM_VTBL_SERVER" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /GZ /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -98,7 +98,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "e:\tcl\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "_WIN32_DCOM" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "\tcl\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "\tcl\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "TCOM_VTBL_SERVER" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -125,7 +125,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "c:\tcl\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "_WIN32_DCOM" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "\tcl\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "\tcl\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCOM_EXPORTS" /D "TCOM_VTBL_SERVER" /D "TCL_THREADS" /D "USE_TCL_STUBS" /D "USE_NON_CONST" /YX /FD /GZ /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -174,6 +174,14 @@ SOURCE=.\configureCmd.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\DispatchAdapter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DispatchImpl.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\Extension.cpp
 # End Source File
 # Begin Source File
@@ -210,6 +218,10 @@ SOURCE=.\naCmd.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\NativeValue.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\nullCmd.cpp
 # End Source File
 # Begin Source File
@@ -286,6 +298,14 @@ SOURCE=.\ComObjectFactory.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\DispatchAdapter.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DispatchImpl.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\Extension.h
 # End Source File
 # Begin Source File
@@ -306,6 +326,10 @@ SOURCE=.\mutex.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\NativeValue.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\Reference.h
 # End Source File
 # Begin Source File
index 1cdd22030e4852e249236db3cd83c7e87513b2eb..9f00bec9ac3f09d6ff5bd5b740d7f4a215b42a77 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: tcomApi.h,v 1.1 2000/04/22 21:39:36 chuang Exp $
+// $Id: tcomApi.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef TCOMAPI_H
 #define TCOMAPI_H
 
index 12e742bf2609cab41cb930cc25d152e11ff873b7..9480528810a0ca9ecf39c919e9c852cc22e0b2dc 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: tcomVersion.rc,v 1.5 2002/04/27 18:15:24 cthuang Exp $
+// $Id: tcomVersion.rc 5 2005-02-16 14:57:24Z cthuang $
 #include <winres.h>
 #include "version.h"
 #include "buildNumber.h"
index b5da9662c80fc90c2c9982ea38eb0028873cd0f3..58d00e0a60b3095ad3c2291f37cfb3a4333f3cc5 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: typelibCmd.cpp,v 1.29 2002/04/13 03:53:57 cthuang Exp $
+// $Id: typelibCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #pragma warning(disable: 4786)
 #include "Extension.h"
 #include "TypeLib.h"
index 51e521494169cc661a65ea943fa8479f00cf210f..cbad50e03e58eeb516f4f56bfeebbfd9a7eb2bbf 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: variantCmd.cpp,v 1.1 2003/05/29 03:33:08 cthuang Exp $
+// $Id: variantCmd.cpp 5 2005-02-16 14:57:24Z cthuang $
 #include "Extension.h"
 #include <string.h>
 
index 5e9876031f973dcad178f4bd16b3db0dd1778c15..361a705f0c7f4685bd8761b826eace841fa034a2 100644 (file)
@@ -1,9 +1,9 @@
-// $Id: version.h,v 1.4 2002/10/01 21:51:32 cthuang Exp $
+// $Id: version.h 5 2005-02-16 14:57:24Z cthuang $
 #ifndef VERSION_H
 #define VERSION_H
 
 #define PACKAGE_MAJOR_VERSION 3
-#define PACKAGE_MINOR_VERSION 9
+#define PACKAGE_MINOR_VERSION 10
 
 #define MAKE_VERSION_STRING0(MAJOR,MINOR) #MAJOR "." #MINOR
 #define MAKE_VERSION_STRING(MAJOR,MINOR) MAKE_VERSION_STRING0(MAJOR,MINOR)
index b2d4f9ed008642ae8f1efc1a498bc6c881f16422..c25e0c3611daab43d41366e5864a7d04d80d169e 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: all.tcl,v 1.1 2002/03/16 04:53:17 cthuang Exp $
+# $Id: all.tcl 5 2005-02-16 14:57:24Z cthuang $
 #
 # This file contains a top-level script to run all of the tests.
 
index 8a8f49b2168a0e6a4cf3f61f3fd705469a494b24..d0f5c50ba8682ef6791509e33e4bdcd0d8e958f6 100644 (file)
@@ -1,6 +1,6 @@
-# $Id: array.test,v 1.1 2003/05/12 23:31:03 cthuang Exp $
+# $Id: array.test 5 2005-02-16 14:57:24Z cthuang $
 #
-# This file contains tests for the passing arrays
+# This file contains tests for passing arrays.
 
 if {[lsearch [namespace children] ::tcltest] == -1} {
     package require tcltest
index e55972b6a162d44517aa83550ff22c4020cb2a08..c2ed8f87346683917b97e5515c01fc1e3af1a1de 100644 (file)
@@ -1,6 +1,6 @@
-# $Id: eval.test,v 1.2 2003/04/02 22:57:35 cthuang Exp $
+# $Id: eval.test 5 2005-02-16 14:57:24Z cthuang $
 #
-# This file contains tests the robustness of handles under eval.
+# This file tests the robustness of handles under eval.
 
 if {[lsearch [namespace children] ::tcltest] == -1} {
     package require tcltest
index f2935bf19b37ef4505fddbf1701f29a548d590b6..6791a78d09549772da39ae7855f89f6d38819df6 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: foreach.test,v 1.2 2003/03/07 00:01:40 cthuang Exp $
+# $Id: foreach.test 5 2005-02-16 14:57:24Z cthuang $
 #
 # This file contains tests for the ::tcom::foreach command.
 
index 21f718fcdd9a19f0786d496a07e7d4630dbea8a7..e3fa96f39885dd6fabf64862b0e833ed84d4f5a7 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: namedarg.test,v 1.2 2003/04/02 22:57:35 cthuang Exp $
+# $Id: namedarg.test 5 2005-02-16 14:57:24Z cthuang $
 #
 # This file contains tests invoking methods through IDispatch with named
 # arguments.
index bf28e22dd9514e50044205e5513e2b630c9e76ae..2b43a8ee6847e4fe2e6ce341c55b58f62f535767 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: ref.test,v 1.2 2002/06/29 15:44:21 cthuang Exp $
+# $Id: ref.test 13 2005-04-18 12:24:14Z cthuang $
 #
 # This file contains tests for the ::tcom::ref command.
 
@@ -34,7 +34,9 @@ test createobject-1.2 {::tcom::ref createobject, Banking example server} {
     package require tcom
 
     set bank [::tcom::ref createobject "Banking.Bank"]
+#    set bank [::tcom::ref querydispatch $bank]
     set account [$bank CreateAccount]
+#    set account [::tcom::ref querydispatch $account]
     $account Deposit 30
     $account Withdraw 20
     $account Balance