Sign in to follow this  
Followers 0

_GUIDisable() - Create a dimmed effect on a GUI.

71 posts in this topic

Posted (edited)

I was inspired by an example in s!mpL3 LAN Messenger, in which when you wanted to change the Password the current GUI had a dimmed effect until the Password was set.

I therefore decided to create _GUIDisable which creates the same effect. I also utilised a Function mentioned by Mat and created by Yashied in the topic.

Example:

Posted Image

or continue for those interested in the original UDF with more options ...

UDF with Global variable:

#include-once

; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
; #INDEX# =======================================================================================================================
; Title .........: _GUIDisable
; AutoIt Version : v3.2.2.0 or higher
; Language ......: English
; Description ...: Creates a dimming effect on the current/selected GUI.
; Note ..........:
; Author(s) .....: guinness
; Remarks .......: Thanks to supersonic for the idea of adjusting the UDF when using Classic themes in Windows Vista+.
; ===============================================================================================================================

; #INCLUDES# ====================================================================================================================
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

; #GLOBAL VARIABLES# ============================================================================================================
Global Enum $__hGUIDisableHWnd, $__hGUIDisableHWndPrevious, $__iGUIDisableMax
Global $__aGUIDisable[$__iGUIDisableMax]

; #CURRENT# =====================================================================================================================
; _GUIDisable: Creates a dimming effect on the current/selected GUI.
; ===============================================================================================================================

; #INTERNAL_USE_ONLY#============================================================================================================
; __GUIDisable_WM_SIZE: Automatically re-sizes the dimmed effect when the GUI is re-sized.
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name ..........: _GUIDisable
; Description ...: Creates a dimming effect on the current/selected GUI.
; Syntax ........: _GUIDisable($hWnd[, $iAnimate = 1[, $iBrightness = 5[, $bColor = 0x000000]]])
; Parameters ....: $hWnd             - GUI handle the effect should be applied to. This can either be a variable of the GUI handle or -1 for the current GUI.
;                  $iAnimate            - [optional] Animate the dimmed effect. Animate = 1 or don't animate = 0. Default is 1.
;                  $iBrightness         - [optional] Percentage of how bright the effect is. Default is 5.
;                  $bColor              - [optional] Color of the dimming effect. Default is 0x000000.
; Return values .: Success - Returns handle of dimmed GUI.
;                  Failure - Returns 0 and sets @error to non-zero
; Author ........: guinness
; Example .......: Yes
; ===============================================================================================================================
Func _GUIDisable($hWnd, $iAnimate = Default, $iBrightness = Default, $bColor = 0x000000)
    Local Const $AW_SLIDE_IN_TOP = 0x00040004, $AW_SLIDE_OUT_TOP = 0x00050008

    If $iAnimate = Default Then
        $iAnimate = 1
    EndIf
    If $iBrightness = Default Then
        $iBrightness = 5
    EndIf

    If $hWnd = -1 And $__aGUIDisable[$__hGUIDisableHWnd] = 0 Then
        Local $iLabel = GUICtrlCreateLabel('', -99, -99, 1, 1)
        $hWnd = _WinAPI_GetParent(GUICtrlGetHandle($iLabel))
        If @error Then
            Return SetError(1, 0 * GUICtrlDelete($iLabel), 0)
        EndIf
        GUICtrlDelete($iLabel)
    EndIf

    If IsHWnd($__aGUIDisable[$__hGUIDisableHWnd]) Then
        If $iAnimate Then
            DllCall('user32.dll', 'int', 'AnimateWindow', 'hwnd', $__aGUIDisable[$__hGUIDisableHWnd], 'dword', 250, 'dword', $AW_SLIDE_OUT_TOP)
        EndIf
        GUIDelete($__aGUIDisable[$__hGUIDisableHWnd])
        GUISwitch($__aGUIDisable[$__hGUIDisableHWndPrevious])
        $__aGUIDisable[$__hGUIDisableHWnd] = 0
        $__aGUIDisable[$__hGUIDisableHWndPrevious] = 0
    Else
        $__aGUIDisable[$__hGUIDisableHWndPrevious] = $hWnd

        Local $iLeft = 0, $iTop = 0
        Local $sCurrentTheme = RegRead('HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes', 'CurrentTheme')
        Local $iIsClassicTheme = Number(StringInStr($sCurrentTheme, 'Basic.theme', 2) = 0 And StringInStr($sCurrentTheme, 'Ease of Access Themes', 2) > 0)

        Local $aStyle = GUIGetStyle($__aGUIDisable[$__hGUIDisableHWndPrevious])
        If UBound($aStyle) Then
            If BitAND($aStyle[0], $WS_SIZEBOX) Then
                If RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\', 'CurrentVersion') >= 6.0 Then ; Windows Vista+.
                    If $iIsClassicTheme Then
                        $iLeft -= 1
                        $iTop -= 1
                    Else
                        $iLeft -= 5
                        $iTop -= 5
                    EndIf
                Else
                    $iLeft -= 1
                    $iTop -= 1
                EndIf
            EndIf
        EndIf

        Local $aWinGetPos = WinGetClientSize($__aGUIDisable[$__hGUIDisableHWndPrevious])
        $__aGUIDisable[$__hGUIDisableHWnd] = GUICreate('', $aWinGetPos[0], $aWinGetPos[1], $iLeft, $iTop, $WS_POPUP, $WS_EX_MDICHILD, $__aGUIDisable[$__hGUIDisableHWndPrevious])
        GUISetBkColor($bColor, $__aGUIDisable[$__hGUIDisableHWnd])
        WinSetTrans($__aGUIDisable[$__hGUIDisableHWnd], '', Round($iBrightness * (255 / 100)))
        GUIRegisterMsg($WM_SIZE, '__GUIDisable_WM_SIZE')
        If $iAnimate Then
            DllCall('user32.dll', 'int', 'AnimateWindow', 'hwnd', $__aGUIDisable[$__hGUIDisableHWnd], 'dword', 250, 'dword', $AW_SLIDE_IN_TOP)
        Else
            GUISetState(@SW_SHOW, $__aGUIDisable[$__hGUIDisableHWnd])
        EndIf
        GUISetState(@SW_DISABLE, $__aGUIDisable[$__hGUIDisableHWnd])
        GUISwitch($__aGUIDisable[$__hGUIDisableHWndPrevious])
    EndIf
    Return $__aGUIDisable[$__hGUIDisableHWnd]
