Jump to content

how to drag a window without titlebar


Go to solution Solved by mikell,

Recommended Posts

  • Moderators

Allow2010,

In mikell's very clever script the GUIGetCursorInfo call should now not fail because the _GetBorder function containing it is not called unless the cursor is actually over the GUI. The _SetCursor function checks using the WindowFromPoint API call and only calls the _GetBorder function if this is the case.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

The error checking was needed for the GUIGetCursorInfo() in the _GetBorder() func, but my code now uses MouseGetPos instead

Anyway - though it's useless - for a peaceful mind you may add the "If @error Then Return" if you want  smile.gif

Edit (the emoticon) biggrin.png

Edited by mikell
Link to comment
Share on other sites

Thank you all for your help.

 

I still could not find a working solution for my Problem, because i use a transparent gui and all clicks inside the gui go right throug the gui to the programm under my gui (for some strange reason th gui is really transparent:-)) when used in combination with this code.

 

Does anyone have an idea how to fix this?

 

Here is my example:

 

 
#include <GuiConstantsEx.au3>
#include <Windowsconstants.au3>
#include <SendMessage.au3>
#include <WINAPI.au3>

HotKeySet("{ESC}", "On_Exit")

; Set distance from edge of window where resizing is possible
Global Const $iMargin = 4
; Set max and min GUI sizes
Global Const $iGUIMinX = 50, $iGUIMinY = 50, $iGUIMaxX = 300, $iGUIMaxY = 300

Global $tPoint = DllStructCreate("struct; long X;long Y; endstruct")

$exstyle = $WS_EX_LAYERED + $WS_EX_TOPMOST;not working but transparent
;$exstyle = -1;working but not transparent

$hgui = GUICreate("Y", 100, 100, -1, -1, $WS_POPUP, $exstyle)
;$display = GUICtrlCreateLabel("Test", 10, 10, -1, -1, -1, $GUI_WS_EX_PARENTDRAG);also working ok when i just size the label to the window size, but i can not use resizing
$display = GUICtrlCreateLabel("Test", 10, 10);so there is something to see:-)
GUICtrlSetColor(-1, 0xFF0000)

GUICtrlSetBkColor(-1, -2);transparent
GUISetBkColor(0xABCDEF);transparent
_WinAPI_SetLayeredWindowAttributes($hgui, 0xABCDEF);transparent

GUISetState()

; Register message handlers
GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN") ; For resize/drag
GUIRegisterMsg($WM_MOUSEMOVE, "_SetCursor") ; For cursor type change
GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO") ; For GUI size limits

While 1
    Sleep(10)
WEnd


; Check cursor type and resize/drag window as required
Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    Local $iCursorType = _GetBorder()
    If $iCursorType > 0 Then ; Cursor is set to resizing style
        $iResizeType = 0xF000 + $iCursorType
        _SendMessage($hgui, $WM_SYSCOMMAND, $iResizeType, 0)
    Else
        Local $aCurInfo = GUIGetCursorInfo($hgui)
        If $aCurInfo[4] = 0 Then ; Mouse not over a control
            DllCall("user32.dll", "int", "ReleaseCapture")
            _SendMessage($hgui, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
        EndIf
    EndIf
EndFunc   ;==>_WM_LBUTTONDOWN

; Set cursor to correct resizing form if mouse is over a border
Func _SetCursor()
    DllStructSetData($tPoint, "x", MouseGetPos(0))
    DllStructSetData($tPoint, "y", MouseGetPos(1))
    Local $aResult = DllCall("user32.dll", "hwnd", "WindowFromPoint", "struct", $tPoint)
    If $aResult[0] <> $hgui Then Return

    Local $iCursorID
    Switch _GetBorder()
        Case 0
            $iCursorID = 2 ; arrow
        Case 1, 2
            $iCursorID = 13 ; SIZEWE
        Case 3, 6
            $iCursorID = 11 ; SIZENS
        Case 5, 7
            $iCursorID = 10 ; SIZENESW
        Case 4, 8
            $iCursorID = 12 ; SIZENWSE
    EndSwitch
    GUISetCursor($iCursorID, 1)
EndFunc   ;==>_SetCursor

; Determines if mouse cursor over a border
Func _GetBorder()
    Local $aMPos = MouseGetPos()
    Local $aWinPos = WinGetPos($hgui)
    Local $iSide = 0
    Local $iTopBot = 0
    If $aMPos[0] < $aWinPos[0] + $iMargin Then $iSide = 1
    If $aMPos[0] > $aWinPos[0] + $aWinPos[2] - $iMargin Then $iSide = 2
    If $aMPos[1] < $aWinPos[1] + $iMargin Then $iTopBot = 3
    If $aMPos[1] > $aWinPos[1] + $aWinPos[3] - $iMargin Then $iTopBot = 6
    Return $iSide + $iTopBot
EndFunc   ;==>_GetBorder

; Set min and max GUI sizes
Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam)
    $tMinMaxInfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
    DllStructSetData($tMinMaxInfo, 7, $iGUIMinX)
    DllStructSetData($tMinMaxInfo, 8, $iGUIMinY)
    DllStructSetData($tMinMaxInfo, 9, $iGUIMaxX)
    DllStructSetData($tMinMaxInfo, 10, $iGUIMaxY)
    Return 0
