[python-win32] Creating python com objects

Tim Golden mail at timgolden.me.uk
Thu Apr 24 21:28:42 CEST 2008


Alex Denham wrote:
> 
> Thanks Tim, the program actually reacts when something is dragged over 
> (much better than before).
> However i'm receiving an error everytime.
> 
>  >>>
> pythoncom error: Unexpected exception in gateway method 'DragEnter'
> <type 'exceptions.AttributeError'>: DragEnter
> pythoncom error: Unexpected gateway error

I've finally got round to producing a test harness to
recreate this situation. (I've never actually used
this functionality before, I'm afraid). And I get the
same error. I've looked at the source code in PyIDropTarget.cpp,
but I'm afraid I haven't the energy to plough through the
gateway code at the moment trying to find out what's
calling what calling what.

One thing to correct from my earlier code is that the
WrapObject function should specify the IID_IDropTarget
interface twice, otherwise you end up with an IDispatch.
But that's not the real problem. The "Unexpected exception"
seems to mean that something's happened internally to the
gateway logic which caused this, and the AttributeError
suggests that it's failing to find the DragEnter method.
But I can't see whether that's a flaw in my technique for
building up the COM object, or a flaw in the gateway code
for discerning its attributes.

> Also, in the documentation it says:
>  
> *Drop(/pDataObj//, pt//, dwEffect/*)
> 
> 
>       Parameters
> 
> /pDataObj/ : *PyIDataObject **
>  
> How do i link the IDataObject to the IDragTarget?

I don't know that you can, if you're asking: how do I
find out where this is coming from?. I think the drag-drop
technique is endpoint-agnostic. (A high-sounding phrase I've
just invented). The most you can do is get hold of the data.
Again, I think.

I'm out of my depth so I'm hoping that Roger or Mark
or other more knowledgeable people can chip in at this point
and help.

For the purposes of discussion, I attach below my test harness
code which creates a simple window and registers a simple
IDropTarget object against it.

Sorry to be no more help than this.
TJG

<code>
import os, sys
import win32gui
import win32con
import pythoncom

CLSID = '{89DD545A-2C83-4103-AFE3-6CEB7FF5ECA4}'
PROGID = "Tim.DropTarget"
DESC = "Drop target handler for Tim's app"

class DropTarget:
   _reg_clsid_ = CLSID
   _reg_progid_ = PROGID
   _reg_desc_ = DESC
   _public_methods_ = ['DragEnter', 'DragOver', 'DragLeave', 'Drop']
   _com_interfaces_ = [pythoncom.IID_IDropTarget]

   def DragEnter (self, data_object, key_state, point, effect):
        pass
   def DragOver (self, key_state, point, effect):
        pass
   def DragLeave (self):
        pass
   def Drop (self, data_object, key_state, point, effect):
        pass

def create_window ():
   def OnDestroy (hwnd, msg, wparam, lparam):
     win32gui.PostQuitMessage (0)

   wc = win32gui.WNDCLASS ()
   hinst = win32gui.GetModuleHandle(None)
   wc.lpszClassName = "DragDrop"
   wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;
   wc.hCursor = win32gui.LoadCursor (0, win32con.IDC_ARROW)
   wc.hbrBackground = win32con.COLOR_WINDOW
   wc.lpfnWndProc = {win32con.WM_DESTROY : OnDestroy}
   classAtom = win32gui.RegisterClass (wc)
   style = win32con.WS_VISIBLE | \
     win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
   return win32gui.CreateWindow (
     classAtom,
     "Drag & Drop demo",
     style,
     0, 0, 100, 100,
     0, 0, hinst, None
   )

if __name__ == '__main__':
   pythoncom.OleInitialize ()
   drop_target = pythoncom.WrapObject (
     DropTarget,
     pythoncom.IID_IDropTarget,
     pythoncom.IID_IDropTarget
   )
   pythoncom.RegisterDragDrop (create_window (), drop_target)
   win32gui.PumpMessages ()

</code>


More information about the python-win32 mailing list