Jump to content

Mysterious Window Drag Delay


Go to solution Solved by NassauSky,

Recommended Posts

Has anyone worked with this before? The question is how to drag your own GUI and hide another as you're dragging yours while restoring/showing the other window when you're done dragging. In this example I'm instead using transparent since I didn't want my external window to disappear during my tests.

I tried this a few ways: (as per some remarked code)

  1. Registering a message GUIRegisterMsg
  2. _IsPressed

The problem is as I'm dragging, it either doesn't respond to the mouse down or mouse up events in a timely fashion.

 

#include <GUIConstants.au3>
#include <Misc.au3>
#include <WinAPISysWin.au3> ; For _SendMessage and Draggable
#include <WinAPIvkeysConstants.au3>

Global $dll = DllOpen("user32.dll")
Global Const $SC_DRAGMOVE = 0xF012
HotKeySet("+{ESC}", "_Quit")                    ; ^Ctrl !Alt +Shift

Run("Notepad.exe")
Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
WinWait("Notepad", "")
Global $hParent = WinGetHandle("Notepad", "")
HideOnDrag(255)

Func HideOnDrag($startTransparency)
    Global $hGUI = GUICreate("Example", Default, Default, Default,Default, $WS_POPUP, $WS_EX_TOPMOST)
    GUISetState()
    WinSetTrans($hParent, "", $startTransparency)

;~  GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")
;~  GUIRegisterMsg($WM_LBUTTONUP, "_WM_LBUTTONUP") ;Most times it doesn't respond

    Local $bMouseButtonDown = False
    Do
        Sleep(5)
        Switch GUIGetMsg()
            Case $GUI_EVENT_PRIMARYDOWN
                WinSetTrans($hParent,"",50)
                 ConsoleWrite("D")
                 _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
             Case $GUI_EVENT_PRIMARYUP
                 WinSetTrans($hParent,"",250)
                 ConsoleWrite("U")
        EndSwitch
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc

;~ Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam) ; Make Draggable
;~     ConsoleWrite("D")
;~  WinSetTrans($hParent,"",50)
;~     _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
;~     Return _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
;~ EndFunc   ;==>_WM_LBUTTONDOWN

;~ Func _WM_LBUTTONUP($hWnd, $iMsg, $wParam, $lParam)   ; Make Draggable
;~     ConsoleWrite("U")
;~  WinSetTrans($hParent,"",255)
;~     Return _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
;~ EndFunc   ;==>_WM_LBUTTONDOWN

;~ Func _IsMouseButtonDown()
;~  If _IsPressed(01, $dll) Then
;~      Return True
;~  EndIf
;~  Return False
;~ EndFunc

Func _Quit()
    SplashTextOn("Notice", "Closing")
        DllClose($dll)
        Sleep(200)
    SplashOff()
    Exit
EndFunc   ;==>_Quit

 

 

Edited by NassauSky
Link to comment
Share on other sites

  • Solution
Posted (edited)

@Melba23 you mentioned this link in the past and I tried a few ways there but just couldn't get it right.   After some persistence I finally got it:

 

#include <GUIConstants.au3>
#include <Misc.au3>

HotKeySet("+{ESC}", "_Quit")            ; ^Ctrl !Alt +Shift
Global $dll = DllOpen("user32.dll")
Global Const $SC_DRAGMOVE = 0xF012
Global $bGetNext = False

Run("Notepad.exe")
Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
WinWait("Notepad", "")
Global $hParent = WinGetHandle("Notepad", "")
HideOnDrag(255)

Func HideOnDrag($startTransparency)
    Global $hGUI = GUICreate("Hidden Title", Default, Default, Default,Default, $WS_POPUP, $WS_EX_TOPMOST)
        GUISetBkColor(0x0000BB)
    GUISetState()
    WinSetTrans($hParent, "", $startTransparency)

    GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
    Do
        Sleep(5)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc

Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    If $hWnd = $hGui and $iMsg = $WM_NCHITTEST then
        If _IsMouseButtonDown() Then
            ConsoleWrite("Down" & @CRLF)
            WinSetTrans($hParent,"",20)
            $bGetNext = True
        ElseIf $bGetNext Then
            ConsoleWrite("Up" & @CRLF)
            WinSetTrans($hParent,"",250)
            $bGetNext = False
        EndIf
        Return $HTCAPTION
    EndIf
