Jump to content
Sign in to follow this  
Malkey

A runtime control move/re-size utility.

Recommended Posts

Malkey

This gives your script the ability to move or re-size the controls on your GUI at run-time.

You need to add to your script"-
1/ #include "CtrlResizeMove.au3" ; with the CtrlResizeMove.au3 file in the same directory as your script, and,

2/ _CtrlResizeMove() ; add to within loop of your script.


To operate run your script with the above two additions. Then:-

:Hold down Ctrl key and drag control with left mouse button. This moves the control;
:Hold down Alt key and drag control with left mouse button. This resizes the control; or,
; Press Ctrl + S to save the new control layout to a backup au3 file.


Beware
For the "save to backup" to work correctly, the controls needs to be created in the following format:-
[$controlID = ]GUICtrlCreateNAME("text", int, int, int, int[,styles, etc.])

Where, [...] = optional.
Also each "text" parameter needs to be unique.

If SciTE is not default handler for opening au3 files, then you may need to delete or comment out the line #76,
ShellExecute($scriptPathNew).

Other things.
Labels would not activate. So "get control classnameNN by position" had to be used. Thanks SmOke_N.

The include file script uses the active window to select the controls to maniputate.
So, for something different, when the example is running, open up the help file window. You can rearrange and re-size the controls in the help window - its not permanent.

CtrlResizeMoveExample.au3

;
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include "CtrlResizeMove.au3"; < ===== Inserted here (Remove when finished) ========

;Opt('MustDeclareVars', 1)

Example()

Func Example()
    Local $Button_1, $Button_2, $msg, $aCPos, $checkCN1, $checkCN2, $myedit, $Label1
    GUICreate("Hold down Ctrl or Alt & Drag control / Ctrl+S Save")

    $Button_1 = GUICtrlCreateButton("ControlMove", 10, 14, 100, 30)
    $Button_2 = GUICtrlCreateButton("Button Test", 118, 14, 100, 30)
    $checkCN1 = GUICtrlCreateCheckbox("CHECKBOX 1", 12, 49, 98, 19)
    $checkCN2 = GUICtrlCreateCheckbox("CHECKBOX 2", 120, 49, 98, 19)
    $myedit = GUICtrlCreateEdit("First line" & @CRLF, 10, 73, 211, 54, $ES_AUTOVSCROLL + $WS_VSCROLL)
    $Label1 = GUICtrlCreateLabel("Line 1 Cell 1", 10, 150, 70, 20)
    GUICtrlCreateLabel("Line 2 Cell 1", 100, 150, 70, 20)
    GUISetState()

; Run the GUI until the dialog is closed
    While 1
        $msg = GUIGetMsg()
        Select
            Case $msg = $GUI_EVENT_CLOSE
                ExitLoop
            Case $msg = $Button_1
            ; A command
            Case $msg = $Button_2
                MsgBox(0, 'Testing', 'Button 2 was pressed')
        EndSelect
        _CtrlResizeMove(); < ========= Inserted here (Remove when finished) ========
    WEnd
EndFunc  ;==>Example
;

The include file CtrlResizeMove.au3

;
;================= CtrlResizeMove.au3  ===========================
; REQUIREMENTS. There are two things you need to do to use script
; If this file is saved as "CtrlResizeMove.au3" then
; 1/ Add  #include "CtrlResizeMove.au3"  or #include "c:\full path\CtrlResizeMove.au3"
;       to top of your script in which you need to resize or move the controls.
; 2/ Put _CtrlResizeMove() within the loop of your script.
;
; HOW TO USE. While hovering over the GUI control you wish to alter:-
; 1/ Press Ctrl + Left mouse button to MOVE the control (And move the mouse);
; 2/ Press Alt + Left mouse button to RE- SIZE the control (And move the mouse);
; 3/ Press Ctrl + s to Save the new control parameters to a backup file called "'your_script_name' & BKn.au3"
;
; CLEANUP. When the control are as required:-
; 1/ Remove the inserted #include "CtrlResizeMove.au3" command
; 2/ Remove the inserted _CtrlResizeMove() command from within the loop of your script.
; 3/ Rename or remove backup files from your script's directory (folder).
;===================================================================
;
#include <GUIConstantsEx.au3>
#include <Misc.au3>