EndFunc   ;==>_GUIDisable

; #INTERNAL_USE_ONLY#============================================================================================================
Func __GUIDisable_WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $iHeight = _WinAPI_HiWord($lParam)
    Local $iWidth = _WinAPI_LoWord($lParam)
    If $hWnd = $__aGUIDisable[$__hGUIDisableHWndPrevious] Then
        Local $iWinGetPos = WinGetPos($__aGUIDisable[$__hGUIDisableHWnd])
        If @error = 0 Then
            WinMove($__aGUIDisable[$__hGUIDisableHWnd], '', $iWinGetPos[0], $iWinGetPos[1], $iWidth, $iHeight)
        EndIf
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>__GUIDisable_WM_SIZE

Example 1:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <Constants.au3>
#include '_GUIDisable.au3'

Example_1()

Func Example_1()
    Local $hGUI = GUICreate('_GUIDisable()', 300, 100, -1, -1, BitXOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX, $WS_MINIMIZEBOX))
    Local $iButton_1 = GUICtrlCreateButton('Effect 1', 5, 5, 100, 25)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKSIZE + $GUI_DOCKTOP)

    Local $iButton_2 = GUICtrlCreateButton('Effect 2', 5, 30, 100, 25)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKSIZE + $GUI_DOCKTOP)

    GUISetState(@SW_SHOW, $hGUI)

    Local $hDisableGUI = 0, $hTimer = 0
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $iButton_1
                ; Enable the dimmed effect on the current GUI with the animation turned on.
                _GUIDisable(-1, 1, 25)
                MsgBox($MB_SYSTEMMODAL, '_GUIDisable()', 'See how the GUI is now dimmed. Once you select OK, you''ll have 5 seconds to re-size the GUI!' & @CRLF & @CRLF & _
                        'If you wish to exit the 5 second timer, then simply select "Close" to exit the loop.')
                $hTimer = TimerInit()
                Do
                    ; Exit the loop if $GUI_EVENT_CLOSE is captured by GUIGetMsg().
                    If GUIGetMsg() = $GUI_EVENT_CLOSE Then
                        ExitLoop
                    EndIf
                    Sleep(10)
                Until TimerDiff($hTimer) > 5000

                ; Disable the dimmed effect with the animation turned on and add focus to the current GUI.
                _GUIDisable(-1, 1)

            Case $iButton_2
                ; Enable the dimmed effect on the current GUI without the animation.
                $hDisableGUI = _GUIDisable($hGUI, 0, 25, 0x7D26CD)

                ; Pass handle of dimmed GUI to the MsgBox, just the same as passing $hGUI.
                MsgBox($MB_SYSTEMMODAL, '_GUIDisable(' & $hGUI & ')', 'See how the GUI is now dimmed with a Purple color.', 0, $hDisableGUI)

                ; Disable the dimmed effect without the animation and add focus back to the previous GUI.
                _GUIDisable($hGUI, 0)

        EndSwitch
    WEnd
    GUIDelete($hGUI)
