Jump to content
dave12077

Disable Controls

Recommended Posts

dave12077

I have seen several threads where others have asked about disabling controls, but not having them greyed out.  The problem is disabling the control is greyed out due to default windows behavior.  My work around for this was to create an array of the controls I would like to disable.   Then i create small, borderless, guis, on top of each control, and disable the gui, that makes the control "unclickable ".  

The lock function returns an array with the handles to the guis created over each control, and to unlock the controls, delete the guis.

There are probably other ways, probably better ways, I just wanted to share the way I got around this problem.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <WinAPISys.au3>
#include <ComboConstants.au3>

; create enum values for index of array of controls we will want to disable
Const Enum $__CTRL_FIRSTNAME, $__CTRL_LASTNAME, $__CTRL_EMAIL, $__CTRL_CBO, $__CTRL_CHECK, $__CTRL_RAD1, $__CTRL_RAD2, $__CTRL_NOTES, $__CTRL_COUNT

; create array for controls we will want to disable
Local $aEditControls[$__CTRL_COUNT]

; build the gui
Local $hGui = GUICreate("Test", 700, 400)
Local $lblFirst = GUICtrlCreateLabel('First Name : ', 10, 10, 60, 20, $SS_RIGHT)
$aEditControls[$__CTRL_FIRSTNAME] = GUICtrlCreateInput('', 80, 10, 250, 20)

Local $lblLast = GUICtrlCreateLabel('Last Name : ', 360, 10, 60, 20, $SS_RIGHT)
$aEditControls[$__CTRL_LASTNAME] = GUICtrlCreateInput('', 430, 10, 250, 20)

Local $lblEmail = GUICtrlCreateLabel('Email : ', 10, 40, 60, 20, $SS_RIGHT)
$aEditControls[$__CTRL_EMAIL] = GUICtrlCreateInput('', 80, 40, 250, 20)