;Opt('MustDeclareVars', 1)

Local $scriptPath = @ScriptFullPath, $File, $Data
Local $scriptPathNew = StringRegExpReplace($scriptPath, "(^.*)\.(.*)", "\1") & "BK" & _
        StringRegExpReplace($scriptPath, "^.*\.", ".$1")
;ConsoleWrite(@ScriptFullPath & @CRLF)
If FileExists($scriptPathNew) Then
    Local $Num = 0
    Do
        $Num += 1
        $scriptPathNew = StringRegExpReplace($scriptPath, "(^.*)\.(.*)", "\1") & "BK" & $Num & _
                StringRegExpReplace($scriptPath, "^.*\.", ".$1")
    Until Not FileExists($scriptPathNew)
EndIf
$Data = FileRead($scriptPath)

; This function to be called from within the loop of the script which has the GUI controls to be altered.
Func _CtrlResizeMove()
    Local $aCPos, $aMPos, $aMPosNew, $Num, $scriptPath, $hWnd, $aClssNmNN, $sTxt, $ClssNmNN, $iCommasNo
    Select
        Case (_IsPressed("11") Or _IsPressed("12")) And _IsPressed("01"); Ctrl + Left mouse button to move
            $hWnd = WinGetHandle(""); or Alt + Left mouse button to re-size
            Opt("MouseCoordMode", 2);1=absolute, 0=relative, 2=client
            $aMPos = MouseGetPos()
            $aClssNmNN = _CtrlGetByPos($hWnd, "", $aMPos[0], $aMPos[1], 0); uses client mouse coords
            Opt("MouseCoordMode", 1);1=absolute, 0=relative, 2=client
            $aMPos = MouseGetPos()
            If IsArray($aClssNmNN) Then $ClssNmNN = $aClssNmNN[1]
        ;ConsoleWrite("CLNN  " & $ClssNmNN & @CRLF)
            $aCPos = ControlGetPos($hWnd, "", $ClssNmNN)
            Do
                $aMPosNew = MouseGetPos()
                If _IsPressed("11") Then ControlMove($hWnd, "", $ClssNmNN, $aCPos[0] + $aMPosNew[0] - $aMPos[0], _
                        $aCPos[1] + $aMPosNew[1] - $aMPos[1])
                If _IsPressed("12") Then ControlMove($hWnd, "", $ClssNmNN, $aCPos[0], $aCPos[1], _
                        $aCPos[2] + $aMPosNew[0] - $aMPos[0], $aCPos[3] + $aMPosNew[1] - $aMPos[1])
                Sleep(100)
            Until Not _IsPressed("01")

        ;========== Updata Data ====================
            $sTxt = StringRegExpReplace(ControlGetText($hWnd, "", $ClssNmNN), "(\w*[ ]*)(\s*\v*)", "\1")
        ;ConsoleWrite($sTxt & @CRLF)
            $aCPos = ControlGetPos($hWnd, "", $ClssNmNN)
            $Data = StringRegExpReplace($Data, '("' & $sTxt & '".*),\h*\d*\h*,\h*\d*\h*,\h*\d*\h*,\h*\d*\h*(,.*|\))', _
                    '\1, ' & $aCPos[0] & ", " & $aCPos[1] & ", " & $aCPos[2] & ", " & $aCPos[3] & "\2")
        ;=========> End of Updata Data =============

        Case _IsPressed("11") And _IsPressed("53"); Ctrl + s   To Save
            Do
            Until Not (_IsPressed("11") And _IsPressed("53"))
            $File = FileOpen($scriptPathNew, 2)
            FileWrite($File, $Data)
            FileClose($File)
            ShellExecute($scriptPathNew)
    EndSelect
