Jump to content

[SOLVED] Determine Which Mouse Button was used to DRAG n DROPOP


Recommended Posts

Trying to determine which mouse button did the drag n drop. Have tried _isPressed logic, but it seems that once drag sequence starts it makes that irrelevant. Looks like there might be something in windows called keystate, which is when the drag starts. Not too swift on COM code, but looking for some guidance on where to proceed to look and if that is where the answer lies I will pursue. Have extracted some of my code into example included. I can today receive multiple dropped files, no problem, but would like to have different logic between left and right drag n drop, much like Windows does if dropping I guess on it's own objects, like explorer or desktop for example showing an option window on right mouse and drop only on left mouse. Thanks for any suggestions.

Opt("MustDeclareVars", 1) ; All variables must be declared
    Opt("TrayIconHide", 0) ; 0=Show the icon 1 = HIDE
    Opt("TrayIconDebug", 1) ; Show Debug line no
    Opt("GUIOnEventMode", 1) ; Use EVENT MODE
    Opt("MouseCoordMode", 1) ; 0= active window, 1=absolute screen, 2= Client area of active window
    Opt("WinTitleMatchMode", 2) ;  match any substring in Title
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <File.au3>   ; for pathsplit
    #Include <APIConstants.au3> ; To Support MultiDrop of files
    #include <WinAPIEx.au3>
    ; ========================================================================================
Global $hBARGui
Global $ButtonCID
Global $File
Global $szDrive, $szDir, $szFName, $szExt ; Separated elements on File PLACE'se
Global $__DropFiles, $iNoDrops, $iDropIdx
GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES")   ; For Handling FILE Drop Onto Buttons with Function WM_DROPFILES
    ; ======================================================================================================================================================================
    $hBARGui = GUICreate("Testdropwhichmouse", 200, 200, 200, 200, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW,$WS_EX_ACCEPTFILES))
    ; ======================================================================================================================================================================
        $ButtonCID = GUICtrlCreateButton("TestButton", 20, 50, 140, 60)
        ; ============================================================================================================
            GUICtrlSetState($ButtonCID, $GUI_DROPACCEPTED)  ; Permits file drops
    GUISetState(@SW_SHOW) ; Showing Bar, Buttons and Controls HERE
    GUISetOnEvent($GUI_EVENT_DROPPED, "_DROP_Item")   ;  Permits the File Drop on Buttons
    GUISetOnEvent($GUI_EVENT_CLOSE, "SAFE_EXIT")    ;  Exit on GUI close
While 1
    sleep(200)
WEnd

Func _DROP_Item() ;
#cs     Would like following capability *****************************
    If $RightMouseButtonDragDrop Then
        ... Do right mouse drop logic ...
    Elseif $LeftMouseButtonDragDrop Then
        ... Do left mouse dro logic ...
    Else
    Endif
#ce  *****************************************************************
    If $__DropFiles[0] > 0 Then  ; There is one or more files being dropped
                        $iNoDrops = $__DropFiles[0]  ; Number of Files
                        $iDropIdx = 1               ; Point to first file
                        Do         ;  All Dropped Files
                            $File = $__DropFiles[$iDropIdx]   ;  Get the FilePath
                            Local $aPathSplit = _PathSplit($File, $szDrive, $szDir, $szFName, $szExt)
                            GUICtrlSetData($ButtonCID,$szFName & "." & $szExt)
                            Sleep(5000)
                            $iDropIdx += 1   ; Do Next Dropped File
                        Until $iDropIdx -1 = $iNoDrops
                    EndIf
EndFunc   ;==> _DROP_Item

Func WM_DROPFILES($hWnd, $iMsg, $iwParam, $ilParam)   ;   From Forum - ? Author unknown
    #forceref $hWnd, $iMsg, $ilParam
    Local $aError[1] = [0], $aReturn
    Switch $iMsg
        Case $WM_DROPFILES
            $aReturn = _WinAPI_DragQueryFileEx($iwParam)
            If IsArray($aReturn) Then
                $__DropFiles = $aReturn
            Else
                $__DropFiles = $aError
            EndIf
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DROPFILES

Func Safe_Exit()
        Exit
EndFunc   ;==>Save_Exit

 

Edited by Bitpicker
SOLVED
Link to comment
Share on other sites

The drag and drop operation terminates when the pressed mouse button is released. This generates a $WM_LBUTTONUP or $WM_RBUTTONUP message. This message is send to the window where the drag and drop operation was iniatiated. Not to the target window (your AutoIt GUI).

The initiation window needs to know how to terminate the operation. To be able to do that it needs these mouse messages. Therefore the messages are send to the initiation window. If the target window accepts dropped files it sends a WM_DROPFILES message to the target window. If not it terminates the operation with an error.

Because the mouse messages are send to the initiation window and not the target window, _isPressed cannot detect the messages.

To detect the $WM_LBUTTONUP or $WM_RBUTTONUP message you can hook into the mouse events. Take a look at _WinAPI_SetWindowsHookEx and search for this function in the forum.

Link to comment
Share on other sites

Appreciate your input. The Drag is from Explorer window(Initiator), and my Gui Window(Target) does not know when the user will drag from an explorer to my Gui Window. Have looked at WinAPI_SetWindowsHookEx and could do that, but it seems I would have to do that AT ALL TIMES for MouseDown as well as Monitor for Mouse Position to detect "Drag" . It sounds then, like once a drag sequence starts then, all mouse messages are going to the initiator. I had thought by querying and noting mouse button status within some hover logic, then when Drop occurred check my note of which mouse button.

What I've read suggest that using Gui_Event_Dropped and WM_DROPFILES  I can not know what the keystate was prior to the drop. Is there anyway to get the keystate from the OnDragEnter or OnDragOver as they are supposed to have the mouse key data used to start the drag. Seems that is the only place to know the history at the time of the drop. I have found no AutoIt examples of getting the mouse data from the OnDrag structures after DROP. I admit I have no experience with COM coding. I see code from ProgAndy, which is pretty heavy, but do not see my way clear to getting Mouse key data.

Thanks for your input. I will keep pursueing.

Link to comment
Share on other sites

An easy workaround is of course to use two different drop areas. Whether the user has to choose between two different mouse buttons or two different drop areas seems to be the same.

Link to comment
Share on other sites

Good suggestion I had not considered, but does not really fit my application. I am not trying to duplicate the Window functions of Drag and Drop on my Autoit side. I am really just getting the file names from the Drop and then doing Autoit functions of Move or (hopefully, with user choice indicated) Copy to a Target Folder. Right now I do an Autoit FileMove, no problem. If I implemented your suggestion I would have to post the Target twice, once for Move and once for Copy and there are multiple targets possible in the GUI, so that would double that number. Not trying to put my applications problems on you, just explaining what I am doing. Would rather the user make that choice when he starts the drag, and it would be similar to the the choice he makes when doing a Windows drag with Left Mouse ,versus Right Mouse with the menu choice of Move or Copy. Not to say that the Windows choice is clear to everyone, most know that Right Mouse gives them a choice at the end. I would like to implement Left Mouse = Move, Right Mouse = Copy -or- maybe a Menu  with Move, Copy or Cancel implementing AUTOIT functions of FileMove or FileCopy.

Edited by Bitpicker
Found DragDropEvent UDF
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...