From: gelonida on
Hi,

I'd like to register an event in order to be informed, whenever a
Windows WIA device is connected or disconnected.

In python I can use WIA devices, but I don't know how to register
events

I have existing C# code, which works and looks like.

class MgrHandlerClass
{
public void devManager_OnEvent(string eventID, string
deviceID, string itemID)
{ } // her emy handler code

public void addhandler(DeviceManager manager)
{
Console.WriteLine("adding handler!");
manager.OnEvent += new
WIA._IDeviceManagerEvents_OnEventEventHandler(
devManager_OnEvent);
}

static void Main(string[] args)
{

MgrHandlerClass mgrhndlr;
mgrhndlr = new MgrClass();
DeviceManager manager;

manager = new DeviceManagerClass();

manager.RegisterEvent(WIA.EventID.wiaEventDeviceConnected, "*");

manager.RegisterEvent(WIA.EventID.wiaEventDeviceDisconnected, "*");
mgrhndlr.addhandler(manager);
// wait for callbacks or do other stuff
}


Now in python I'm stuck

import win32com.client
import wia_defs # created with makepy.py
manager = win32com.client.Dispatch("WIA.DeviceManager")
mgrhndlr = MgrClass()
manager.RegisterEvent(EventID=constants.wiaEventDeviceConnected,DeviceID=u'*')
manager.RegisterEvent(EventID=constants.wiaEventDeviceDisconnected,DeviceID=u'*')
mgrhndlr.addhandler(manager)


class MgrHandlerClass:
def OnEvent(self, EventID=defaultNamedNotOptArg,
DeviceID=defaultNamedNotOptArg, ItemID=defaultNamedNotOptArg):
print "Called back with (%s) (%s) (%s)" %
(EventID,DeviceID,ItemID)

def addhandler(self,manager):
# here I'm stuck :-(
# the following line doesn't work as it seems, that manager
does not have attr
# onevent

manager.OnEvent.append( WIA._IDeviceManagerEvents_OnEventEventHandler(self.OnEvent) )



The autogenerated file contains:
class IDeviceManager(DispatchBaseClass):
CLSID = IID('{73856D9A-2720-487A-A584-21D5774E9D0F}')
coclass_clsid = IID('{E1C5D730-7E97-4D8A-9E42-BBAE87C2059F}')

def RegisterEvent(self, EventID=defaultNamedNotOptArg,
DeviceID=u'*'):
"""Registers the specified EventID for the specified DeviceID. If
DeviceID is "*" then OnEvent will be called whenever the event
specified occurs for any device. Otherwise, OnEvent will only be
called if the event specified occurs on the device specified."""
return self._ApplyTypes_(2, 1, (24, 32), ((8, 1), (8, 49)),
u'RegisterEvent', None,EventID
, DeviceID)



but I do not know where to place (how to create the function)
OnEvent()


Any help would be appreciated.
From: Mark Hammond on
On 16/04/2010 7:15 AM, gelonida wrote:
> Hi,
>
> I'd like to register an event in order to be informed, whenever a
> Windows WIA device is connected or disconnected.
>
> In python I can use WIA devices, but I don't know how to register
> events
>
> I have existing C# code, which works and looks like.
>
> class MgrHandlerClass
> {
> public void devManager_OnEvent(string eventID, string
> deviceID, string itemID)
> { } // her emy handler code
>
> public void addhandler(DeviceManager manager)
> {
> Console.WriteLine("adding handler!");
> manager.OnEvent += new
> WIA._IDeviceManagerEvents_OnEventEventHandler(
> devManager_OnEvent);
> }
>
> static void Main(string[] args)
> {
>
> MgrHandlerClass mgrhndlr;
> mgrhndlr = new MgrClass();
> DeviceManager manager;
>
> manager = new DeviceManagerClass();
>
> manager.RegisterEvent(WIA.EventID.wiaEventDeviceConnected, "*");
>
> manager.RegisterEvent(WIA.EventID.wiaEventDeviceDisconnected, "*");
> mgrhndlr.addhandler(manager);
> // wait for callbacks or do other stuff
> }
>
>
> Now in python I'm stuck
>
> import win32com.client
> import wia_defs # created with makepy.py
> manager = win32com.client.Dispatch("WIA.DeviceManager")
> mgrhndlr = MgrClass()
> manager.RegisterEvent(EventID=constants.wiaEventDeviceConnected,DeviceID=u'*')
> manager.RegisterEvent(EventID=constants.wiaEventDeviceDisconnected,DeviceID=u'*')
> mgrhndlr.addhandler(manager)
>
>
> class MgrHandlerClass:
> def OnEvent(self, EventID=defaultNamedNotOptArg,
> DeviceID=defaultNamedNotOptArg, ItemID=defaultNamedNotOptArg):
> print "Called back with (%s) (%s) (%s)" %
> (EventID,DeviceID,ItemID)
>
> def addhandler(self,manager):
> # here I'm stuck :-(
> # the following line doesn't work as it seems, that manager
> does not have attr
> # onevent
>
> manager.OnEvent.append( WIA._IDeviceManagerEvents_OnEventEventHandler(self.OnEvent) )

The model used by pywin32 is more "low level" than that exposed by some
of the MS languages. You probably need something closer to:


class MgrHandlerClass:
def OnEvent(self, EventID=defaultNamedNotOptArg, ...):
print "Called back with ..."


manager = win32com.client.DispatchWithEvents("WIA.DeviceManager",
MgrHandlerClass)
manager.RegisterEvent(EventID=constants.wiaEventDeviceConnected,DeviceID=u'*')
manager.RegisterEvent(EventID=constants.wiaEventDeviceDisconnected,DeviceID=u'*')

And magically your OnEvent should be called when the event happens.
Googling for 'DispatchWithEvents' might find some good hits for more
information.

HTH,

Mark
From: gelonida on
Hi Mark,

On Apr 16, 3:16 am, Mark Hammond <skippy.hamm...(a)gmail.com> wrote:
> On 16/04/2010 7:15 AM,gelonidawrote:
>
> The model used by pywin32 is more "low level" than that exposed by some
> of the MS languages.  You probably need something closer to:
>
>   class MgrHandlerClass:
>        def OnEvent(self, EventID=defaultNamedNotOptArg, ...):
>            print "Called back with ..."
>
> manager = win32com.client.DispatchWithEvents("WIA.DeviceManager",
> MgrHandlerClass)
> manager.RegisterEvent(EventID=constants.wiaEventDeviceConnected,DeviceID=u'*')
> manager.RegisterEvent(EventID=constants.wiaEventDeviceDisconnected,DeviceID=u'*')
>
> And magically your OnEvent should be called when the event happens.
> Googling for 'DispatchWithEvents' might find some good hits for more
> information.
>

I'm still stuck. Please look at following code snippet.
I tried to reduce it to the absolute minimum.
running under WinXP and python 2.6.4


import win32com.client,pythoncom,time

defaultNamedNotOptArg=pythoncom.Empty
wiaEventDeviceConnected =u'{A28BBADE-64B6-11D2-
A231-00C04FA31809}' # from enum EventID

class MgrHandlerClass: # doesn't work either
def OnEvent(self, EventID=defaultNamedNotOptArg,
DeviceID=defaultNamedNotOptArg, ItemID=defaultNamedNotOptArg):
print "Called back with ..."

manager = win32com.client.DispatchWithEvents("WIA.DeviceManager",
MgrHandlerClass)
manager.RegisterEvent(EventID=wiaEventDeviceConnected,DeviceID=u'*')

while True:
print "sleep"
time.sleep(10)

When I plug / unplug a USB WIA device nothing shows up.
My C# implementation prints messages on wiaEventDeviceConnected /
wiaEventDeviceDisconnected events if I register them.

What am I missing?

Should MgrHandlerClass inherit from some kind of default class?


From: Roger Upole on
gelonida wrote:
....
> while True:
> print "sleep"
> time.sleep(10)
>
>When I plug / unplug a USB WIA device nothing shows up.
> My C# implementation prints messages on wiaEventDeviceConnected /
> wiaEventDeviceDisconnected events if I register them.
>
> What am I missing?

You need to be processing messages to receive COM events.
Try replacing your sleep loop with pythoncom.PumpMessages().

Roger




From: News123 on
Hi Roger,

Roger Upole wrote:
> gelonida wrote:
> ...
>> while True:
>> print "sleep"
>> time.sleep(10)
>>
>> When I plug / unplug a USB WIA device nothing shows up.
>> My C# implementation prints messages on wiaEventDeviceConnected /
>> wiaEventDeviceDisconnected events if I register them.
>>
>> What am I missing?
>
> You need to be processing messages to receive COM events.
> Try replacing your sleep loop with pythoncom.PumpMessages().
>

Thanks a lot

Indeed the only thing missing was a call to pythoncom.PumpMessages()

I fell over another tiny detail though, as I wanted to keep my main
application running ( the place holder was my sleep loop)

Tt seems, that PumpMessages() cannot be in another thread.


So I ended up with:

import win32com.client,pythoncom,time,threading

defaultNamedNotOptArg=pythoncom.Empty
wiaEventDeviceConnected =u'{A28BBADE-64B6-11D2-A231-00C04FA31809}'

class MgrHandlerClass:
def OnEvent(self, EventID=defaultNamedNotOptArg,
DeviceID=defaultNamedNotOptArg,
ItemID=defaultNamedNotOptArg):
print "Called back with ..."


mgrhndlr = MgrHandlerClass()
manager = win32com.client.DispatchWithEvents("WIA.DeviceManager",
MgrHandlerClass)
manager.RegisterEvent(EventID=wiaEventDeviceConnected,DeviceID=u'*')

def sleeploop():
while True:
print "sleep"
time.sleep(10)

thrd = threading.Thread(target=sleeploop)
thrd.start()
# doesn't work if pump is in another thread
pythoncom.PumpMessages()


bye



N