EndFunc  ;==>_CtrlResizeMove

; From http://www.autoitscript.com/forum/index.php?s=&showtopic=30717&view=findpost&p=219847
Func _CtrlGetByPos($hWin, $sText = '', $iXPos = 0, $iYPos = 0, $iReturnType = 0)
    If IsString($hWin) Then $hWin = WinGetHandle($hWin)
    Local $sClassList = WinGetClassList($hWin), $hCtrlWnd
    Local $sSplitClass = StringSplit(StringTrimRight($sClassList, 1), @LF), $aReturn = ''
    For $iCount = UBound($sSplitClass) - 1 To 1 Step -1
        Local $nCount = 0
        While 1
            $nCount += 1
            Local $aCPos = ControlGetPos($hWin, $sText, $sSplitClass[$iCount] & $nCount)
            If @error Then ExitLoop
            If $iXPos >= $aCPos[0] And $iXPos <= ($aCPos[0] + $aCPos[2]) _
                    And $iYPos >= $aCPos[1] And $iYPos <= ($aCPos[1] + $aCPos[3]) Then
                If $sSplitClass[$iCount] <> '' And Not $iReturnType Then
                    Local $aClassNN[2] = [2, $sSplitClass[$iCount] & $nCount]
                    Return $aClassNN
                EndIf
                If $sSplitClass[$iCount] <> '' And $iReturnType = 3 Then
                    $hCtrlWnd = ControlGetHandle($hWin, $sText, $sSplitClass[$iCount] & $nCount)
                    ControlFocus($hWin, $sText, $hCtrlWnd)
                    $aReturn = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $hCtrlWnd)
                    If @error = 0 And $aReturn[0] <> '' Then
                        Local $aClassNN[4] = [4, $aReturn[0], $sSplitClass[$iCount] & $nCount, $hCtrlWnd]
                        Return $aClassNN
                    EndIf
                    Local $aClassNN[2] = [2, $sSplitClass[$iCount] & $nCount]
                    Return $aClassNN
                ElseIf $sSplitClass[$iCount] <> '' And $iReturnType = 2 Then
                    Return ControlGetHandle($hWin, $sText, $sSplitClass[$iCount] & $nCount)
                ElseIf $sSplitClass[$iCount] <> '' And $iReturnType = 1 Then
                    $hCtrlWnd = ControlGetHandle($hWin, $sText, $sSplitClass[$iCount] & $nCount)
                    ControlFocus($hWin, $sText, $hCtrlWnd)
                    $aReturn = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $hCtrlWnd)
                    If @error = 0 And $aReturn[0] <> '' Then
                        Local $aClassNN[2] = [2, $aReturn[0]]
                        Return $aClassNN
                    EndIf
                EndIf
                Return SetError(1, 0, 0)
            EndIf
        WEnd
    Next
    Return SetError(2, 0, 0)
EndFunc  ;==>_CtrlGetByPos
;

Edit: Added comment,";", to Opt('MustDeclareVars', 1) lines.

Edited by Malkey

Share this post


Link to post
Share on other sites
Yashied
Malkey

Very interesting idea, thanks.

Yes. That was my second thought.

My third thought was this must have been done on these forums before.

Share this post


Link to post
Share on other sites
YellowLab

Interesting, but ControlMove has a problem. The problem is that ControlMove picks up the entire box of the control ignoring transparency. I found the problem with some irregularly shaped images, but your script shows the same issues when you drag the Text labels slowly around the buttons. If anyone has a solution to this I would appreciate the help.

Edited by YellowLab

You can't see a rainbow without first experiencing the rain.

Share this post


Link to post
Share on other sites
Malkey

YellowLab

If the problem is the GUI is needing updating after the ControlMove command, then using _WinAPI_RedrawWindow($hWnd) after ControlMove() should fix the problem.

If _WinAPI_RedrawWindow does not work, then posting a small working script displaying the problem in the "General Help and Support" forum is the best method to help people to help you.

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.