Jump to content

Drag and Drop command to out of focus window (ControlClick?)


Recommended Posts

I've been successful in using the ControlClick command to click at specific locations in an out of focus window, but now I need to expand upon it and perform a 'drag and drop' movement. Here are the specifics of what I have in mind:

  • Click on a specific location with x and y coordinates("mouse down command")
  • Drag to new location with different x and y coordinates ("mouse move command"?)
  • Release mouse at this new location ("mouse up command")
  • During the whole process, window stays out of focus and regular mouse cursor is not moved (similar to what ControlClick does)

Does anyone know if this is possible, through the use of ControlCommand, SendMessage or some other means? I'd be really grateful if someone could shed some light on this.

Link to comment
Share on other sites

Solved. In case anyone else needs this, I found an old script called "MouseClickPlus.au3" in another thread and was able to modify it to include two different coordinates, a starting coordinate and a final coordinate, and thus performing a drag.  It does this through user32.dll calls. Here's what the modified script looks like:

#cs ----------------------------------------------------------------------------
 AutoIt Version: 3.2.8.1
 Author:         someone
 Script Function:
    MouseClickPlus
#ce ----------------------------------------------------------------------------

Func _MouseClickPlus($Window, $Button="left", $X1=0, $Y1=0, $X2=0, $Y2=0, $Clicks=1)
  Local $MK_LBUTTON       =  0x0001
  Local $WM_LBUTTONDOWN   =  0x0201
  Local $WM_LBUTTONUP     =  0x0202

  Local $MK_RBUTTON       =  0x0002
  Local $WM_RBUTTONDOWN   =  0x0204
  Local $WM_RBUTTONUP     =  0x0205

  Local $WM_MOUSEMOVE     =  0x0200

  Local $i                = 0

  Select
  Case $Button = "left"
     $Button     =  $MK_LBUTTON
     $ButtonDown =  $WM_LBUTTONDOWN
     $ButtonUp   =  $WM_LBUTTONUP
  Case $Button = "right"
     $Button     =  $MK_RBUTTON
     $ButtonDown =  $WM_RBUTTONDOWN
     $ButtonUp   =  $WM_RBUTTONUP
  EndSelect

  If $X1 = 0 OR $Y1 = 0 Then
     $MouseCoord = MouseGetPos()
     $X1 = $MouseCoord[0]
     $Y1 = $MouseCoord[1]
  EndIf

  For $i = 1 to $Clicks
     DllCall("user32.dll", "int", "SendMessage", _
        "hwnd",  WinGetHandle( $Window ), _
        "int",   $WM_MOUSEMOVE, _
        "int",   0, _
        "long",  _MakeLong($X1, $Y1))

     DllCall("user32.dll", "int", "SendMessage", _
        "hwnd",  WinGetHandle( $Window ), _
        "int",   $ButtonDown, _
        "int",   $Button, _
        "long",  _MakeLong($X1, $Y1))

     DllCall("user32.dll", "int", "SendMessage", _
        "hwnd",  WinGetHandle( $Window ), _
        "int",   $WM_MOUSEMOVE, _
        "int",   0, _
        "long",  _MakeLong($X2, $Y2))

     DllCall("user32.dll", "int", "SendMessage", _
        "hwnd",  WinGetHandle( $Window ), _
        "int",   $ButtonUp, _
        "int",   $Button, _
        "long",  _MakeLong($X2, $Y2))
  Next
EndFunc

Func _MakeLong($LoWord,$HiWord)
  Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF))
EndFunc

 

Link to comment
Share on other sites

  • 2 months later...
  • 1 year later...

This is an old-ish topic but I wanted to leave a few notes after my own struggles:

  • Select software may expect WM_MOUSEMOVE's wParam of drag-while-pressed to be MK_LBUTTON (as per MSDN)
  • Select software may expect hwnd to be the destination control rather than the window itself.
  • As it is no longer 2003, it is OK to use _SendMessage+_WinAPI_MakeLong instead of DllCall+custom function.
  • If the drag operation triggers something time-consuming (suppose loading a big file), you may want _WinAPI_PostMessage instead of _SendMessage not to freeze your script for the duration.

Thus, a simplified version (LMB only) would look like so:

Func ControlMouseDrag($hwnd, $x1, $y1, $x2, $y2)
    _SendMessage($hwnd, $WM_MOUSEMOVE,   0, _WinAPI_MakeLong($x1, $y1))
    _SendMessage($hwnd, $WM_LBUTTONDOWN, 1, _WinAPI_MakeLong($x1, $y1))
    _SendMessage($hwnd, $WM_MOUSEMOVE,   1, _WinAPI_MakeLong($x2, $y2))
    _SendMessage($hwnd, $WM_LBUTTONUP,   0, _WinAPI_MakeLong($x2, $y2))
EndFunc

and then called with a handle from WinGetHandle or ControlGetHandle.
(as you might expect, when using ControlGetHandle, coordinates are relative to that control - see "ConctrolClick coords" in Window Info)

Edited by YellowAfterlife
it wasn't [code]
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...