EndFunc   ;==>_WM_GETMINMAXINFO

Func On_Exit()
    Exit
EndFunc   ;==>On_Exit
Edited by Melba23
Added code tags
Link to comment
Share on other sites

Show window menu ==> Alt+Space

Select second menu entry (in German it is Verschieben, should be move in English)

Then: left click and hold and then move the mouse

Release mouse key when in desired position

Hope this helps

 

just a little correction:

that is not to be used exactly that way (at least on my system)...

change the following 2 steps from above:

  • Then: left click and hold and then move the mouse
  • Release mouse key when in desired position

with this:

  • Then:use arrows keys on the keyboard to move the window
  • hit Enter to fix new position

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Wow, how by hell will you resize a transparent gui by dragging its invisible borders ?!?

And to move a transparent gui the best way is the solution by jguinch in post #2

 

You are right, sizing while transparent is not possible, but the window is not always transparent :-)

The example was simplified...

Yes using $GUI_WS_EX_PARENTDRAG is easy and will work, but i still have to exactly hit the text, i can not drag when the mouse is in an transperent area between letters...its hard to tell the user that he hast to click inside a letter in a changing text :-(

Link to comment
Share on other sites

@exit

You can drag the window even when not exactly clicking the text (i mean by clicking transparent area between letters)?

I am going crazy...please post or PM me the script that you have verified to work on your system and if possible some info about your system...Thanks !

Link to comment
Share on other sites

ok, mystery solved, but still no solution:-(

Everything works just fine when run on a real window7 machine.

It does not work correct on a Windows 8.1 machine or on a Windows 7 Machine used by RemoteDesktop or Teamviewer from the Win 8.1 machine...

So any ideas on that :-)

Link to comment
Share on other sites

Chimp, did you try this with the op's transparent gui ? :idiot:

 

no, I didn't because I know that it doesn't work on that kind of gui.... :idiot:

 

@chimp         On my System both works

even if you click on client area of the window? (not on the title bar)

if it works only when you click on the title bar, then that's just a normal Drag, not the Alt+Space+Move way

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

 

OK I understand

What about this one ?

#include <GuiConstantsEx.au3>
#include <Windowsconstants.au3>
#include <SendMessage.au3>

 HotKeySet("{ESC}", "On_Exit")
 
 ; Set distance from edge of window where resizing is possible
 Global Const $iMargin = 4
 ; Set max and min GUI sizes
 Global Const $iGUIMinX = 50, $iGUIMinY = 50, $iGUIMaxX = 300, $iGUIMaxY = 300

Global $tPoint = DllStructCreate("struct; long X;long Y; endstruct")

 ; Create GUI
 $hGUI = GUICreate("Y", 100, 100, -1, -1, $WS_POPUP)
 GUISetBkColor(0x00FF00)
 GUISetState()
 
 ; Register message handlers
 GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")     ; For resize/drag
 GUIRegisterMsg($WM_MOUSEMOVE, "_SetCursor")            ; For cursor type change
 GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO") ; For GUI size limits
 
 While 1
     Sleep(10)
 WEnd

 
 ; Check cursor type and resize/drag window as required
 Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
     Local $iCursorType = _GetBorder()
     If $iCursorType > 0 Then ; Cursor is set to resizing style
         $iResizeType = 0xF000 + $iCursorType
         _SendMessage($hGUI, $WM_SYSCOMMAND, $iResizeType, 0)
     Else
         Local $aCurInfo = GUIGetCursorInfo($hGUI)
         If $aCurInfo[4] = 0 Then ; Mouse not over a control
             DllCall("user32.dll", "int", "ReleaseCapture")
             _SendMessage($hGUI, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
         EndIf
    EndIf
 EndFunc ;==>WM_LBUTTONDOWN
 
 ; Set cursor to correct resizing form if mouse is over a border
 Func _SetCursor()
    DllStructSetData($tPoint, "x", MouseGetPos(0))
    DllStructSetData($tPoint, "y", MouseGetPos(1))
    Local $aResult = DllCall("user32.dll", "hwnd", "WindowFromPoint", "struct", $tPoint)
    If $aResult[0] <> $hGUI Then Return

    Local $iCursorID
     Switch _GetBorder()
         Case 0
             $iCursorID = 2  ; arrow
         Case 1, 2
             $iCursorID = 13  ; SIZEWE
         Case 3, 6
             $iCursorID = 11  ; SIZENS
         Case 5, 7
             $iCursorID = 10  ; SIZENESW
         Case 4, 8
             $iCursorID = 12   ; SIZENWSE
     EndSwitch
     GUISetCursor($iCursorID, 1)
 EndFunc ;==>SetCursor
 
 ; Determines if mouse cursor over a border
 Func _GetBorder()
     Local $aMPos = MouseGetPos()
     Local $aWinPos = WinGetPos($hGUI)
     Local $iSide = 0
     Local $iTopBot = 0
     If $aMPos[0] < $aWinPos[0] + $iMargin Then $iSide = 1
     If $aMPos[0] > $aWinPos[0] + $aWinPos[2] - $iMargin Then $iSide = 2
     If $aMPos[1] < $aWinPos[1] + $iMargin Then $iTopBot = 3
     If $aMPos[1] > $aWinPos[1] + $aWinPos[3] - $iMargin Then $iTopBot = 6
     Return $iSide + $iTopBot
 EndFunc ;==>_GetBorder
 
 ; Set min and max GUI sizes
 Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam)
     $tMinMaxInfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
     DllStructSetData($tMinMaxInfo,  7, $iGUIMinX)
     DllStructSetData($tMinMaxInfo,  8, $iGUIMinY)
     DllStructSetData($tMinMaxInfo,  9, $iGUIMaxX)
     DllStructSetData($tMinMaxInfo, 10, $iGUIMaxY)
     Return 0
 EndFunc   ;==>_WM_GETMINMAXINFO
 
 Func On_Exit()
     Exit
 EndFunc

 

I'm using a similar code in my screenhooter app where you select a portion of the screen to capture the area where you can resize the marked area.

But if you resize the box using the left, top or left upper / lower corner the opposite side of the box is not staying fixed when you resize the box fast. 

For the right and buttom side it works as expected.

Any idea or solution?

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

UEZ,

I couldn't reproduce that using the script I posted

The only thing I can think of (w/o more information) is some kind of delay introduced somewhere which changes the resize action to a drag action - only a supposition chepa.gif

 

Allow2010,

The only solution I found is this dirty and newbie-fashioned way (drag using the $display label)

#include <WindowsConstants.au3>
#Include <GUIConstantsEx.au3>
#include <WINAPI.au3>
#include <Misc.au3>

$hgui = GUICreate("gui", 400, 400, -1, -1, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_TOPMOST)
GUICtrlSetBkColor(-1, 0x000055)
$display = GUICtrlCreateLabel("Test", 50, 50)
GUICtrlSetColor(-1, 0xFF0000)
GUICtrlSetBkColor(-1, -2);transparent
GUISetBkColor(0xABCDEF);transparent
_WinAPI_SetLayeredWindowAttributes($hgui, 0xABCDEF);transparent

GUISetState()

While 1
    $msg = GUIGetMsg()
    If $msg = -3 Then ExitLoop
    If _IsPressed("01") Then 
      Do
         _Drag()
      Until not _IsPressed("01")
   EndIf
WEnd


Func _Drag()
    Local $aMPos = MouseGetPos()
    Local $aWinPos = WinGetPos($hgui)
If $aMPos[0]>$aWinPos[0]+50 and $aMPos[0]<$aWinPos[0]+100 and $aMPos[1]>$aWinPos[1]+50 and $aMPos[1]<$aWinPos[1]+70 Then
    Sleep(20)
    Local $aMPos2 = MouseGetPos()
    $dx = $aMPos2[0]-$aMPos[0]
    $dy = $aMPos2[1]-$aMPos[1]
    WinMove($hgui, "", $aWinPos[0]+$dx, $aWinPos[1]+$dy)
  EndIf
EndFunc
Link to comment
Share on other sites

thanks to everyone who tried to help here and the new solution is quite good (but has limitations for transparent guis).

I found a workaround for my situation (the user presses a hotkey which then chaged background to black and now it is possible to see the window and to move it with a label with $GUI_WS_EX_PARENTDRAG. When down he presses hotkey again to make it transparent again), so i will give up on this...should anyone find a way i will be happy to test it:-)

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