visual basic -> win32com server problem

Mark Hammond mhammond at skippinet.com.au
Wed Feb 5 23:52:21 CET 2003


Giles Brown wrote:
> I am trying to create an application object model in Python that
> I can use from a Visual Basic application via COM.
> 
> I am aiming to create a parent object that exposes a collection
> property and have the collection property have a default value that 
> allows indexing of an item in the collection (in the normal VB 
> collection idiom).
> 
> So the VB code might look like so:
> 
> Dim App As Object
> Dim Station As Object
> 
> Set App = CreateObject("MyApp.Application")
> Set Station = App.Stations("MyStation")
> 
> And a short version of the Python code would be:
> 
> class Stations:
> 
>     _public_methods_ = ['Item', 'Count', 'Add', 'Remove']
> 
>     # Method definitions here
> 
>     def Item(self, *args):
>         return wrapped whatever here
> 
>     # Make Item default value a la win32com.server.util.Collection
>     _value_ = Item
>     
> 
> class Application:
> 
>     # Registration stuff here
>     _public_attrs_ = ['Stations']
> 
>     def __init__(self):
>         self.Stations = win32com.server.util.wrap(Stations())
> 
> Looking at the debug trace, what happens is rather than VB invoking the
> "Stations" property on the App object then invoking the default on the
> Stations object, it invokes the Stations property on the App object with
> "MyStation" as a argument (which is ignored by the dispatcher) so the
> Stations.Item method never gets called.
> 
> My question is (sorry for the slow buildup ;-) is the behaviour of win32com
> and Visual Basic correct and I just need to implement my object model
> differently or is there something going on in VB or win32com that is
> causing this not to work and if so what?

The underlying problem is that you are exposing a property as a method, 
and Python doesn't support this syntactically. ie,

item.foo(1) = 2

is invalid syntax.  Hence making use of these default properties *from* 
Python is difficult.  However, you are coming from the opposite angle, 
so the above can be ignored ;)

If you have a later win32all, then you *can* support this.  Your class 
should loook like:

class Stations:
      _public_methods_ = ['Item', 'Count', 'Add', 'Remove']
      # Method definitions here
      def Item(self, *args): # The 'getter'
         return wrapped whatever here
      def SetItem(self, *args):
         set whatever here.
      # Make Item default value a la win32com.server.util.Collection
      _value_ = Item
      Set_value_ = SetItem

win32com has special support for a "Set" prefix added to property names 
to work as the property setter.  A "side effect" of the implementation 
is that the "name" for the default value is "_value_" - hence 
"Set_value_" can be used as the setter for this property.

Ensure you have the latest win32all, and mail me if it doesn't work - I 
will then go and add something similar to our test suite and see what is 
broken.

Mark.





More information about the Python-list mailing list