$aEditControls[$__CTRL_CBO] = GUICtrlCreateCombo("", 430, 40, 80, 20, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Item1|Item2|Item3")

$aEditControls[$__CTRL_CHECK] = GUICtrlCreateCheckbox("Locked", 550, 40, 120, 20)

$aEditControls[$__CTRL_RAD1] = GUICtrlCreateRadio("Radio1", 430, 70, 100, 25)
$aEditControls[$__CTRL_RAD2] = GUICtrlCreateRadio("Radio2", 550, 70, 100, 25)

Local $lblAddress = GUICtrlCreateLabel('Notes : ', 10, 100, 60, 20, $SS_RIGHT)
$aEditControls[$__CTRL_NOTES] = GUICtrlCreateEdit('', 80, 100, 600, 100)

Local $cmdLock = GUICtrlCreateButton('Lock Controls', 80, 220, 90, 30)
Local $cmdUnlock = GUICtrlCreateButton('Unlock Controls', 590, 220, 90, 30)
GUISetState(@SW_SHOW)


Local $nMsg
Local $aLockedCtrls[0]

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            _UnlockControls($aLockedCtrls)
            Exit
        Case $cmdLock
            $aLockedCtrls = _LockControls($aEditControls)
        Case $cmdUnlock
            _UnlockControls($aLockedCtrls)
    EndSwitch
WEnd



; #FUNCTION# ====================================================================================================================
; Name ..........: _LockControls
; Description ...: Locks controls
; Syntax ........: _LockControls(Byref $aCtrls)
; Parameters ....: $aCtrls              - array of controls to lock
; Return values .: an array of handles to the GUIs covering the controls
; ===============================================================================================================================
Func _LockControls(ByRef $aCtrls)
    Local $aGuiHandles[UBound($aCtrls)] ; create array to hold gui
    Local $aSize[0] ; array for control position
    Local $hParent = 0 ; control parent
    Local $hWnd = 0 ; control handle


    For $i = 0 To UBound($aCtrls) - 1

        $hWnd = GUICtrlGetHandle($aCtrls[$i])
        If $hWnd <> 0 Then
            $hParent = _WinAPI_GetParent($hWnd)

            ; get size and position of the control
            $aSize = ControlGetPos($hParent, '', $aCtrls[$i])

            ; create gui over the control
            $aGuiHandles[$i] = GUICreate('', $aSize[2], $aSize[3], $aSize[0], $aSize[1], $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
            _WinAPI_SetParent($aGuiHandles[$i], $hParent)
            GUISetState(@SW_SHOW, $aGuiHandles[$i])
            GUISetState(@SW_DISABLE, $aGuiHandles[$i])
        EndIf
    Next
    WinActivate($hParent)
    Return $aGuiHandles
EndFunc   ;==>_LockControls


; #FUNCTION# ====================================================================================================================
; Name ..........: _UnlockControls
; Description ...: unlocks controls previously locked
; Syntax ........: _UnlockControls(ByRef $aLockedGuis)
; Parameters ....: $aLockedGuis              - array of of gui handles that was used to lock the controls [returned from _LockControls()]
; Return values .: none
; ===============================================================================================================================
Func _UnlockControls(ByRef $aLockedGuis)
    ; lock parent window to prevent flashing
    GUISetState(@SW_LOCK, _WinAPI_GetParent($aLockedGuis[0]))

    ; delete the guis
    For $i = 0 To UBound($aLockedGuis) - 1
        GUIDelete($aLockedGuis[$i])
    Next

    ; unlock parent window
    GUISetState(@SW_UNLOCK, _WinAPI_GetParent($aLockedGuis[0]))
EndFunc   ;==>_UnlockControls

 

  • Like 1

Share this post


Link to post
Share on other sites
InnI

I pressed "Lock Controls" two times and now I can't unlock them by pressing "Unlock Controls" :(

Share this post


Link to post
Share on other sites
dave12077
37 minutes ago, InnI said:

I pressed "Lock Controls" two times and now I can't unlock them by pressing "Unlock Controls" :(

 

I never tried that, I usually disable the buttons that lock the controls to prevent trying to lock them again,  it was creating a second set of guis to block the input and loosing the reference to the previous ones so it could not delete them.  I modified it to use the guiarray as a byref parameter instead of a return value, and static variable to see if they have already been locked, should take care of that issue.  Try this.

 

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <WinAPISys.au3>
#include <ComboConstants.au3>

; create enum values for index of array of controls we will want to disable
Const Enum $__CTRL_FIRSTNAME, $__CTRL_LASTNAME, $__CTRL_EMAIL, $__CTRL_CBO, $__CTRL_CHECK, $__CTRL_RAD1, $__CTRL_RAD2, $__CTRL_NOTES, $__CTRL_COUNT

; create array for controls we will want to disable
Local $aEditControls[$__CTRL_COUNT]

; build the gui
Local $hGui = GUICreate("Test", 700, 400)
Local $lblFirst = GUICtrlCreateLabel('First Name : ', 10, 10, 60, 20, $SS_RIGHT)
$aEditControls[$__CTRL_FIRSTNAME] = GUICtrlCreateInput('', 80, 10, 250, 20)

Local $lblLast = GUICtrlCreateLabel('Last Name : ', 360, 10, 60, 20, $SS_RIGHT)
$aEditControls[$__CTRL_LASTNAME] = GUICtrlCreateInput('', 430, 10, 250, 20)

Local $lblEmail = GUICtrlCreateLabel('Email : ', 10, 40, 60, 20, $SS_RIGHT)
$aEditControls[$__CTRL_EMAIL] = GUICtrlCreateInput('', 80, 40, 250, 20)

$aEditControls[$__CTRL_CBO] = GUICtrlCreateCombo("", 430, 40, 80, 20, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Item1|Item2|Item3")

$aEditControls[$__CTRL_CHECK] = GUICtrlCreateCheckbox("Locked", 550, 40, 120, 20)

$aEditControls[$__CTRL_RAD1] = GUICtrlCreateRadio("Radio1", 430, 70, 100, 25)
$aEditControls[$__CTRL_RAD2] = GUICtrlCreateRadio("Radio2", 550, 70, 100, 25)

Local $lblAddress = GUICtrlCreateLabel('Notes : ', 10, 100, 60, 20, $SS_RIGHT)
$aEditControls[$__CTRL_NOTES] = GUICtrlCreateEdit('', 80, 100, 600, 100)

Local $cmdLock = GUICtrlCreateButton('Lock Controls', 80, 220, 90, 30)
Local $cmdUnlock = GUICtrlCreateButton('Unlock Controls', 590, 220, 90, 30)
GUISetState(@SW_SHOW)


Local $nMsg
Local $aLockedCtrls[0]

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            _UnlockControls($aLockedCtrls)
            Exit
        Case $cmdLock
            _LockControls($aEditControls, $aLockedCtrls)
        Case $cmdUnlock
            _UnlockControls($aLockedCtrls)
    EndSwitch
WEnd



; #FUNCTION# ====================================================================================================================
; Name ..........: _LockControls
; Description ...: Locks controls
; Syntax ........: _LockControls(Byref $aCtrls, Byref $aGuiHandles)
; Parameters ....: $aCtrls              - [in/out] array of controls to lock
;                  $aGuiHandles         - [in/out] array of handles to the GUIs covering the controls
; Return values .: None
; ===============================================================================================================================
Func _LockControls(ByRef $aCtrls, ByRef $aGuiHandles)
    Static $bLocked = False

    ; check to see if they were already locked
    If Not $bLocked Or UBound($aGuiHandles) < UBound($aCtrls) Then

        If UBound($aGuiHandles) < UBound($aCtrls) Then ReDim $aGuiHandles[UBound($aCtrls)]

        Local $aSize[0] ; array for control position
        Local $hParent = 0 ; control parent
        Local $hWnd = 0 ; control handle

        For $i = 0 To UBound($aCtrls) - 1
            $hWnd = GUICtrlGetHandle($aCtrls[$i])
            If $hWnd <> 0 Then
                $hParent = _WinAPI_GetParent($hWnd)

                ; get size and position of the control
                $aSize = ControlGetPos($hParent, '', $aCtrls[$i])

                ; create gui over the control
                $aGuiHandles[$i] = GUICreate('', $aSize[2], $aSize[3], $aSize[0], $aSize[1], $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
                _WinAPI_SetParent($aGuiHandles[$i], $hParent)
                GUISetState(@SW_SHOW, $aGuiHandles[$i])
                GUISetState(@SW_DISABLE, $aGuiHandles[$i])
            EndIf
        Next
        WinActivate($hParent)

        $bLocked = True
    EndIf
EndFunc   ;==>_LockControls


; #FUNCTION# ====================================================================================================================
; Name ..........: _UnlockControls
; Description ...: unlocks controls previously locked
; Syntax ........: _UnlockControls(Byref $aLockedGuis)
; Parameters ....: $aLockedGuis         - [in/out] array of of gui handles that was used to lock the controls [returned from _LockControls()]
; Return values .: None
; ===============================================================================================================================
Func _UnlockControls(ByRef $aLockedGuis)

    ; lock parent window to prevent flashing
    GUISetState(@SW_LOCK, _WinAPI_GetParent($aLockedGuis[0]))

    ; delete the guis
    For $i = 0 To UBound($aLockedGuis) - 1
        GUIDelete($aLockedGuis[$i])
    Next

    ; unlock parent window
    GUISetState(@SW_UNLOCK, _WinAPI_GetParent($aLockedGuis[0]))

    ; reset locked guis array
    ReDim $aLockedGuis[0]
EndFunc   ;==>_UnlockControls

 

Share this post


Link to post
Share on other sites
InnI
8 hours ago, dave12077 said:

Try this

You need more testing before sharing ;)

Try run script and press "Unlock Controls". Or close window with unlocked controls

"D:\AutoIt v3 Script.au3" (110) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
GUISetState(@SW_LOCK, _WinAPI_GetParent($aLockedGuis[0]))
GUISetState(@SW_LOCK, _WinAPI_GetParent(^ ERROR

You need add some error checking.

Call _LockControls with not array $aGuiHandles

"D:\AutoIt v3 Script.au3" (72) : ==> "ReDim" used without an array variable.:
If UBound($aGuiHandles) < UBound($aCtrls) Then ReDim $aGuiHandles[UBound($aCtrls)]
If UBound($aGuiHandles) < UBound($aCtrls) Then ReDim ^ ERROR

 

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

×