An interesting read is http://msdn.microsoft.com/en-us/library/bb776904.aspx - it shows that lots of interesting state is communicated via SetData calls with custom formats. The IAsyncOperation interface is also an interesting distraction.
Cheers, Mark From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of mir amicitas Sent: Wednesday, 24 September 2008 5:46 PM To: python-win32@python.org Subject: Re: [python-win32] Drag and drop of files (CF_HDROP) >The last arg is output, and will be returned from the function. > In that case I am confused about the output coming out of DoDragDrop(). The output that I get for different cases: drag canceled: 0 copy succeed: 1 move succeed: 0 I expect that move succeed would give me a value of 2 (shellcon.DROPEFFEC_MOVE). With the output above I cannot tell weather a move succeded or the drop got canceled. This is not critical functionality for me (I don't need to know the end result). At this point I am just curious. Below I am including the dragging code that I put together, just in case it is useful to anyone. (if anyone happens to notice something horribly wrong with it let me know though.) - Novi ------------------------------------------- import pythoncom import win32con import winerror import win32clipboard from win32com.server.util import NewEnum, wrap from win32com.server.exception import COMException from win32com.shell import shellcon num_do_objects = 0 def WrapCOMObject(ob, iid=None): return wrap(ob, iid=iid, useDispatcher = 0) def PackDROPFILESStructure(file_name_array): import struct """ typedef struct _DROPFILES { DWORD pFiles; POINT pt; BOOL fNC; BOOL fWide; } DROPFILES, *LPDROPFILES; """ file_name_buffer='\0'.join(file_name_array)+'\0\0' fmt="lllll%ss" %len(file_name_buffer) dropfiles=struct.pack(fmt, 20, 0, 0, 0, 0, file_name_buffer) return dropfiles def RegisterClipboardFormats(qmimedata): """ Here we extract all of the formats from the qmimedata object and register them. This will give us an ID for each type. This will return a dictionary with the ID's and descriptions for each mime type. """ mime_formats = qmimedata.formats() format_dictionary = dict() for format in mime_formats: id = win32clipboard.RegisterClipboardFormat(str(format)) format_dictionary[id] = format return format_dictionary def GetClipboardFormats(qmimedata): """ What I want to do here is to check if any of the mime data in the QMimeData object can/should be converted into a standard windows clipboard format. If it can I will extract the data here. This essentially does what QWindowsMime probably does, but since QWindowsMime is not in PyQt4 I have to do this myself. """ format_dictionary = dict() if qmimedata.hasText(): id = win32con.CF_TEXT data = str(qmimedata.text()) format_dictionary[id] = data id = win32con.CF_UNICODETEXT data = unicode(qmimedata.text()) format_dictionary[id] = data if qmimedata.hasUrls(): files = [] for url in qmimedata.urls(): file_name = url.toLocalFile() if file_name: files.append(str(file_name)) if files: id = win32con.CF_HDROP format_dictionary[id] = files return format_dictionary class IDropSource: _com_interfaces_ = [pythoncom.IID_IDropSource] _public_methods_ = ["QueryContinueDrag", "GiveFeedback"] def __init__(self): pass def __del__(self): pass def QueryContinueDrag(self, is_escape_pressed, modifier_key_state): if is_escape_pressed == True: return winerror.DRAGDROP_S_CANCEL if (modifier_key_state & win32con.MK_LBUTTON) == False and \ (modifier_key_state & win32con.MK_RBUTTON) == False: return winerror.DRAGDROP_S_DROP return winerror.S_OK def GiveFeedback(self, effect): return winerror.DRAGDROP_S_USEDEFAULTCURSORS class IDataObject: _com_interfaces_ = [pythoncom.IID_IDataObject] _public_methods_ = ["GetData", "GetDataHere", "QueryGetData" \ ,"GetCanonicalFormatEtc", "SetData", "EnumFormatEtc" \ ,"DAdvise", "DUnadvise", "EnumDAdvise"] def __init__(self, qmimedata): global num_do_objects num_do_objects += 1 self.qmimedata = qmimedata self.mime_formats = RegisterClipboardFormats(qmimedata) self.clipboard_formats = GetClipboardFormats(qmimedata) self.supported_formatetc = [] for format in self.mime_formats: formatetc = format, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL self.supported_formatetc.append(formatetc) for format in self.clipboard_formats: formatetc = format, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL self.supported_formatetc.append(formatetc) def __del__(self): global num_do_objects num_do_objects -= 1 def _query_interface_(self, iid): if iid==pythoncom.IID_IEnumFORMATETC: return NewEnum(self.supported_formatetc, iid=iid) def GetData(self, formatetc_in): #print 'GetData' ret_stg = None cf_in, target_in, aspect_in, index_in, tymed_in = formatetc_in # Loop through the supported formats. # We do this as opposed to directly searching mime_formats & clipboard_formats # mostly just to make sure the order is consistant. for formatetc in self.supported_formatetc: cf, target, aspect, index, tymed = formatetc if (aspect_in == aspect) and \ (tymed_in & tymed) and \ (cf_in == cf): ret_stg = pythoncom.STGMEDIUM() if self.mime_formats.has_key(cf): data = self.qmimedata.data(self.mime_formats[cf]) ret_stg.set(tymed, data) elif self.clipboard_formats.has_key(cf): data = self.clipboard_formats[cf] if cf == win32con.CF_TEXT or cf_in == win32con.CF_UNICODETEXT: ret_stg.set(tymed, data) elif cf == win32con.CF_HDROP: dropfiles = PackDROPFILESStructure(data) ret_stg.set(tymed, dropfiles) else: print "hystrixNtDrag.IDataObject.GetData:" print " Programming Error: id should be supported but isn't" if ret_stg is None: raise COMException(hresult=winerror.E_NOTIMPL) return ret_stg def GetDataHere(self, formatetc): #print 'GetDataHere' raise COMException(hresult=winerror.E_NOTIMPL) def QueryGetData(self, formatetc_in): #print 'QueryGetData' cf_in, target_in, aspect_in, index_in, tymed_in = formatetc_in for formatetc in self.supported_formatetc: cf, target, aspect, index, tymed = formatetc if (aspect_in & aspect) and \ (tymed_in & tymed) and \ (cf_in == cf): return winerror.S_OK raise COMException(hresult=winerror.DV_E_FORMATETC) return winerror.DV_E_FORMATETC def GetCanonicalFormatEtc(self, formatetc): #print 'GetCanonicalFormatEtc' RaiseCOMException(winerror.DATA_S_SAMEFORMATETC) # return fe def SetData(self, formatetc, medium, fRelease): #print 'SetData' raise COMException(hresult=winerror.E_NOTIMPL) def EnumFormatEtc(self, direction): #print 'EnumFormatEtc' if direction != pythoncom.DATADIR_GET: raise COMException(hresult=winerror.E_NOTIMPL) return NewEnum(self.supported_formatetc, iid=pythoncom.IID_IEnumFORMATETC) def DAdvise(self, formatetc, flags, sink): #print 'DAdvise' raise COMException(hresult=winerror.E_NOTIMPL) def DUnadvise(self, connection): #print 'DUnadvise' raise COMException(hresult=winerror.E_NOTIMPL) def EnumDAdvise(self): #print 'EnumDAdvise' raise COMException(hresult=winerror.E_NOTIMPL) def DoDragDrop(qmimedata, allow_copy=True, allow_move=False): source = IDropSource() source = WrapCOMObject(source, iid=pythoncom.IID_IDropSource) data_object = IDataObject(qmimedata) data_object = WrapCOMObject(data_object, iid=pythoncom.IID_IDataObject) effect_mask = 0 if allow_copy: effect_mask += shellcon.DROPEFFECT_COPY if allow_move: effect_mask += shellcon.DROPEFFECT_MOVE value = pythoncom.DoDragDrop(data_object, source, effect_mask) print value
_______________________________________________ python-win32 mailing list python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32