Thanks.  I actually found out the problem was enabling the events within the 
proprietary COM object, so once I did that everything is working.  Thanks for 
your help!



________________________________
 From: Mark Hammond <skippy.hamm...@gmail.com>
To: Darren McElfresh <dmcelfr...@yahoo.com> 
Cc: "python-win32@python.org" <python-win32@python.org> 
Sent: Sunday, March 4, 2012 10:18 PM
Subject: Re: [python-win32] Help Needed on Handling Events from a Proprietary 
COM Object
 
Sorry for the delay - I'm afraid there isn't anything obvious I can see. 
  However, note that all the IConnection* interfaces are fully exposed 
in Python - so it should be able to avoid the "WithEvents" type helpers 
and "port" the code below directly - ie, manually doing the QI for the 
IConnect* interfaces, etc.  You might find win32com/client/connect.py 
and win32com/demos/connect.py useful as these do the low-level 
connection-point wrangling so may either be useful directly or as a 
guide to using them from Python.

Cheers,

Mark.

On 1/03/2012 1:01 AM, Darren McElfresh wrote:
> Thanks for your help on this!
>
> I expect an "event" to make a callback on my event handler.
>
> I updated my code to not utilize getevents, since I'm using
> DispatchWithEvents, and removed my call to MsgWaitForMultipleObjects and
> updated the call to PumpWaitingMessages in a loop, to just be
> PumpMessages; however it still doesn't seem to work.
>
> So at this point I basically have:
> class Events():
> def OnChange(self, e=defaultNamedNotOptArg):
> ....
> ....
> event_source = view.newItemEventSource(
> server.typeForName(server.TypeNames.CHANGEREQUEST) )
> event_monitor = win32com.client.DispatchWithEvents( event_source, Events )
> pythoncom.PumpMessages()
>
> The C++ code snippets are the following
> class CMyListener :
> // _StItemSink is the default source (outgoing) dspinterface for
> // StItemEventSource objects.
> public IDispatchImpl<_IStItemSink, &DIID__IStItemSink, &LIBID_StarTeam>,
> public CComObjectRoot
> {
> public:
> CMyListener() {}
> BEGIN_COM_MAP(CMyListener)
> COM_INTERFACE_ENTRY(IDispatch)
> COM_INTERFACE_ENTRY(_IStItemSink)
> END_COM_MAP()
> ....
> // _IStItemSink is a dspinterface.
> // We must implement IDispatch::Invoke().
> STDMETHOD(Invoke)( DISPID dispIdMember,
> REFIID riid, LCID lcid,
> WORD wFlags,
> DISPPARAMS FAR* pDispParams,
> VARIANT FAR* pVarResult,
> EXCEPINFO FAR* pExcepInfo,
> unsigned int FAR* puArgErr )
> {
> ....
> }
> ....
> // Create the event source for CHANGEREQUEST items.
> CComPtr<IStItemEventSource> source;
> hr = stView->newItemEventSource(type, &source);
> if (!VerifyHR(hr, IID_IStView, stView)) {
> return(false);
> }
>
> // The event source is the connection point container.
> CComPtr<IConnectionPointContainer> cpc;
> hr = source->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc);
> if (!VerifyHR(hr, IID_IStItemEventSource, source)) {
> return(false);
> }
>
> // Find the connection point for Item events.
> // We save it so that we can call IConnectionPointContainer::Unadvise()
> later.
> hr = cpc->FindConnectionPoint(DIID__IStItemSink, &m_cp);
> if (!VerifyHR(hr, IID_IConnectionPointContainer, cpc)) {
> return(false);
> }
>
> // Instantiate our listener.
> CComObject<CMyListener>* listener = NULL;
> hr = CComObject<CMyListener>::CreateInstance(&listener);
> if (!VerifyHR(hr)) {
> return(false);
> }
>
> // Slip in a pointer to the parent dialog.
> listener->m_dlg = this;
>
> // Connect the listener.
> // We save the cookie so that we can call
> IConnectionPointContainer::Unadvise() later.
> hr = m_cp->Advise(listener, &m_cookie);
> if (!VerifyHR(hr, IID_IConnectionPoint, m_cp)) {
> return(false);
>
> Any ideas on what I'm missing? Is it that the object is an Dispatch
> Interface, and so I'm not handling that correctly?
>
> Thanks,
> Darren
>
>
> ------------------------------------------------------------------------
> *From:* Mark Hammond <skippy.hamm...@gmail.com>
> *To:* Darren McElfresh <dmcelfr...@yahoo.com>
> *Cc:* "python-win32@python.org" <python-win32@python.org>
> *Sent:* Tuesday, February 28, 2012 5:15 PM
> *Subject:* Re: [python-win32] Help Needed on Handling Events from a
> Proprietary COM Object
>
> On 29/02/2012 8:26 AM, Darren McElfresh wrote:
>  > I’ve read through numerous posts on how to get this to work, but I’ve
>  > realized it is time to ask for help.
>  > In general I have a COM object that returns an event handler:
>  > /event_source = com_object.newEventSource( arg_data )/
>  > I’ve tried establishing the connection points necessary by creating an
>  > event class derived on the sink co-class of this event source:
>  > /class Events(win32com.client.getevents(COM_LIB.CLSID)):/
>  > I included all of the methods that were mentioned in the generated code
>  > from makepy.From there I tried to utilize DispatchWithEvents to connect
>  > the listener:
>  > /event_monitor = win32com.client.DispatchWithEvents( event_source,
> Events )/
>
> Using DispatchWithEvents means you shouldn't need to use getevents
> manually at all - it does the getevents for you. So just defining your
> Events class without a base-class should work - check out the docstring
> for DispatchWithEvents.
>
>  > Everything seems fine at this point, but when I use try to listen it
>  > never seems to fire:
>  > /rc = win32event.WaitForSingleObject( event_monitor.event, TIME )/
>
> What is event_monitor.event? I guess it must be an integer event handle,
> but it is worth checking it is sane. Also, that doesn't really make
> sense as an event sink - presumably you have referenced the 'event'
> attribute before an event has fired, so the actual firing of an event
> doesn't seem to need to do anything - it just sets the handle object and
> wouldn't need to make a callback into your handler. Generally the firing
> of an event will explicitly call a method you supply, but that doesn't
> seem to be the case here.
>
> Even if that was "normal" for your object, you might need
> MsgWaitForMultipleObjects - a message loop way well be needed to deliver
> the event calls (ie, so the event handler functions can be called).
>
>  > I’ve even tried (even though I don’t think it is necessary for single
>  > threaded applications):
>  > /pythoncom.PumpWaitingMessages()/
>
> A single threaded application will have to do *something* while it is
> waiting for the events to fire, so unless you are in a UI like
> pythonwin, you *will* need something like PumpMessages - otherwise your
> thread will just terminate. PumpWaitingMessages only pumps what is
> queued now - you need PumpMessages to pump "forever" - or until you call
> PostQuitMessage to kill the pump, presumably in response to a future event)
>
> But I'm missing something - either you expect an "event" to set a
> Windows event handle (and therefore probably need
> MsgWaitForMultipleObjects) or you expect an "event" to make a callback
> on your event handler (in which case you need something like
> PumpMessages) - but the 2 scenarios are quite different depending on
> what is expected to happen.
>
>  > However that didn’t seem to have any impact either.No matter what I try
>  > – I can’t get my handlers to fire.I have sample code on how to do this
>  > in C++, and I have already taken the sample Java code and have my own
>  > version of that working; however I’d prefer to use Python if I can get
>  > it to work.
>  > I can provide my code (or the samples), but it is somewhat lengthy so I
>  > was hoping someone would see what I was missing right away?
>
> Maybe you could just provide a summary of the relevant C++ code?
>
> Mark
>
>
>
>
> _______________________________________________
> python-win32 mailing list
> python-win32@python.org
> http://mail.python.org/mailman/listinfo/python-win32
_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to