EndFunc

Func _IsMouseButtonDown()
    If _IsPressed(01, $dll) Then
        Return True
    EndIf
    Return False
EndFunc

Func _Quit()
    SplashTextOn("Notice", "Closing")
        DllClose($dll)
        Sleep(200)
    SplashOff()
    Exit
EndFunc   ;==>_Quit

 

Edited by NassauSky
Link to comment
Share on other sites

 

#include <GUIConstants.au3>
#include <Misc.au3>
#include <WinAPISysWin.au3> ; For _SendMessage And Draggable
#include <WinAPIvkeysConstants.au3>

Global $dll = DllOpen("user32.dll")
Global Const $SC_DRAGMOVE = 0xF012

Run("Notepad.exe")
Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
WinWait("Notepad", "")
Global $hParent = WinGetHandle("Notepad", "")
HideOnDrag(255)

;----------------------------------------------------------------------------------------
Func HideOnDrag($startTransparency)
    Global $hGUI = GUICreate("Example", Default, Default, Default, Default, $WS_POPUP, $WS_EX_TOPMOST)
    GUISetState()
    WinSetTrans($hParent, "", $startTransparency)
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                _Quit()
        EndSwitch
        _IsDrag()
    WEnd
EndFunc   ;==>HideOnDrag
;----------------------------------------------------------------------------------------
Func _IsDrag()
    Local $hDLL = DllOpen("user32.dll")

    If _IsPressed("01", $hDLL) Then ; 01 Left mouse button
        WinSetTrans($hParent, "", 50)
        While _IsPressed("01", $hDLL)
            _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
            Sleep(10)
        WEnd
    EndIf

    WinSetTrans($hParent, "", 255)
    DllClose($hDLL)
EndFunc   ;==>_IsDrag

;----------------------------------------------------------------------------------------
Func _Quit()
    SplashTextOn("Notice", "Closing")
    Sleep(200)
    SplashOff()
    Exit
EndFunc   ;==>_Quit
;----------------------------------------------------------------------------------------

 

I know that I know nothing

Link to comment
Share on other sites

Posted (edited)

@ioa747 Not bad that's now my 2nd option.  It's nice to have that option if I also wanted the external window to disappear while I'm over the 2nd window.  The way I'm doing it now is just having it disappear when I drag my own GUI.

 

Thanks!

Edited by NassauSky
Link to comment
Share on other sites

How about a third option :

#include <GUIConstants.au3>
#include <WinAPIConstants.au3>
#include <WinAPISys.au3>

Global Const $tagMSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"
Global $hHook, $hGUI, $hParent

Run("Notepad")
$hParent = WinWait("[CLASS:Notepad]")
HideOnDrag()

Func HideOnDrag()
  $hGUI = GUICreate("ControlParent", Default, Default, Default, Default, $WS_POPUP, $WS_EX_TOPMOST + $WS_EX_CONTROLPARENT)
  GUISetState()

  Local $hStub = DllCallbackRegister(WinProc, "lresult", "int;wparam;lparam")
  $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hStub), _WinAPI_GetModuleHandle(0))

  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd
  _WinAPI_UnhookWindowsHookEx($hHook)
  DllCallbackFree($hStub)
  WinClose($hParent)
EndFunc   ;==>HideOnDrag

Func WinProc($iMsg, $wParam, $lParam)
  Local Static $bSet = False
  Local $tMSLLHOOKSTRUCT
  If $iMsg = 0 Then
    If $wParam = $WM_LBUTTONDOWN Then
      $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $lParam)
      $aPos = WinGetPos($hGUI)
      If $tMSLLHOOKSTRUCT.X >= $aPos[0] And $tMSLLHOOKSTRUCT.X <= $aPos[0] + $aPos[2] And _
          $tMSLLHOOKSTRUCT.Y >= $aPos[1] And $tMSLLHOOKSTRUCT.Y <= $aPos[1] + $aPos[3] Then
        ConsoleWrite("down" & @CRLF)
        WinSetTrans($hParent, "", 70)
        $bSet = True
      EndIf
    ElseIf $wParam = $WM_LBUTTONUP And $bSet Then
      ConsoleWrite("up" & @CRLF)
      WinSetTrans($hParent, "", 255)
      $bSet = False
    EndIf
  EndIf
  Return _WinAPI_CallNextHookEx($hHook, $iMsg, $wParam, $lParam)