EndFunc   ;==>Example_1

All of the above has been included in a ZIP file. GUIDisable.zip

Previous downloads: 420+.

Updated: 01/02/2013

Edited by guinness
1 person likes this

Share this post


Link to post
Share on other sites



Posted

I copied the script runs but does not see anything happen :)

Share this post


Link to post
Share on other sites

Posted

@jscript that's strange, because I see something happen: the window gets darker... (when the MsgBox is opened)

Share this post


Link to post
Share on other sites

Posted (edited)

@jscript, maybe try this to see the difference in "dimness!"

_GUIDisable(-1, 90) ; This is 90% dimmed.

And thanks AppTux for Testing.

Edited by guinness

Share this post


Link to post
Share on other sites

Posted

@jscript, maybe try this to see the difference in "dimness!"

_GUIDisable(-1, 90) ; This is 90% dimmed.

And thanks AppTux for Testing.

Perfect! I think my "Colorblind" not much help... :)

Share this post


Link to post
Share on other sites

Posted

Nice effect guinness :)

For me it would be better if the dimming function had parameters passed to it so that it could be used with any gui in the script and it didn't need, or use, global variables.

Share this post


Link to post
Share on other sites

Posted

parameters passed to it so that it could be used with any gui in the script and it didn't need, or use, global variables.

It's something I could work on, but this was something I put together in 5mins :)

Share this post


Link to post
Share on other sites

Posted

It's something I could work on, but this was something I put together in 5mins :)

Well I think we could have waited another 5 minutes :)

Share this post


Link to post
Share on other sites

Posted (edited)

_GUIDisable without the Global Variable & Re-Sizing (as suggested by martin.)

UDF without Global variable:

#include-once

; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
; #INDEX# =======================================================================================================================
; Title .........: _GUIDisable
; AutoIt Version : v3.2.2.0 or higher
; Language ......: English
; Description ...: Creates a dimming effect on the current/selected GUI.
; Note ..........:
; Author(s) .....: guinness
; Remarks .......:
; ===============================================================================================================================

; #INCLUDES# =========================================================================================================
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

; #GLOBAL VARIABLES# =================================================================================================
; None.

; #CURRENT# =====================================================================================================================
; _GUIDisable: Creates a dimming effect on the current/selected GUI.
; ===============================================================================================================================

; #INTERNAL_USE_ONLY#============================================================================================================
; None.
; ===============================================================================================================================

; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
; #FUNCTION# =========================================================================================================
; Name...........: _GUIDisable
; Description ...: Creates a dimming effect on the current/selected GUI.
; Syntax.........: _GUIDisable([$hWnd = -1, [$iDelete = 0, [$iBrightness = 5, [$bColor = 0x000000]]]])
; Parameters ....: $hWnd  - [Optional] GUI handle the effect should be applied to. Default = -1 (Current GUI handle created)
;                  $iDelete - [Optional] Create or Delete the dimming effect. Default = 0 (Create = 0 & Delete = 1)
;                  $iBrightness - [Optional] Percentage of how bright the effect is. Default = 5%
;                  $bColor - [Optional] Color of the dimming effect. Default = Black
; Requirement(s).: v3.2.2.0 or higher
; Return values .: Success - Returns handle of dimmed GUI or value of GUIDelete().
;                  Failure - Returns 0
; Author ........: guinness
; Example........; Yes
;=====================================================================================================================
Func _GUIDisable($hWnd = -1, $iDelete = 0, $iBrightness = Default, $bColor = 0x000000)
    Local $vGUI = 0

    If $iBrightness = Default Then
        $iBrightness = 5
    EndIf

    If $hWnd = -1 Then
        Local $iLabel = GUICtrlCreateLabel('', -99, -99, 1, 1)
        $hWnd = _WinAPI_GetParent(GUICtrlGetHandle($iLabel))
        If @error Then
            Return SetError(1, 0 * GUICtrlDelete($iLabel), 0)
        EndIf
        GUICtrlDelete($iLabel)
    EndIf

    If $iDelete Then
        $vGUI = GUIDelete($hWnd)
    Else
        Local $aWinGetPos = WinGetClientSize($hWnd)
        $vGUI = GUICreate('', $aWinGetPos[0], $aWinGetPos[1], 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $hWnd)
        GUISetBkColor($bColor, $vGUI)
        WinSetTrans($vGUI, '', Round($iBrightness * (255 / 100)))
        GUISetState(@SW_SHOW, $vGUI)

    EndIf
    Return $vGUI
EndFunc   ;==>_GUIDisable

Example 1:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <WindowsConstants.au3>

#include '_GUIDisable.au3'

Example_1()

Func Example_1()
    Local $hGUI = GUICreate('_GUIDisable()', 300, 100, -1, -1, BitXOR($GUI_SS_DEFAULT_GUI, $WS_MINIMIZEBOX))
    Local $iButton_1 = GUICtrlCreateButton('Effect 1', 5, 5, 100, 25)
    Local $iButton_2 = GUICtrlCreateButton('Effect 2', 5, 30, 100, 25)
    GUISetState(@SW_SHOW, $hGUI)

    Local $hDisableGUI = 0
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $iButton_1
                ; Enable the dimmed effect on the current GUI.
                _GUIDisable(-1, 0, 45)
                MsgBox(4096, '_GUIDisable(' & $hGUI & ')', 'See how the GUI is now dimmed.')

                ; Disable the previously dimmed effect.
                _GUIDisable(-1, 1)

            Case $iButton_2
                ; Enable the dimmed effect on the current GUI.
                $hDisableGUI = _GUIDisable(-1, 0, 25, 0x7D26CD)

                ; Pass handle of dimmed GUI to the MsgBox, just the same as passing $GUI.
                MsgBox(4096, '_GUIDisable(' & $hGUI & ')', 'See how the GUI is now dimmed with a Purple color.', 0, $hDisableGUI)

                ; Disable the previously dimmed effect.
                _GUIDisable(-1, 1)

        EndSwitch
    WEnd
    GUIDelete($hGUI)
EndFunc   ;==>Example_1
Edited by guinness

Share this post


Link to post
Share on other sites

Posted

That's a good improvement :)

Share this post


Link to post
Share on other sites

Posted (edited)

I've just updated _GUIDisable(). It's now packaged together in a ZIP file, included a better looking screenshot and I cleaned up the code. Any suggestions then post below. Thanks.

Edited by guinness

Share this post


Link to post
Share on other sites

Posted

guinness,

I like your UDF a lot. Thanks for sharing! :huh2:

-supersonic.

Share this post


Link to post
Share on other sites

Posted (edited)

But I have found two little issues:

- When used with a resizable window the dimmed layer is not correctly positioned (e. g. MS Windows 7 with Aero, ~ 2-3 pixels, see top and left side).

- And the dimmed layer will not be correctly resized.

Maybe there could be solutions for these little issues?

-supersonic.

Edited by supersonic

Share this post


Link to post
Share on other sites

Posted (edited)

Yeh I will update it today or tomorrow. Thanks supersonic.

I've normally just intercepted the sizing of the GUI when _GUIDisable() is enabled, but I can see it being a benefit now.

Edited by guinness

Share this post


Link to post
Share on other sites

Posted (edited)

Updated with the suggestions by supersonic, Thanks. See the original post for an updated version.

ChangeLog:

ADDED: Animation of the dimmed effect. If enabled it will animate from top to bottom when the dim effect is applied and reverse when removed.
ADDED: Re-sizing of the dimmed effect if $WS_SIZEBOX is present as a Style in GUICreate().
FIXED: Alignment issues if $WS_SIZEBOX has been used as a style.

