Jump to content

[Solved] Drag and Drop with UAC


Trong
 Share

Recommended Posts

#RequireAdmin
#include <WinAPISys.au3>
#include <WindowsConstants.au3>

_WinAPI_ChangeWindowMessageFilterEx ( $hWnd, $iMsg, $iAction )

;_WinAPI_ChangeWindowMessageFilterEx( $hWnd, $WM_DROPFILES, $MSGFLT_ALLOW)
;_WinAPI_ChangeWindowMessageFilterEx( $hWnd, $WM_COPYDATA, $MSGFLT_ALLOW)
;_WinAPI_ChangeWindowMessageFilterEx( $hWnd, $WM_COPYGLOBALDATA, $MSGFLT_ALLOW)

; $WM_COPYDATA = 0x004A - $WM_DROPFILES = 0x0233 - $WM_COPYGLOBALDATA = 0x0049 - $MSGFLT_ALLOW = 1 - $MSGFLT_DISALLOW = 2

Example:

#RequireAdmin
Opt("TrayAutoPause", 0)
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
Global $AppWindows = GUICreate("Dao Van Trong  - Trong.CF", 320, 50, -1, -1, BitOR($WS_BORDER, $WS_POPUP), BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST, $WS_EX_WINDOWEDGE))
Global $AppTitle = GUICtrlCreateLabel("=== Drag and drop UAC ===", 56, 0, 210, 25, $SS_CENTERIMAGE, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetFont(-1, 9, 800)
Global $AppTask = GUICtrlCreateLabel("Drag and drop files here ", 56, 24, 220, 17, $SS_CENTERIMAGE, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetFont(-1, 9, 500)
Global $xCLOSE = GUICtrlCreateButton("X", 308, 0, 12, 12, BitAND($BS_MULTILINE, $BS_VCENTER, $BS_FLAT))
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUISetState(@SW_SHOW)
_WinAPI_ChangeWindowMessageFilterEx($AppWindows, $WM_DROPFILES, $MSGFLT_ALLOW)
_WinAPI_ChangeWindowMessageFilterEx($AppWindows, $WM_COPYDATA, $MSGFLT_ALLOW)
_WinAPI_ChangeWindowMessageFilterEx($AppWindows, $WM_COPYGLOBALDATA, $MSGFLT_ALLOW)
Global $__aDropFiles
GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES")
Local $nMsg
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_DROPPED
            If $__aDropFiles[0] > 0 Then
                For $i = 1 To $__aDropFiles[0]
                    ConsoleWrite($__aDropFiles[$i] & @CRLF)
                    GUICtrlSetData($AppTask, $__aDropFiles[$i])
                Next
            EndIf
        Case $GUI_EVENT_CLOSE, $xCLOSE
            Exit
    EndSwitch
WEnd
Func WM_DROPFILES($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $ilParam
    Switch $iMsg
        Case $WM_DROPFILES
            Local $aReturn = _WinAPI_DragQueryFileEx($iwParam)
            If IsArray($aReturn) Then
                $__aDropFiles = $aReturn
            Else
                Local $aError[1] = [0]
                $__aDropFiles = $aError
            EndIf
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DROPFILES

 

Edited by Trong
Example

Regards,
 

Link to comment
Share on other sites

@Trong: would you mind restating (in your first post) what the problem is that you've solved?

_WinAPI_ChangeWindowMessageFilterEx appears to be very useful ... but are you working only with AU3 scripts? ... or have you tried it with other applications?  If so, what is your method for doing that?

Thanks for opening this topic.

 

Link to comment
Share on other sites

His problem was, he could not drop files on his GUI's ListView. Script requires Admin privileges (#RequireAdmin). I found after @AdmiralAlex post this solution:

;found https://www.autoitscript.com/forum/topic/124406-drag-and-drop-with-uac/
#RequireAdmin
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
Opt("GuiOnEventMode", 1)

Global $DropFilesArr[1]
Global $FilesAllowedMask[4] = [3, ".txt", ".exe", "D"]

$mainFrm = GUICreate("Drop Multiple Files to LV Demo", 500, 400, -1, -1, -1, $WS_EX_ACCEPTFILES+$WS_EX_TOPMOST)
_ChangeWindowMessageFilterEx($mainFrm, 0x233, 1)
_ChangeWindowMessageFilterEx($mainFrm, $WM_COPYDATA, 1)
_ChangeWindowMessageFilterEx($mainFrm, 0x0049, 1)

GUISetOnEvent($GUI_EVENT_CLOSE, "MainEvents")
GUISetOnEvent($GUI_EVENT_DROPPED, "MainEvents")

GUIRegisterMsg(0x233, "WM_DROPFILES_FUNC")

GUICtrlCreateLabel("Drag to the List View some file(s)", 60, 20)

$ListView = GUICtrlCreateListView("Col1", 50, 50, 400, 300, -1, $WS_EX_CLIENTEDGE)
GUICtrlSendMsg(-1, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_HEADERDRAGDROP, $LVS_EX_HEADERDRAGDROP)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)

GUISetState()

While 1
    Sleep(100)
WEnd

Func MainEvents()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_DROPPED
            $NotValidExtPath = ""
            $ValidExtCount = 0
            For $i = 1 To UBound($DropFilesArr)-1
                $ValidExtCount += 1
                GUICtrlCreateListViewItem($DropFilesArr[$i], $ListView)
            Next
            If $ValidExtCount > 0 Then GUICtrlSendMsg($ListView, $LVM_SETCOLUMNWIDTH, 0, -1)
    EndSwitch
EndFunc

Func _IsValidExt($sPath)
    For $i = 1 To $FilesAllowedMask[0]
        If StringRight($sPath, 4) = $FilesAllowedMask[$i] And _
            Not StringInStr(FileGetAttrib($sPath), $FilesAllowedMask[$i]) Then Return True
    Next
    Return False
EndFunc

Func WM_DROPFILES_FUNC($hWnd, $msgID, $wParam, $lParam)
    Local $nSize, $pFileName
    Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
    For $i = 0 To $nAmt[0] - 1
        $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0)
        $nSize = $nSize[0] + 1
        $pFileName = DllStructCreate("char[" & $nSize & "]")
        DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", _
            DllStructGetPtr($pFileName), "int", $nSize)
        ReDim $DropFilesArr[$i + 2]
        $DropFilesArr[$i+1] = DllStructGetData($pFileName, 1)
        $pFileName = 0
    Next
    $DropFilesArr[0] = UBound($DropFilesArr)-1
EndFunc

Func _ChangeWindowMessageFilterEx($hWnd, $iMsg, $iAction)
    Local $aCall = DllCall("user32.dll", "bool", "ChangeWindowMessageFilterEx", _
            "hwnd", $hWnd, _
            "dword", $iMsg, _
            "dword", $iAction, _
            "ptr", 0)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return 1
EndFunc

When you remove Lines 12-14 which uses the func _ChangeWindowMessageFilterEx you have the problem similar to @Tong's. When you want to use this func in a other programming language you have to implement the DLL-call for User32.dll.

Link to comment
Share on other sites

His problem was, he could not drop files on his GUI's ListView. Script requires Admin privileges (#RequireAdmin). I found after @AdmiralAlex post this solution:

[..]
    Local $aCall = DllCall("user32.dll", "bool", "ChangeWindowMessageFilterEx", _
  [...]

Windows 7 or later Only ChangeWindowMessageFilterEx 

XP and All :

#include <WinAPISys.au3>
_WinAPI_ChangeWindowMessageFilterEx ( $hWnd, $iMsg, $iAction )


 

Regards,
 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...