Ward Posted March 9, 2012 Share Posted March 9, 2012 (edited) To deal with OLE drag-and-drop event is painful in autoit. is an exmaple from ProgAndy (thanks). But since we have AutoItObject UDF, it should go easy. However, there are still a lot of works to do. So I wrote the UDF to convert OLE drag-and-drop event to "Windows Message" event that can be easily handled by GUIRegisterMsg() in AutoIt. This UDF provides 4 kinds of message: $WM_DRAGENTER, $WM_DRAGOVER, $WM_DRAGLEAVE, and $WM_DROP. To use is easy, just register a GUI window or control as the drop target, then handle message by GUIRegisterMsg(). See example: expandcollapse popup#Include <GUIConstantsEx.au3> #Include <WindowsConstants.au3> #Include "DragDropEvent.au3" Opt("MustDeclareVars", 1) DragDropEvent_Startup() Main() Exit Func Main() Local $MainWin = GUICreate("DragDropEvent Example", 380, 130, -1, -1, -1, $WS_EX_TOPMOST) GUISetFont(12, 900) GUICtrlCreateLabel("(Drop text or files on me)", 40, 40) DragDropEvent_Register($MainWin) GUIRegisterMsg($WM_DRAGENTER, "OnDragDrop") GUIRegisterMsg($WM_DRAGOVER, "OnDragDrop") GUIRegisterMsg($WM_DRAGLEAVE, "OnDragDrop") GUIRegisterMsg($WM_DROP, "OnDragDrop") GUISetState(@SW_SHOW) While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd GUIDelete() EndFunc Func OnDragDrop($hWnd, $Msg, $wParam, $lParam) Static $DropAccept Switch $Msg Case $WM_DRAGENTER, $WM_DROP ToolTip("") Select Case DragDropEvent_IsFile($wParam) If $Msg = $WM_DROP Then Local $FileList = DragDropEvent_GetFile($wParam) MsgBox(262144, "DragDropEvent", StringReplace($FileList, "|", @LF)) EndIf $DropAccept = $DROPEFFECT_COPY Case DragDropEvent_IsText($wParam) If $Msg = $WM_DROP Then MsgBox(262144, "DragDropEvent", DragDropEvent_GetText($wParam)) EndIf $DropAccept = $DROPEFFECT_COPY Case Else $DropAccept = $DROPEFFECT_NONE EndSelect Return $DropAccept Case $WM_DRAGOVER Local $X = DragDropEvent_GetX($wParam) Local $Y = DragDropEvent_GetY($wParam) ToolTip("(" & $X & "," & $Y & ")") Return $DropAccept Case $WM_DRAGLEAVE ToolTip("") EndSwitch EndFunc == Public Functions List == DragDropEvent_Startup() ; DragDropEvent UDF startup. ; DragDropEvent_Register($hWnd, $hWndToReceiveMsg = $hWnd) ; Register a window or control that can be the target. $hWndToReceiveMsg is needed only when $hWnd is a control. ; DragDropEvent_Revoke($hWnd) ; Revokes the registration of the specified window or control. ; DragDropEvent_GetHWnd($wParam) ; Can invoke by all message handler, to get what window or control is the target. ; DragDropEvent_GetX($wParam) DragDropEvent_GetY($wParam) DragDropEvent_GetKeyState($wParam) ; Can invoke by all message handler except $WM_DRAGLEAVE, to get the modifier keys and mouse position. ; DragDropEvent_IsText($wParam) DragDropEvent_IsFile($wParam) ; Can invoke by $WM_DRAGENTER or $WM_DROP, to check what data is being dragged. ; DragDropEvent_GetText($wParam) DragDropEvent_GetFile($wParam) ; Can invoke by $WM_DRAGENTER or $WM_DROP, to get related data. Path of file is splited by "|". ; == Requirement == AutoIt 3.3.8.0Attachment not includes above requirement files, but includes more examples. == Update 2012/3/10 ==* Fix x64 problem. (Thanks to trancexx)* Remove dependency to AutoItObject and Associative Array UDF. (Suggestion by wraithdu) == Update 2012/3/15==* Remove dependency to Bianry UDF.* Remove extra DllStructGetPtr(). (Suggestion by trancexx)* Fix bug in DataObject_GetFile(). DragDropEvent.zip Edited November 23, 2015 by Ward Zedna 1 新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了。 Link to comment Share on other sites More sharing options...
trancexx Posted March 9, 2012 Share Posted March 9, 2012 Excellent as always with you.Are you sure you got the x64 issue correctly. By looking at the code the problem with x64 could be struct parameter for methods of that interface. You have used POINTL = uint;uint logic, but that's valid only for x86 (it should be long;long btw). ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
outdated Posted March 9, 2012 Share Posted March 9, 2012 good examples but dunno where u can use it $WS_EX_ACCEPTFILES for me it enough Link to comment Share on other sites More sharing options...
Ward Posted March 9, 2012 Author Share Posted March 9, 2012 @trancexxThank you for always find the problem. Now I use uint64 to receive the POINTL struct. It works both x86 and x64.@macwcodvs$WS_EX_ACCEPTFILES and $WM_DROPFILES are what I use before.If you don't want to handle text and mouse enter / leave / over event. They are enough.I wrote these UDF because my new program need to drag files to a TreeView control. However, when use WM_DROPFILES, I don't know where to insert the new node. 新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了。 Link to comment Share on other sites More sharing options...
wraithdu Posted March 9, 2012 Share Posted March 9, 2012 (edited) Could this be updated to use the new internal ObjCreateInterface function? That would remove the req for AutoItObject. Edited March 9, 2012 by wraithdu Link to comment Share on other sites More sharing options...
Ward Posted March 10, 2012 Author Share Posted March 10, 2012 @wraithdu, using ObjCreateInterface need to write a replacement of _AutoItObject_ObjectFromDtag.It should not hard, just copy the code from AutoItObject.au3... 新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了。 Link to comment Share on other sites More sharing options...
Ward Posted March 10, 2012 Author Share Posted March 10, 2012 @wraithdu, I just done what you suggested !Since need to rewrite _AutoItObject_ObjectFromDtag, I also removed a memory leakage and the dependency to associative array UDF (instead of using associative array, I store the hwnd data just in the interface vtable). 新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了。 Link to comment Share on other sites More sharing options...
trancexx Posted March 10, 2012 Share Posted March 10, 2012 (edited) By using built-in function you have some new data types available, like struct*. If you specify that inside description strings instead of ptr, you don't need tedious DllStructGetPtr() every time you try to pass pointer of a struct.struct* will accept either pointer or a structure itself (in which case it will query for pointer internally). Edited March 10, 2012 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Saiph Posted July 22, 2012 Share Posted July 22, 2012 Hi, your udf is wonderful and works with Opera and Chrome but not with Firefox. When I drag and drop an image from Firefox to a your example Gui it says me C:UsersmyuserAppDataLocalTempagkri35bho.bmp and not the internet address. Can you suufest me a solution? Thanks Link to comment Share on other sites More sharing options...
prazetto Posted April 16, 2013 Share Posted April 16, 2013 @Saiph Thats aren't UDF fault but what browser like Mozillia Firefox or Seamonkey add to DragDrop source. # Button. Progressbar - Graphical AutoIt3 Control (UDF) # GTK on AutoIt3 - GTK+ Framework | Widgets cig computer instruction graphics http://code.hstn.me Link to comment Share on other sites More sharing options...
AutID Posted October 19, 2014 Share Posted October 19, 2014 Correct this line : If @AutoItVersion < "3.3.8.0" Then Exit MsgBox(16, "DragDropEvent Fail", "Require AutoIt Version 3.3.8.0 at least") This is excellent work my friend. https://iblockify.wordpress.com/ Link to comment Share on other sites More sharing options...
Zedna Posted June 2, 2016 Share Posted June 2, 2016 Please can somebody upload missing file DragDropEvent.zip? Thanks Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Gianni Posted June 2, 2016 Share Posted June 2, 2016 1 hour ago, Zedna said: Please can somebody upload missing file DragDropEvent.zip? Thanks I haven't the zip file, but probably these three listings were in that zip: DragDropEvent.au3 expandcollapse popup; =============================================================================================================================== ; File : DragDropEvent.au3 (2012/3/15) ; Purpose : Convert OLE drag-and-drop event to "Windows Message" that AutoIt3 can handle by GUIRegisterMsg ; Provide 4 message: $WM_DRAGENTER, $WM_DRAGOVER, $WM_DRAGLEAVE, and $WM_DROP ; Author : Ward ; =============================================================================================================================== #Include-once #Include <Memory.au3> #Include <SendMessage.au3> #Include <WindowsConstants.au3> ; =============================================================================================================================== ; Public Functions: ; ; DragDropEvent_Startup() ; DragDropEvent UDF startup. ; ; DragDropEvent_Register($hWnd, $hWndToReceiveMsg = $hWnd) ; Register a window or control that can be the target. $hWndToReceiveMsg is needed only when $hWnd is a control. ; ; DragDropEvent_Revoke($hWnd) ; Revokes the registration of the specified window or control. ; ; DragDropEvent_GetHWnd($wParam) ; Can invoke by all message handler, to get what window or control is the target. ; ; DragDropEvent_GetX($wParam) ; DragDropEvent_GetY($wParam) ; DragDropEvent_GetKeyState($wParam) ; Can invoke by all message handler except $WM_DRAGLEAVE, to get the modifier keys and mouse position. ; ; DragDropEvent_IsText($wParam) ; DragDropEvent_IsFile($wParam) ; Can invoke by $WM_DRAGENTER or $WM_DROP, to check what data is being dragged. ; ; DragDropEvent_GetText($wParam) ; DragDropEvent_GetFile($wParam) ; Can invoke by $WM_DRAGENTER or $WM_DROP, to get related data. Path of file is splited by "|". ; ; =============================================================================================================================== ; =============================================================================================================================== ; Internal Functions: ; ; IDropTarget_QueryInterface($pSelf, $pRIID, $pObj) ; IDropTarget_AddRef($pSelf) ; IDropTarget_Release($pSelf) ; IDropTarget_DragEnter($pSelf, $DataObj, $KeyState, $X, $Y, $pEffect) ; IDropTarget_DragLeave($pSelf) ; IDropTarget_DragOver($pSelf, $KeyState, $X, $Y, $pEffect) ; IDropTarget_Drop($pSelf, $DataObj, $KeyState, $X, $Y, $pEffect) ; IDropTarget_SetEffect($pEffect, $Value) ; Methods of IDropTarget interface. ; ; IDropTarget_SetHWnd($pSelf, $hWnd, $hWndToReceiveMsg) ; IDropTarget_GetHWnd($pSelf, ByRef $hWnd, ByRef $hWndToReceiveMsg) ; To set and get data store in IDropTarget interface. ; ; DataObject_QueryText($DataObj) ; DataObject_QueryFile($DataObj) ; DataObject_GetText($DataObj) ; DataObject_GetFile($DataObj) ; Functions to handle DataObject. ; ; DragDropEvent_InfoCreate($hWnd, $DataObj, $KeyState, $X, $Y) ; DragDropEvent_Get($wParam, $Name) ; Functions to handle infomation data for DragDropEvent. ; ; __CreateCOMInterface($sFunctionPrefix, $dtagInterface, $fNoUnknown = False, $ExtraSpace = 0) ; To create vtable of a COM interface. Modify from _AutoItObject_ObjectFromDtag. ; ; =============================================================================================================================== ; =============================================================================================================================== ; Global const and variables ; =============================================================================================================================== ; Define 4 kind of DragDropEvent: DragEnter, DragOver, DragLeave, and Drop Global Enum $WM_DRAGENTER = $WM_USER + 0x1001, $WM_DRAGOVER, $WM_DRAGLEAVE, $WM_DROP ; Message handler return one of these flags, which indicates what the result of the drop operation would be. Global Enum $DROPEFFECT_NONE = 0, $DROPEFFECT_COPY = 1, $DROPEFFECT_MOVE = 2, $DROPEFFECT_LINK = 4, $DROPEFFECT_SCROLL = 0x80000000 Global Const $IID_IDataObject = "{0000010e-0000-0000-C000-000000000046}" Global Const $dtagIDropTarget = "DragEnter hresult(ptr;uint;uint64;ptr);DragOver hresult(uint;uint64;ptr);DragLeave hresult();Drop hresult(ptr;uint;uint64;ptr);" Global Const $dtagIDataObject = "GetData hresult(struct*;struct*);GetDataHere hresult(struct*;struct*);QueryGetData hresult(struct*);GetCanonicalFormatEtc hresult(struct*;struct*);SetData hresult(struct*;struct*;int);EnumFormatEtc hresult(uint;ptr);DAdvise hresult(struct*;uint;ptr;ptr);DUnadvise hresult(uint);EnumDAdvise hresult(ptr);" Global Const $tagFORMATETC = "struct;uint Format;ptr ptd;uint Aspect;int lindex;uint tymed;endstruct" Global Const $tagSTGMEDIUM = "struct;uint tymed;ptr hGlobal;ptr UnkForRelease;endstruct" Global Const $tagDragDropEventInfo = "ptr hwnd;ptr DataObj;uint KeyState;uint x;uint y" Global Const $__KERNEL32_DLL = DllOpen("kernel32.dll") Global Const $__OLE32_DLL = DllOpen("ole32.dll") Global $__IDropTargetLen = 0 ; =============================================================================================================================== ; DragDropEvent startup and register functions ; =============================================================================================================================== Func DragDropEvent_Startup() ; If @AutoItVersion < "3.3.8.0" Then Exit MsgBox(16, "DragDropEvent Fail", "Require AutoIt Version 3.3.8.0 at least") DllCall($__OLE32_DLL, "int", "OleInitialize", "ptr", 0) EndFunc Func DragDropEvent_Register($hWnd, $hWndToReceiveMsg = Default) If IsKeyword($hWndToReceiveMsg) Then $hWndToReceiveMsg = $hWnd Local $IDropTarget = __CreateCOMInterface("IDropTarget_", $dtagIDropTarget, True, 2) ; add 2 extra space to store hWnd If $IDropTarget Then $__IDropTargetLen = @Extended IDropTarget_SetHWnd($IDropTarget, $hWnd, $hWndToReceiveMsg) DllCall($__OLE32_DLL, "int", "RegisterDragDrop", "hwnd", $hWnd, "ptr", $IDropTarget) EndIf EndFunc Func DragDropEvent_Revoke($hWnd) DllCall($__OLE32_DLL, "int", "RevokeDragDrop", "hwnd", $hWnd) EndFunc ; =============================================================================================================================== ; Methods of IDropTarget interface ; =============================================================================================================================== Func IDropTarget_QueryInterface($pSelf, $pRIID, $pObj) Return 0x80004002 ; E_NOINTERFACE EndFunc Func IDropTarget_AddRef($pSelf) EndFunc Func IDropTarget_Release($pSelf) DllCall($__OLE32_DLL, "none", "CoTaskMemFree", "ptr", $pSelf) EndFunc Func IDropTarget_DragEnter($pSelf, $DataObj, $KeyState, $Point, $pEffect) Local $hWnd, $hWndToReceiveMsg IDropTarget_GetHWnd($pSelf, $hWnd, $hWndToReceiveMsg) Local $X = BitAND($Point, 0xFFFFFFFF), $Y = Dec(StringTrimRight(Hex($Point), 8)) Local $Info = DragDropEvent_InfoCreate($hWnd, $DataObj, $KeyState, $X, $Y) Local $Ret = _SendMessage($hWndToReceiveMsg, $WM_DRAGENTER, DllStructGetPtr($Info), 0) DllStructSetData(DllStructCreate("dword", $pEffect), 1, $Ret) EndFunc Func IDropTarget_DragLeave($pSelf) Local $hWnd, $hWndToReceiveMsg IDropTarget_GetHWnd($pSelf, $hWnd, $hWndToReceiveMsg) Local $Info = DragDropEvent_InfoCreate($hWnd, 0, 0, 0, 0) _SendMessage($hWndToReceiveMsg, $WM_DRAGLEAVE, DllStructGetPtr($Info), 0) EndFunc Func IDropTarget_DragOver($pSelf, $KeyState, $Point, $pEffect) Local $hWnd, $hWndToReceiveMsg IDropTarget_GetHWnd($pSelf, $hWnd, $hWndToReceiveMsg) Local $X = BitAND($Point, 0xFFFFFFFF), $Y = Dec(StringTrimRight(Hex($Point), 8)) Local $Info = DragDropEvent_InfoCreate($hWnd, 0, $KeyState, $X, $Y) Local $Ret = _SendMessage($hWndToReceiveMsg, $WM_DRAGOVER, DllStructGetPtr($Info), 0) DllStructSetData(DllStructCreate("dword", $pEffect), 1, $Ret) EndFunc Func IDropTarget_Drop($pSelf, $DataObj, $KeyState, $Point, $pEffect) Local $hWnd, $hWndToReceiveMsg IDropTarget_GetHWnd($pSelf, $hWnd, $hWndToReceiveMsg) Local $X = BitAND($Point, 0xFFFFFFFF), $Y = Dec(StringTrimRight(Hex($Point), 8)) Local $Info = DragDropEvent_InfoCreate($hWnd, $DataObj, $KeyState, $X, $Y) Local $Ret = _SendMessage($hWndToReceiveMsg, $WM_DROP, DllStructGetPtr($Info), 0) DllStructSetData(DllStructCreate("dword", $pEffect), 1, $Ret) EndFunc Func IDropTarget_SetHWnd($pSelf, $hWnd, $hWndToReceiveMsg) Local $Buffer = DllStructCreate("ptr[" & ($__IDropTargetLen + 2) & "]", $pSelf) DllStructSetData($Buffer, 1, $hWnd, $__IDropTargetLen + 1) DllStructSetData($Buffer, 1, $hWndToReceiveMsg, $__IDropTargetLen + 2) EndFunc Func IDropTarget_GetHWnd($pSelf, ByRef $hWnd, ByRef $hWndToReceiveMsg) Local $Buffer = DllStructCreate("ptr[" & ($__IDropTargetLen + 2) & "]", $pSelf) $hWnd = DllStructGetData($Buffer, 1, $__IDropTargetLen + 1) $hWndToReceiveMsg = DllStructGetData($Buffer, 1, $__IDropTargetLen + 2) EndFunc ; =============================================================================================================================== ; Functions to handle DataObject ; =============================================================================================================================== Func DataObject_QueryText($DataObj) Local $IDataObj = ObjCreateInterface($DataObj, $IID_IDataObject, $dtagIDataObject) If Not IsObj($IDataObj) Then Return -1 $IDataObj.AddRef() Local $FORMATETC = DllStructCreate($tagFORMATETC) DllStructSetData($FORMATETC, "Format", 13) ; 13 = CF_UNICODETEXT DllStructSetData($FORMATETC, "Aspect", 1) DllStructSetData($FORMATETC, "lindex", -1) DllStructSetData($FORMATETC, "tymed", 1) ; 1 = TYMED_HGLOBAL Local $Ret = $IDataObj.QueryGetData($FORMATETC) If $Ret <> 0 Then DllStructSetData($FORMATETC, "Format", 1) ; 1 = CF_TEXT $Ret = $IDataObj.QueryGetData($FORMATETC) EndIf Return $Ret EndFunc Func DataObject_QueryFile($DataObj) Local $IDataObj = ObjCreateInterface($DataObj, $IID_IDataObject, $dtagIDataObject) If Not IsObj($IDataObj) Then Return -1 $IDataObj.AddRef() Local $FORMATETC = DllStructCreate($tagFORMATETC) DllStructSetData($FORMATETC, "Format", 15) ; 15 = CF_HDROP DllStructSetData($FORMATETC, "Aspect", 1) DllStructSetData($FORMATETC, "lindex", -1) DllStructSetData($FORMATETC, "tymed", 1) ; 1 = TYMED_HGLOBAL Return $IDataObj.QueryGetData($FORMATETC) EndFunc Func DataObject_GetText($DataObj) Local $IDataObj = ObjCreateInterface($DataObj, $IID_IDataObject, $dtagIDataObject) If Not IsObj($IDataObj) Then Return -1 $IDataObj.AddRef() Local $FORMATETC = DllStructCreate($tagFORMATETC) Local $STGMEDIUM = DllStructCreate($tagSTGMEDIUM) DllStructSetData($FORMATETC, "Format", 13) ; 13 = CF_UNICODETEXT DllStructSetData($FORMATETC, "Aspect", 1) DllStructSetData($FORMATETC, "lindex", -1) DllStructSetData($FORMATETC, "tymed", 1) ; 1 = TYMED_HGLOBAL Local $IsUnicode = True Local $Ret = $IDataObj.QueryGetData($FORMATETC) If $Ret <> 0 Then $IsUnicode = False DllStructSetData($FORMATETC, "Format", 1) ; 1 = CF_TEXT $Ret = $IDataObj.QueryGetData($FORMATETC) EndIf If $Ret <> 0 Then Return SetError(1, 0, "") Local $Error = 1, $Text = "" If $IDataObj.GetData($FORMATETC, $STGMEDIUM) = 0 Then If DllStructGetData($STGMEDIUM, "tymed") = 1 Then Local $Ptr = _MemGlobalLock(DllStructGetData($STGMEDIUM, "hGlobal")) Local $Tag If $IsUnicode Then $Tag = "wchar[" & (_MemGlobalSize($Ptr) / 2) & "]" Else $Tag = "char[" & _MemGlobalSize($Ptr) & "]" EndIf $Text = DllStructGetData(DllStructCreate($Tag, $Ptr), 1) _MemGlobalUnlock($Ptr) If DllStructGetData($STGMEDIUM, "UnkForRelease") = 0 Then _MemGlobalFree($Ptr) $Error = 0 EndIf EndIf Return SetError($Error, 0, $Text) EndFunc Func DataObject_GetFile($DataObj) Local $IDataObj = ObjCreateInterface($DataObj, $IID_IDataObject, $dtagIDataObject) If Not IsObj($IDataObj) Then Return -1 $IDataObj.AddRef() Local $FORMATETC = DllStructCreate($tagFORMATETC) Local $STGMEDIUM = DllStructCreate($tagSTGMEDIUM) DllStructSetData($FORMATETC, "Format", 15) ; 15 = CF_HDROP DllStructSetData($FORMATETC, "Aspect", 1) DllStructSetData($FORMATETC, "lindex", -1) DllStructSetData($FORMATETC, "tymed", 1) ; 1 = TYMED_HGLOBAL Local $Error = 1, $FileList = "" If $IDataObj.GetData($FORMATETC, $STGMEDIUM) = 0 Then If DllStructGetData($STGMEDIUM, "tymed") = 1 Then Local $Ptr = _MemGlobalLock(DllStructGetData($STGMEDIUM, "hGlobal")) Local $StrPtr = $Ptr + DllStructGetData(DllStructCreate("dword", $Ptr), 1) Do Local $Ret = DllCall($__KERNEL32_DLL, "uint", "lstrlenW", "ptr", $StrPtr) Local $StrLen = $Ret[0] If $StrLen Then Local $Str = DllStructGetData(DllStructCreate("wchar[" & $StrLen & "]", $StrPtr), 1) $FileList &= $Str & "|" $StrPtr += $StrLen * 2 + 2 EndIf Until $StrLen = 0 If StringRight($FileList, 1) = "|" Then $FileList = StringTrimRight($FileList, 1) _MemGlobalUnlock($Ptr) If DllStructGetData($STGMEDIUM, "UnkForRelease") = 0 Then _MemGlobalFree($Ptr) $Error = 0 EndIf EndIf Return SetError($Error, 0, $FileList) EndFunc ; =============================================================================================================================== ; Functions to handle infomation data for DragDropEvent ; =============================================================================================================================== Func DragDropEvent_InfoCreate($hWnd, $DataObj, $KeyState, $X, $Y) Local $Info = DllStructCreate($tagDragDropEventInfo) DllStructSetData($Info, "hwnd", $hWnd) DllStructSetData($Info, "DataObj", $DataObj) DllStructSetData($Info, "KeyState", $KeyState) DllStructSetData($Info, "x", $X) DllStructSetData($Info, "y", $Y) Return $Info EndFunc Func DragDropEvent_Get($wParam, $Name) If Not $wParam Then Return SetError(1, 0, 0) Local $Info = DllStructCreate($tagDragDropEventInfo, $wParam) Return DllStructGetData($Info, $Name) EndFunc Func DragDropEvent_GetHWnd($wParam) Local $Ret = DragDropEvent_Get($wParam, "hwnd") Return SetError(@Error, 0, $Ret) EndFunc Func DragDropEvent_GetX($wParam) Local $Ret = DragDropEvent_Get($wParam, "x") Return SetError(@Error, 0, $Ret) EndFunc Func DragDropEvent_GetY($wParam) Local $Ret = DragDropEvent_Get($wParam, "y") Return SetError(@Error, 0, $Ret) EndFunc Func DragDropEvent_GetKeyState($wParam) Local $Ret = DragDropEvent_Get($wParam, "KeyState") Return SetError(@Error, 0, $Ret) EndFunc Func DragDropEvent_IsText($wParam) Local $DataObj = DragDropEvent_Get($wParam, "DataObj") Return DataObject_QueryText($DataObj) = 0 EndFunc Func DragDropEvent_IsFile($wParam) Local $DataObj = DragDropEvent_Get($wParam, "DataObj") Return DataObject_QueryFile($DataObj) = 0 EndFunc Func DragDropEvent_GetText($wParam) Local $DataObj = DragDropEvent_Get($wParam, "DataObj") Return DataObject_GetText($DataObj) EndFunc Func DragDropEvent_GetFile($wParam) Local $DataObj = DragDropEvent_Get($wParam, "DataObj") Return DataObject_GetFile($DataObj) EndFunc ; =============================================================================================================================== ; Functions to create COM interface ; =============================================================================================================================== Func __CreateCOMInterface($sFunctionPrefix, $dtagInterface, $fNoUnknown = False, $ExtraSpace = 0) ; Original is _AutoItObject_ObjectFromDtag in AutoItObject.au3 by AutoItObject-Team ; Modify by Ward Local Const $__PtrSize = DllStructGetSize(DllStructCreate('ptr', 1)) Local Const $dtagIUnknown = "QueryInterface hresult(ptr;ptr*);AddRef dword();Release dword();" If $fNoUnknown Then $dtagInterface = $dtagIUnknown & $dtagInterface Local $sMethods = StringReplace(StringRegExpReplace($dtagInterface, "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF) If $sMethods = $dtagInterface Then $sMethods = StringReplace(StringRegExpReplace($dtagInterface, "\h*(\w+)\h*(;|;*\z)", "$1\|" & @LF), ";" & @LF, @LF) $sMethods = StringTrimRight($sMethods, 1) $sMethods = StringReplace(StringReplace(StringReplace(StringReplace($sMethods, "object", "idispatch"), "variant*", "ptr"), "hresult", "long"), "bstr", "ptr") Local $aMethods = StringSplit($sMethods, @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback Local $AllocSize = $__PtrSize * ($iUbound + 1 + $ExtraSpace) Local $Ret = DllCall($__OLE32_DLL, "ptr", "CoTaskMemAlloc", "uint_ptr", $AllocSize) If @error Then Return SetError(1, 0, 0) Local $AllocPtr = $Ret[0] Local $tInterface = DllStructCreate("ptr[" & $iUbound + 1 & "]", $AllocPtr) If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] $sTagPart = $aSplit[1] $sMethod = $sFunctionPrefix & $sNamePart $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams ; To avoid repeat allocate the same callback, a memory leakage $hCallback = Eval(":Callback:" & $sMethod) If Not $hCallback Then $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) Assign(":Callback:" & $sMethod, $hCallback, 2) EndIf DllStructSetData($tInterface, 1, DllCallbackGetPtr($hCallback), $i + 2) Next DllStructSetData($tInterface, 1, $AllocPtr + $__PtrSize) ; Interface method pointers are actually pointer size away Return SetExtended($iUbound + 1, $AllocPtr) ; Return interface size as @Extended for access extra space EndFunc DragDropEvent_Example_1.au3 expandcollapse popup; =============================================================================================================================== ; File : DragDropEvent_Example_1.au3 (2012/3/9) ; Purpose : Demonstrate the usage of DragDropEvent UDF ; Author : Ward ; =============================================================================================================================== #Include <GUIConstantsEx.au3> #Include <WindowsConstants.au3> #Include "DragDropEvent.au3" Opt("MustDeclareVars", 1) DragDropEvent_Startup() Main() Exit Func Main() Local $MainWin = GUICreate("DragDropEvent Example", 380, 130, -1, -1, -1, $WS_EX_TOPMOST) GUISetFont(12, 900) GUICtrlCreateLabel("(Drop text or files on me)", 40, 40) DragDropEvent_Register($MainWin) GUIRegisterMsg($WM_DRAGENTER, "OnDragDrop") GUIRegisterMsg($WM_DRAGOVER, "OnDragDrop") GUIRegisterMsg($WM_DRAGLEAVE, "OnDragDrop") GUIRegisterMsg($WM_DROP, "OnDragDrop") GUISetState(@SW_SHOW) While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd GUIDelete() EndFunc Func OnDragDrop($hWnd, $Msg, $wParam, $lParam) Static $DropAccept Switch $Msg Case $WM_DRAGENTER, $WM_DROP ToolTip("") Select Case DragDropEvent_IsFile($wParam) If $Msg = $WM_DROP Then Local $FileList = DragDropEvent_GetFile($wParam) MsgBox(262144, "DragDropEvent", StringReplace($FileList, "|", @LF)) EndIf $DropAccept = $DROPEFFECT_COPY Case DragDropEvent_IsText($wParam) If $Msg = $WM_DROP Then MsgBox(262144, "DragDropEvent", DragDropEvent_GetText($wParam)) EndIf $DropAccept = $DROPEFFECT_COPY Case Else $DropAccept = $DROPEFFECT_NONE EndSelect Return $DropAccept Case $WM_DRAGOVER Local $X = DragDropEvent_GetX($wParam) Local $Y = DragDropEvent_GetY($wParam) ToolTip("(" & $X & "," & $Y & ")") Return $DropAccept Case $WM_DRAGLEAVE ToolTip("") EndSwitch EndFunc DragDropEvent_Example_2.au3 expandcollapse popup; =============================================================================================================================== ; File : DragDropEvent_Example_2.au3 (2012/3/9) ; Purpose : Demonstrate the usage of DragDropEvent UDF ; Author : Ward ; =============================================================================================================================== #Include <GUIConstantsEx.au3> #Include <WindowsConstants.au3> #Include "DragDropEvent.au3" Opt("MustDeclareVars", 1) Global $Button1, $Button2, $Button3, $Button4 DragDropEvent_Startup() Main() Exit Func Main() Local $MainWin = GUICreate("DragDropEvent Example", 460, 400, -1, -1, -1, $WS_EX_TOPMOST) GUISetFont(12, 900) $Button1 = GUICtrlCreateButton("Drop Text", 20, 20, 200, 150) $Button2 = GUICtrlCreateButton("Drop Files", 240, 20, 200, 150) $Button3 = GUICtrlCreateButton("Drop Anything", 20, 190, 200, 150) $Button4 = GUICtrlCreateButton("Don't Drop", 240, 190, 200, 150) GUICtrlCreateLabel("(Click button to revoke the target)", 40, 350) DragDropEvent_Register(GUICtrlGetHandle($Button1), $MainWin) DragDropEvent_Register(GUICtrlGetHandle($Button2), $MainWin) DragDropEvent_Register(GUICtrlGetHandle($Button3), $MainWin) DragDropEvent_Register(GUICtrlGetHandle($Button4), $MainWin) GUIRegisterMsg($WM_DRAGENTER, "OnDragDrop") GUIRegisterMsg($WM_DRAGOVER, "OnDragDrop") GUIRegisterMsg($WM_DRAGLEAVE, "OnDragDrop") GUIRegisterMsg($WM_DROP, "OnDragDrop") GUISetState(@SW_SHOW) While 1 Local $Msg = GUIGetMsg() Switch $Msg Case $Button1, $Button2, $Button3, $Button4 DragDropEvent_Revoke(GUICtrlGetHandle($Msg)) Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() EndFunc Func OnDragDrop($hWnd, $Msg, $wParam, $lParam) Static $DropAccept Switch $Msg Case $WM_DRAGENTER, $WM_DROP ToolTip("") Local $Target = DragDropEvent_GetHWnd($wParam) Select Case DragDropEvent_IsFile($wParam) If $Target = GUICtrlGetHandle($Button1) Or $Target = GUICtrlGetHandle($Button4) Then $DropAccept = $DROPEFFECT_NONE Else If $Msg = $WM_DROP Then Local $FileList = DragDropEvent_GetFile($wParam) MsgBox(262144, "DragDropEvent", StringReplace($FileList, "|", @LF)) EndIf $DropAccept = $DROPEFFECT_COPY EndIf Case DragDropEvent_IsText($wParam) If $Target = GUICtrlGetHandle($Button2) Or $Target = GUICtrlGetHandle($Button4) Then $DropAccept = $DROPEFFECT_NONE Else If $Msg = $WM_DROP Then MsgBox(262144, "DragDropEvent", DragDropEvent_GetText($wParam)) EndIf $DropAccept = $DROPEFFECT_COPY EndIf Case Else $DropAccept = $DROPEFFECT_NONE EndSelect Return $DropAccept Case $WM_DRAGOVER Local $X = DragDropEvent_GetX($wParam) Local $Y = DragDropEvent_GetY($wParam) Local $KeyState = DragDropEvent_GetKeyState($wParam) ToolTip("(" & $X & "," & $Y & "," & $KeyState & ")") Return $DropAccept Case $WM_DRAGLEAVE ToolTip("") EndSwitch EndFunc Zedna, Bitnugger and lee321987 1 2 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now