Any suggestions or improvements then please post below. Thanks.

Edited by guinness

Share this post


Link to post
Share on other sites

Posted

Updated for those that use multiple GUI's

ChangeLog:

FIXED: If a second GUI was created after _GUIDisable() was enabled, then re-sizing the second GUI would re-size the dimmed effect too.
FIXED: If using a second GUI with $WS_POPUP on top of _GUIDisable() would result in the dimmed effect being brought forward if selected, this was solved by setting the state to @SW_DISABLE.

Any suggestions or improvements then please post below. Thanks.

Share this post


Link to post
Share on other sites

Posted (edited)

guinness,

thank you, works well.

I found another problem:

Your script seems to work well - but only with one GUI at runtime. In my case I have to handle up to three GUIs at runtime.

Here's my quick-'n'-dirty solution to that issue:

#include-once


#include <Array.au3>
#include <WindowsConstants.au3>


Func _GUIDisable($hGD_Window, ByRef $aGD_Window, $bGD_Color = 0x000000, $iGD_Transparency = 10)
    If IsHWnd($hGD_Window) = 1 Then
        If UBound($aGD_Window, 0) = 2 Then
            Switch @NumParams
                Case 2 ; Enable.
                    Local $iGD_ArraySearch = _ArraySearch($aGD_Window, $hGD_Window, 1, 0, 0, 0, 0, 0)
                    If Not @error Then
                        GUIDelete($aGD_Window[$iGD_ArraySearch][1])
                        GUISetState(@SW_ENABLE, $aGD_Window[$iGD_ArraySearch][0])
                        _ArrayDelete($aGD_Window, $iGD_ArraySearch)
                        Return SetError(0, 0, 1)
                    EndIf
                    Return SetError(4, 0, 0)
                Case 3, 4 ; Disable.
                    If BitAND(WinGetState($hGD_Window, ""), 2) = True Then
                        Local $aGD_WindowPosition = WinGetPos($hGD_Window, "")
                        If Not @error And UBound($aGD_WindowPosition) = 4 Then
                            Local $hGD_Dummy = GUICreate("", $aGD_WindowPosition[2], $aGD_WindowPosition[3], $aGD_WindowPosition[0], $aGD_WindowPosition[1], BitOR($WS_DISABLED, $WS_POPUP), BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
                            If Not @error Then
                                ReDim $aGD_Window[UBound($aGD_Window, 1) + 1][UBound($aGD_Window, 2)]
                                $aGD_Window[UBound($aGD_Window) - 1][0] = $hGD_Window
                                $aGD_Window[UBound($aGD_Window) - 1][1] = $hGD_Dummy
                                GUISetBkColor($bGD_Color, $hGD_Dummy)
                                WinSetTrans($hGD_Dummy, "", Round($iGD_Transparency * (255 / 100), 0))
                                GUISetState(@SW_DISABLE, $hGD_Window)
                                GUISetState(@SW_SHOW, $hGD_Dummy)
                                Return SetError(0, 0, 1)
                            EndIf
                            Return SetError(6, 0, 0)
                        EndIf
                        Return SetError(5, 0, 0)
                    EndIf
                    Return SetError(4, 0, 0)
            EndSwitch
            Return SetError(3, 0, 0)
        EndIf
        Return SetError(2, 0, 0)
    EndIf
    Return SetError(1, 0, 0)
EndFunc   ;==>_GUIDisable

Although working with an array in this UDF the performance is still good because the array is very small.

A little performance improvement is to check if the window is visible or not before applying the effect.

-supersonic.

Edited by supersonic

Share this post


Link to post
Share on other sites

Posted (edited)

Your script seems to work well - but only with one GUI at runtime. In my case I have to handle up to three GUIs at runtime.

My initial design brief was for it to be with only 1 GUI at a time because I normally have a "Main" GUI that I always revert back to. If your solution works then great :) Edited by guinness

Share this post


Link to post
Share on other sites

Posted

ChangeLog:

IMPROVED: Source code of the UDF.

Any suggestions or improvements then please post below. Thanks.

Share this post


Link to post
Share on other sites

Posted

@guinness

When I click the link, go to message #19...

João Carlos.

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  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.