Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

ControlClick Dragging


  • Please log in to reply
3 replies to this topic
AHK GUEST
  • Guests
  • Last active:
  • Joined: --
I have been using controlsend and controlclick to make a macro that works on a minimized window, is there a way to send a MouseClickDrag to a minimized window? I have tried
WinGet,SBID, ID,A
Controlclick, , ahk_id %SBID%,, left, 1, D NA x35 y487
sleep, 1500
Controlclick, , ahk_id %SBID%,, left, 1, U NA x200 y635
Hope I explained that well, any help would be appreciated.

Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008
Im pretty sure there isn't but I may be wrong. Ill do some more research and post if I find anything.

EDIT: I found nothing to sugest this is posible.
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run

AHK GUEST
  • Guests
  • Last active:
  • Joined: --
That's what I feared, oh well thanks for your help.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
ControlClick only sends WM_'BUTTONDOWN/UP messages. A long while ago I wrote ControlMouseMove, but I'm not sure if I ever posted it. I did post some of the code in this thread, in which I basically demonstrated how to do a proper "ControlDoubleClick".

The example "synchronises" left click-drag between multiple "Untitled - Paint" windows. It isn't perfect and doesn't work on the toolbar, but demonstrates the function nicely. Simply run the script, open a few Paint windows and start drawing.
#NoEnv

WINTITLE = Untitled - Paint

~LButton::
    CoordMode, Mouse, Screen
    MouseGetPos, x, y, win            ; get mouse pos,
    WinGetPos, wx, wy,,, ahk_id %win%
    x -= wx, y -= wy                  ; relative to mouse window
    ifWinNotExist, %WINTITLE% ahk_id %win%
        return
    WinGet, w, List, %WINTITLE%
    Loop, %w%
        if (w%A_Index% != win)
            ControlClick, X%x% Y%y%, % "ahk_id " w%A_Index%,,,, D
    Loop { ; loop to simulate drag
        if !GetKeyState("LButton","P")
            break
        MouseGetPos, x, y   ; get mouse pos,
        WinGetPos, wx, wy,,, ahk_id %win%
        x -= wx, y -= wy    ; relative to mouse window
        Loop, %w%
            if (w%A_Index% != win)
                c%A_Index% := ControlMouseMove(x, y, c%A_Index%, "ahk_id " w%A_Index%, "", "L K")
                ; c%A_Index% is used to simulate mouse capture.
        Sleep, 10
    }
    Loop, %w%
        if (w%A_Index% != win)
        {
            if c%A_Index%
            {   ; window coords -> control coords
                ControlGetPos, cx, cy,,,, % "ahk_id " c%A_Index%
                x -= cx, y -= cy
                ; simulate mouse capture
                w%A_Index% := c%A_Index%
                c%A_Index% =
            }
            ControlClick, X%x% Y%y%, % "ahk_id " w%A_Index%,,,, U
        }
return


