Python, COM & Windows

J

jahurt

I've written a COM server in Python for use with a VB app. So far
things work very well... I'm able to call all my Python functions from
VB with no problems. However, now I need to notify the VB client when
data is available in the server. I've been trying to implement a
callback function in the server, but I haven't had any luck. My needs
here are modest; I only need some sort of asyncronous notification of
VB from my Python COM server... is there easy way to do this?

I'm only moderately familiar with either language... Python is growing
on me :) I can't say the same for VB. TIA
 
D

drs

I've written a COM server in Python for use with a VB app. So far
things work very well... I'm able to call all my Python functions from
VB with no problems. However, now I need to notify the VB client when
data is available in the server. I've been trying to implement a
callback function in the server, but I haven't had any luck. My needs
here are modest; I only need some sort of asyncronous notification of
VB from my Python COM server... is there easy way to do this?

No doubt there are better ways to do this, but you can pass a VB control to
python which can then control it. For instance, imagine you have a
progressBar called PB in VB and a (untested -- i think i typed this
correctly) python function called foo as follows.

def foo(self, PB):
PB = win32com.client.Dispatch(PB)
PB.Max = 9
PB.Visible = 1
for i in range(10):
PB.Value = i

So long as you are using COM (and not DCOM) Python will control your
control.

-d
 
P

Peter Maas

drs said:
def foo(self, PB):
PB = win32com.client.Dispatch(PB)

That's looking strange. AFAIK Dispatch() is passed a string with
the class name (e.g. ADO.Recordset) and returns an instance. In
your example foo() would then be passed a class string PB for the
progressbar control and overwrite it with the instance PB. But
how gets the server to know the instance of the client's
progressbar?

Perhaps this works:

- COM server with method queryHandle(nHandle) which is called
by the client to transmit a notification handle to the server.

- The server can then send messages to nHandle with
win32gui.SendMessage().

Mit freundlichen Gruessen,

Peter Maas
 
U

U-CDK_CHARLES\\Charles

I've written a COM server in Python for use with a VB app. So far
things work very well... I'm able to call all my Python functions from
VB with no problems. However, now I need to notify the VB client when
data is available in the server. I've been trying to implement a
callback function in the server, but I haven't had any luck. My needs
here are modest; I only need some sort of asyncronous notification of
VB from my Python COM server... is there easy way to do this?

I'm only moderately familiar with either language... Python is growing
on me :) I can't say the same for VB. TIA

Yes, I can name at least one other person who's doing exactly what
you're doing, and has the same opinion as to the the merits of the
languages. :)

What you're after is called an "Observer" pattern in OO circles, albeit
a degenerate one.

What you need to do is have the VB side create a Notify service. Then
on the Python side, you keep track of every COM service that needs to be
Notified of a change in state. In your case, just one, but you could
just as easily have a list of process call backs.

The key is going to be creating the service on the VB side.

If that's too heavy, you could use a socket connection between the
processes. You can set the socket to be nonblocking (at least with a
win32api call) and have the socket handler tickle a command button or
something when it's fifo is full.
 
J

jahurt

drs said:
No doubt there are better ways to do this, but you can pass a VB control to
python which can then control it. For instance, imagine you have a
progressBar called PB in VB and a (untested -- i think i typed this
correctly) python function called foo as follows.

def foo(self, PB):
PB = win32com.client.Dispatch(PB)
PB.Max = 9
PB.Visible = 1
for i in range(10):
PB.Value = i

So long as you are using COM (and not DCOM) Python will control your
control.

-d

Thank you for the reply :) This looks like what I've been trying to
do, but I'm unclear on how to pass a VB object to Python.

I've been looking at "Python Programming on WIn32" by Mark Hammond and
Andy Robinson. In their example, they pass a form to to a Python
function using a "Me" keyword, which I assume is similar to Python's
"self" and C++'s "this". I've tried doing this on program
initialization with something like...

Private Sub Form_Load()
Set pymodule = CreateObject("PythonCOM.testprog")
pymodule.init_callback Me
End Sub

....and a corresponding Python function...

def init_callback(self, vbForm):
self.vbForm = win32com.client.Dispatch(vbForm)

The code starts with no errors or warnings. However, the program
crashes when my Python module tries to access "self.vbForm".

I have a feeling I'm making this more difficult than necessary. Any
help or suggestions are greatly appreciated... TIA
 
M

Markus Wankus

Thank you for the reply :) This looks like what I've been trying to
do, but I'm unclear on how to pass a VB object to Python.

I've been looking at "Python Programming on WIn32" by Mark Hammond and
Andy Robinson. In their example, they pass a form to to a Python
function using a "Me" keyword, which I assume is similar to Python's
"self" and C++'s "this". I've tried doing this on program
initialization with something like...

Private Sub Form_Load()
Set pymodule = CreateObject("PythonCOM.testprog")
pymodule.init_callback Me
End Sub

...and a corresponding Python function...

def init_callback(self, vbForm):
self.vbForm = win32com.client.Dispatch(vbForm)

The code starts with no errors or warnings. However, the program
crashes when my Python module tries to access "self.vbForm".

I have a feeling I'm making this more difficult than necessary. Any
help or suggestions are greatly appreciated... TIA

Hmm...this looks correct - what does the rest of the code look like?
What are you doing with self.vbForm - and what does the VB code look like?

Markus.
 
J

jahurt

Markus Wankus said:
Hmm...this looks correct - what does the rest of the code look like?
What are you doing with self.vbForm - and what does the VB code look like?

Markus.

Ok, it works now... the same code that didn't work the day before
works now, and I have no idea why. I suspect that I needed a hard
reboot and coming from the Unix/Linux world this never occurred to me.
Does this make any sense, or do I have a gremlin in my computer?

Now I'm dealing with a minor problem that I hope someone can help me
with. Without going into too much detail, my COM object wraps another
python class that writes to a file. I'm using standard C-style I/O
functions to do this... open(), write() and close(). Running these on
the console (in IDLE, actually) these work fine. As an attribute of
the COM object, is doesn't work.

I understand that I can use win32 api calls to write to a file, but I
haven't tried this yet. Is there an easier solution? Thanks everyone
:)
 
D

drs

Markus Wankus <[email protected]> wrote in message

* * *
Ok, it works now... the same code that didn't work the day before
works now, and I have no idea why. I suspect that I needed a hard
reboot and coming from the Unix/Linux world this never occurred to me.
Does this make any sense, or do I have a gremlin in my computer?

Now I'm dealing with a minor problem that I hope someone can help me
with. Without going into too much detail, my COM object wraps another
python class that writes to a file. I'm using standard C-style I/O
functions to do this... open(), write() and close(). Running these on
the console (in IDLE, actually) these work fine. As an attribute of
the COM object, is doesn't work.

Something to watch out for is that the VB IDE (VB^ at any rate) caches
python objects, so once one is loaded by a program running in the IDE,
before a change to the python object will be detected, you must restart the
VB IDE. This is a major pain, but I don't know of any way around it. I
mention this as it sounds like what you ran in to above.

-d
 
S

Somesh Bartakkay

i wanna deploy my com server to non-python m/c,
plz let me know how to write simple script with py2exe ?
 
U

U-CDK_CHARLES\\Charles

i wanna deploy my com server to non-python m/c,
plz let me know how to write simple script with py2exe ?

Take a look at Python Win32 Programming. It has an example you can call
from any VBA program. You can DL the examples, but I'd recommend the
book.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,184
Messages
2,570,978
Members
47,561
Latest member
gjsign

Latest Threads

Top