EndFunc   ;==>WinProc

 

Link to comment
Share on other sites

get a fourth option in addition:

; https://www.autoitscript.com/forum/topic/211735-mysterious-window-drag-delay

#include <GUIConstants.au3>
#include <Misc.au3>

Run("Notepad.exe")
Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
WinWait("Notepad", "")
Global $hParent = WinGetHandle("Notepad", "")
HideOnDrag(255)

;----------------------------------------------------------------------------------------
Func HideOnDrag($startTransparency)
    Global $hGUI = GUICreate("Example", 400, 400, -1, -1, $WS_POPUP, $WS_EX_TOPMOST)
    GUISetState()
    WinSetTrans($hParent, "", $startTransparency)
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                _Quit()
        EndSwitch
        _IsDrag()
    WEnd
EndFunc   ;==>HideOnDrag
;----------------------------------------------------------------------------------------
Func _IsDrag()
    Local $hDLL = DllOpen("user32.dll")

    If Not IsMouseOverWin($hGUI) Or Not WinActive($hGUI) Then Return
    Local $aMPos, $aWPos, $aDif[2]

    If _IsPressed("01", $hDLL) Then ; 01 Left mouse button
        $aMPos = MouseGetPos()
        $aWPos = WinGetPos($hGUI)
        $aDif[0] = $aMPos[0] - $aWPos[0]
        $aDif[1] = $aMPos[1] - $aWPos[1]

        While _IsPressed("01", $hDLL)
            $aMPos = MouseGetPos()
            WinMove($hGUI, "", $aMPos[0] - $aDif[0], $aMPos[1] - $aDif[1])
            If WinExists($hParent) Then
                If IsWinOverWin($hGUI, $hParent) Then
                    WinSetTrans($hParent, "", 50)
                Else
                    WinSetTrans($hParent, "", 255)
                EndIf
            EndIf
            Sleep(10) ;***
        WEnd
        WinSetTrans($hParent, "", 255)
    EndIf

    DllClose($hDLL)
EndFunc   ;==>_IsDrag
;----------------------------------------------------------------------------------------
Func IsMouseOverWin($hWnd)
    Local $aMPos = MouseGetPos()
    Local $aWPos = WinGetPos($hWnd)
    If $aMPos[0] > $aWPos[0] And $aMPos[1] > $aWPos[1] And $aMPos[0] < $aWPos[0] + $aWPos[2] And $aMPos[1] < $aWPos[1] + $aWPos[3] Then
        Return True ; Mouse is over Windows
    EndIf
    Return False ; Mouse is not over Windows
EndFunc   ;==>IsMouseOverWin
;----------------------------------------------------------------------------------------
Func IsWinOverWin($hWnd1, $hWnd2)
    Local $rect1 = WinGetPos($hWnd1)
    Local $rect2 = WinGetPos($hWnd2)

    If $rect2[0] < $rect1[0] + $rect1[2] And _
            $rect2[0] + $rect2[2] > $rect1[0] And _
            $rect2[1] < $rect1[1] + $rect1[3] And _
            $rect2[1] + $rect2[3] > $rect1[1] Then
        Return True ; "Window 1 is over Window 2"
    Else
        Return False ; "Window 1 is not over Window 2"
    EndIf
EndFunc   ;==>IsWinOverWin
;----------------------------------------------------------------------------------------
Func _Quit()
    SplashTextOn("Notice", "Closing")
    Sleep(200)
    SplashOff()
    Exit
EndFunc   ;==>_Quit
;----------------------------------------------------------------------------------------

 

Edited by ioa747
UpDate

I know that I know nothing

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...