; Accepts coords relative to the specified window.
;   X and Y MUST be specified, since current actual mouse location is irrelevant.
;   Control:
;       This can be, ClassNN, the name/text of the control, or a control HWND
;       (which must be a child of the target window.)
;       If a control HWND is specified, X and Y will be relative to the target
;       window, not the child control.
;   Options:
;       a string of letters (spaces are optional) indicating which buttons("LMR X1 X2")/keys("S C"=shift,control) should be considered pressed.
;       K: use actual key state for Shift and Ctrl.
;   Return value:
;       The hwnd of the control which was sent the mousemove message.
;       Pass this to the Control parameter to simulate mouse capture.
; Based on AutoHotkey::script2.cpp::ControlClick()
ControlMouseMove(X, Y, Control="", WinTitle="", WinText="", Options="", ExcludeTitle="", ExcludeText="")
{
    static EnumChildFindPointProc=0
    if !EnumChildFindPointProc
        EnumChildFindPointProc := RegisterCallback("EnumChildFindPoint","Fast")
    
    if !(target_window := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText))
        return false
    if Control
    {
        if Control is integer
            Control_is_hwnd := IsWindowChildOf(Control, target_window)
        
        if Control_is_hwnd
        {
            ; If %Control% specifies a control hwnd, send it the mouse move,
            ; but use coords relative to the window specified by WinTitle.
            ; This can be used to more easily simulate mouse capture.
            control_window := Control
            VarSetCapacity(rect, 16)
            DllCall("GetWindowRect","uint",target_window,"uint",&rect)
            VarSetCapacity(child_rect, 16)
            DllCall("GetWindowRect","uint",control_window,"uint",&child_rect)
            X -= NumGet(child_rect,0,"int") - NumGet(rect,0,"int")
            Y -= NumGet(child_rect,4,"int") - NumGet(rect,4,"int")
        }
        else
            ControlGet, control_window, Hwnd,, %Control%, ahk_id %target_window%
    }
    if (!control_window)
    {
        VarSetCapacity(rect, 16)
        DllCall("GetWindowRect","uint",target_window,"uint",&rect)
        VarSetCapacity(pah, 36, 0)
        NumPut(X + NumGet(rect,0,"int"), pah,0,"int")
        NumPut(Y + NumGet(rect,4,"int"), pah,4,"int")
        DllCall("EnumChildWindows","uint",target_window,"uint",EnumChildFindPointProc,"uint",&pah)
        control_window := NumGet(pah,24) ? NumGet(pah,24) : target_window
        DllCall("ScreenToClient","uint",control_window,"uint",&pah)
        X:=NumGet(pah,0,"int"), Y:=NumGet(pah,4,"int")
    }
    wParam :=  (InStr(Options,"L") ? 0x1 : 0) || (InStr(Options,"M") ? 0x10 : 0) || (InStr(Options,"R") ? 0x2 : 0)
            || (InStr(Options,"X1") ? 0x20 : 0) || (InStr(Options,"X2") ? 0x40 : 0)
            || (InStr(Options,"S") ? 0x4 : 0) || (InStr(Options,"C") ? 0x8 : 0)
            || (InStr(Options,"K") ? (GetKeyState("Shift") ? 0x4:0)|(GetKeyState("Control") ? 0x8:0) : 0)
    PostMessage, 0x200, wParam, (x & 0xFFFF) | ((y & 0xFFFF)<<16),, ahk_id %control_window%
    return control_window
}

IsWindowChildOf(aChild, aParent)
{
    static EnumChildFindHwndProc=0
    if !EnumChildFindHwndProc
        EnumChildFindHwndProc := RegisterCallback("EnumChildFindHwnd","Fast")
    VarSetCapacity(lParam,8,0), NumPut(aChild,lParam,0)
    DllCall("EnumChildWindows","uint",aParent,"uint",EnumChildFindHwndProc,"uint",&lParam)
    return NumGet(lParam,4)
}
EnumChildFindHwnd(aWnd, lParam)
{
    if (aWnd = NumGet(lParam+0))
    {
        NumPut(1, lParam+4)
        return false
    }
    return true
}

; Ported from AutoHotkey::script2.cpp::EnumChildFindPoint()
EnumChildFindPoint(aWnd, lParam)
{
    if !DllCall("IsWindowVisible","uint",aWnd)
        return true
    VarSetCapacity(rect, 16)
    if !DllCall("GetWindowRect","uint",aWnd,"uint",&rect)
        return true
    pt_x:=NumGet(lParam+0,0,"int"), pt_y:=NumGet(lParam+0,4,"int")
    rect_left:=NumGet(rect,0,"int"), rect_right:=NumGet(rect,8,"int")
    rect_top:=NumGet(rect,4,"int"), rect_bottom:=NumGet(rect,12,"int")
    if (pt_x >= rect_left && pt_x <= rect_right && pt_y >= rect_top && pt_y <= rect_bottom)
    {
        center_x := rect_left + (rect_right - rect_left) / 2
        center_y := rect_top + (rect_bottom - rect_top) / 2
        distance := Sqrt((pt_x-center_x)**2 + (pt_y-center_y)**2)
        update_it := !NumGet(lParam+24)
        if (!update_it)
        {
            rect_found_left:=NumGet(lParam+8,0,"int"), rect_found_right:=NumGet(lParam+8,8,"int")
            rect_found_top:=NumGet(lParam+8,4,"int"), rect_found_bottom:=NumGet(lParam+8,12,"int")
            if (rect_left >= rect_found_left && rect_right <= rect_found_right
                && rect_top >= rect_found_top && rect_bottom <= rect_found_bottom)
                update_it := true
            else if (distance < NumGet(lParam+28,0,"double")
                && (rect_found_left < rect_left || rect_found_right > rect_right
                 || rect_found_top < rect_top || rect_found_bottom > rect_bottom))
                 update_it := true
        }
        if (update_it)
        {
            NumPut(aWnd, lParam+24)
            DllCall("RtlMoveMemory","uint",lParam+8,"uint",&rect,"uint",16)
            NumPut(distance, lParam+28, 0, "double")
        }
    }
    return true
}