To those who have shown interest in this: I'll publish a How-To when I
reach a reasonable solution.

Now, reading some other examples included with ActivePython, I realized
the COM wrapper class generated by makepy is just a mixin. So I tried
this other approach, inspired by the
\Python21\Pythonwin\pywin\Demos\ocx\webbrowser.py example included in
the distribution:

-- LISTING 3 ---------------
from win32com.client import gencache, constants
SpiritModule =
gencache.EnsureModule('{D6CD40C0-A522-11D0-9800-D3C9B35D2C47}', 0, 1, 0)

from pywin.mfc import activex

class Rcx(activex.Control, SpiritModule.Spirit):
        def OnDownloadDone(self, ErrorCode=None, DownloadNo=None):
                print 'OnDownloadDone: %s, %s' % (ErrorCode, DownloadNo)

def test():
        rcx = Rcx()
        print rcx
        print rcx._obj_
        rcx.ComPortNo = constants.COM2
        rcx.LinkType = constants.InfraRed
        rcx.PBrick = constants.RCX
        print rcx.InitComm()
        print rcx.CloseComm()

if __name__ == '__main__':
        test()
----------------------------

Now I get this traceback:

Traceback (most recent call last):
  File "rcx_mod.py", line 22, in ?
    test()
  File "rcx_mod.py", line 18, in test
    print rcx.InitComm()
  File "c:\python21\pythonwin\pywin\mfc\activex.py", line 38, in
__getattr__
    return window.Wnd.__getattr__(self, attr)
  File "c:\python21\pythonwin\pywin\mfc\object.py", line 23, in
__getattr__
    raise win32ui.error, "The MFC object has died."
win32ui: The MFC object has died.

I noticed that the object instantiated by rcx = Rcx() is early-bound, so
one of the problems I had before is solved (the control identifies
itself as <win32com.gen_py.LEGO PBrickControl, OLE Control module.Rcx>,
and I can use the COM constants). 

I also noticed when I print rcx.__obj__ that the result is None. As far
as I understand, the __obj__ attr should point to the COM counterpart of
my Python class, so it being None must be bad. 

The Activex examples provided with ActivePython assume that the OCX is
attached to a window. But in this case this would be useless, since I
have already been able to operate the RCX through Spirit.OCX without any
GUI. All I need is a way to subclass the Spirit class to implement event
handlers.

Any ideas would be greatly appreciated!

Best regards,

Luciano


Luciano Ramalho wrote:
> 
> I've been experimenting with the win32com extensions to control an RCX
> programmable brick using the Spirit.OCX provided by LEGO. My first
> attempts have been succesful: I've been able to command the RCX quite
> easily by calling the functions prototyped in the module generated by
> makepy.
> 
> However, I've had two problems:
> 
> 1. EARLY BINDING: NO GO
> 
> I've been unable to early-bind the COM object for Spirit.OCX. When I run
> the code below, communications with the RCX work, and the file
> D6CD40C0-A522-11D0-9800-D3C9B35D2C47x0x1x0.py is generated at
> C:\Python21\win32com\gen_py as expected, but the string representation
> of the rcx object (line 7 below) is <COMObject SPIRIT.SpiritCtrl.1>
> instead of someting like <win32com.gen_py.???> as shown on page 205 of
> Mark Hammond's Python Programming on Win32 and on the "Quick Start to
> Client side COM and Python" online help page. One consequence of this is
> that I cannot use the COM enum constants generated by makepy.
> 
> -- LISTING 1 ---------------
> # next 2 lines generated by makepy.py -i ([Hammond], p.204)
> from win32com.client import gencache
> gencache.EnsureModule('{D6CD40C0-A522-11D0-9800-D3C9B35D2C47}', 0, 1, 0)
> 
> import win32com.client
> rcx = win32com.client.Dispatch('SPIRIT.SpiritCtrl.1')
> print repr(rcx)
> print rcx.__class__
> 
> rcx.ComPortNo = 2   #COM2
> rcx.LinkType = 0    #INFRARED
> rcx.PBrick = 1      #RCX
> 
> print 'InitComm:', rcx.InitComm()
> 
> print 'TowerAndCableConnected:', rcx.TowerAndCableConnected()
> print 'PBAliveOrNot:', rcx.PBAliveOrNot()
> 
> print 'CloseComm:', rcx.CloseComm()
> ----------------------------
> 
> 2. HOW TO SUBCLASS A COM CLASS?
> 
> I need to handle some events generated by the OCX. The auto-generated
> D6CD40C0... module contains commented-out prototypes for functions like
> this:
> 
> #       def OnDownloadDone(self, ErrorCode=defaultNamedNotOptArg,
> DownloadNo=defaultNamedNotOptArg):
> 
> Now, I don't know where to define those functions im my code. I suppose
> I should not edit the D6CD40C0... module, since it is auto-generated. I
> would like to create a subclass of the OCX class, but I don't know how,
> since the __class__ of the rcx object returned by
> win32com.client.Dispatch('SPIRIT.SpiritCtrl.1') is
> win32com.client.CDispatch.
> 
> I also tried to use the GetClassForProgID function of the
> win32com.client.gencache module, which gave me a class described as:
> <class win32com.gen_py.D6CD40C0-A522-11D0-9800-D3C9B35D2C.Spirit at
> 0081811C>. This looked promising. But trying to create an instance of
> that class generated the following traceback:
> 
> Traceback (most recent call last):
>   File "spirit_test_class.py", line 10, in ?
>     rcx = MySpirit()
>   File
> "c:\python21\win32com\gen_py\D6CD40C0-A522-11D0-9800-D3C9B35D2C47x0x1x0.py",
> line 407, in __init__
>     self.__dict__["_dispobj_"] = self.default_interface(oobj)
> TypeError: object is not callable:
> '{D6CD40C1-A522-11D0-9800-D3C9B35D2C47}'
> 
> Here is the code I used in this attempt:
> 
> -- LISTING 2 ---------------
> from win32com.client import gencache
> SpiritClass = gencache.GetClassForProgID('SPIRIT.SpiritCtrl.1')
> 
> print repr(SpiritClass)
> 
> class MySpirit(SpiritClass):
>     def OnDownloadDone(self, ErrorCode=None, DownloadNo=None):
>         print 'ErrorCode: %s; DownloadNo: %s' % (ErrorCode, DownloadNo)
> 
> rcx = MySpirit()
> ----------------------------
> 
> Best regards,
> 
> Luciano
> _______________________________________________
> ActivePython mailing list
> [EMAIL PROTECTED]
> http://listserv.ActiveState.com/mailman/listinfo/activepython
_______________________________________________
ActivePython mailing list
[EMAIL PROTECTED]
http://listserv.ActiveState.com/mailman/listinfo/activepython

Reply via email to