Jump to content

Prevent Dotted Focus Lines on Controls


Melba23
 Share

Recommended Posts

  • Moderators

[BUGFIX VERSION] - 25 Jun 13

Fixed: A bug in AutoIt v3.3.6.1 could crash the UDF under certain circumstances - other releases do not show the same error. Small code change to prevent error in any release. :)

Thanks to DatMCEyeBall for finding it. :thumbsup:

New UDF below and in zip. :)

Previous versions:

Spoiler

[uPDATED VERSION] - 6 Feb 11

Changes:

- Uses OnAutoItExitRegister to clear up - no longer any requirement to call the correct _Exit function in your script. Note that this requires v3.3.4 or better.

New UDF, example and zip below. :D


Updated version now posted - 30 Sep 09


A recent topic dealt with the problem of the dotted focus lines which appear around controls - the most obvious ones are around sliders - and how to get rid of them.

A bit of experimentation showed that these focus lines do not always appear. If there is a button in the GUI, they do not seem to appear until the TAB key has been used to change focus in the GUI - if you only use the mouse, they usually remain hidden. However, if there is no button, they appear immediately. I posted some code in the topic to show this.

The only solution to permanently remove these lines appeared to be subclassing the controls to bypass the WM_SETFOCUS message, but the necessary code seemed a little daunting to coders less well-versed in the dark side of Autoit (in which category I firmly place myself! :D ). So once I had understood what was going on in the subclassing process, I thought I might try and make a UDF which would simplify the whole thing for us average Autoit users.

A number of other forum members have offered suggestions and code snippets - and here you have the resulting UDF, which prevents focus lines from ruining the visual appearance of buttons, radios, checkboxes and sliders:

[NEW] The NoFocusLines.au3 include file:

#include-once

; #INDEX# ============================================================================================================
; Title .........: NoFocusLines
; AutoIt Version : 3.3.4.0 +
; Language ......: English
; Description ...: Prevents dotted focus lines on GUI controls of button and slider classes
; Remarks .......: Once the _Set function has been used to prevent focus lines, the specified controls should be reset
;                  with the _Clear function before deletion.  Note all such controls can be reset in
;                  one call to the _Clear function without having to specify each individual control.
;                  The _Global_Set function prevents focus lines on ANY subsequently created button or slider class
;                  control.  However, CAUTION is advised when using the _Global_Set function as even though the use of
;                  the _Global_Exit function on exit deletes all such controls and frees the memory used by the UDF,
;                  full clean up relies on internal AutoIt procedures.
; Note ..........: Button class controls include buttons, radios and checkboxes
; Author(s) .....: Melba23, based on code from Siao, aec, martin, Yashied and rover
; ====================================================================================================================

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

OnAutoItExitRegister("_NoFocusLines_AutoExit")

; #GLOBAL VARIABLES# =================================================================================================
Global $hNoFocusLines_Proc = 0, $pOrg_SliderProc = 0, $pOrg_ButtonProc = 0, $aHandle_Proc[1][2] = [[0, ""]]

; #CURRENT# ==========================================================================================================
; _NoFocusLines_Set:         Prevents dotted focus lines on specified button and slider class controls
; _NoFocusLines_Clear:       Resets normal focus lines on specified controls.
; _NoFocusLines_Exit:        Used on script exit to reset all subclassed controls and free UDF WndProc memory
; _NoFocusLines_Global_Set:  Prevents dotted focus lines on all subsequently created button and slider class controls
; _NoFocusLines_Global_Exit: Used on script exit to delete all subclassed controls and free UDF WndProc memory
; ====================================================================================================================

; #INTERNAL_USE_ONLY#=================================================================================================
; _NoFocusLines_SubClass:    Sets WndProc for specified control
; _NoFocusLines_Proc:        New WndProc to prevent focus lines on specified button and slider class controls
; _NoFocusLines_Global_Proc: New WndProc to prevent focus lines on all subsequently created button and slider controls
; _NoFocusLines_AutoExit:    Automatically deletes all controls and frees the memory used on exit
; ====================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _NoFocusLines_Set
; Description ...: Prevents the dotted focus lines on specified button and slider class controls
; Syntax.........: _NoFocusLines_Set($vCID)
; Parameters ....: $vCID - ControlIDs of controls - multiple ControlIDs must be passed as a 0-based array
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns number of controls currently subclassed
;                  Failure:  Sets @error as follows:
;                  1 = Global function already run
;                  2 = Invalid controlID
; Author ........: Melba23, based on code from Siao, aec, martin and Yashied
; Remarks .......: Any controls on which focus lines have been prevented by using the _SET function should be reset via
;                  the _CLEAR function if deleted prior to exit
; Example........: Yes
;=====================================================================================================================
Func _NoFocusLines_Set($vCID)

    Local $aCID[1]

    ; Check if Global function already used
    If $aHandle_Proc[0][1] = "Global" Then Return SetError(1, 0, 0)

    ; Check parameters are button or slider class controls
    If Not IsArray($vCID) Then
        Switch _WinAPI_GetClassName(GUICtrlGetHandle($vCID))
            Case "Button", "msctls_trackbar32"
                $aCID[0] = $vCID
            Case Else
                Return SetError(2, 0, 0)
        EndSwitch
    Else
        For $i = 0 To UBound($vCID) - 1
            Switch _WinAPI_GetClassName(GUICtrlGetHandle($vCID[$i]))
                Case "Button", "msctls_trackbar32"
                    ; ContinueLoop
                Case Else
                    Return SetError(2, 0, 0)
            EndSwitch
        Next
        $aCID = $vCID
    EndIf

    ; Check if _NoFocusLines_Proc has been registered
    If $hNoFocusLines_Proc = 0 Then
        ; Register callback function and obtain handle to _NoFocusLines_Proc
        $hNoFocusLines_Proc = DllCallbackRegister("_NoFocusLines_Proc", "int", "hwnd;uint;wparam;lparam")
    EndIf

    ; Get pointer to _NoFocusLines_Proc
    Local $pNoFocusLines_Proc = DllCallbackGetPtr($hNoFocusLines_Proc)

    ; Work through CIDs
    For $i = 0 To UBound($aCID) - 1

        ; Get handle for control
        Local $hHandle = GUICtrlGetHandle($aCID[$i])
        ; Check if control is already subclassed
        For $j = 1 To $aHandle_Proc[0][0]
            ; Skip if so
            If $hHandle = $aHandle_Proc[$j][0] Then
                ContinueLoop 2
            EndIf
        Next

        ; Increase control count
        $aHandle_Proc[0][0] += 1
        ; Double array size if too small (fewer ReDim needed)
        If UBound($aHandle_Proc) <= $aHandle_Proc[0][0] Then ReDim $aHandle_Proc[UBound($aHandle_Proc) * 2][2]

        ; Store control handle
        $aHandle_Proc[$aHandle_Proc[0][0]][0] = $hHandle
        ; Subclass control and store pointer to original WindowProc
        $aHandle_Proc[$aHandle_Proc[0][0]][1] = _NoFocusLines_SubClass($hHandle, $pNoFocusLines_Proc)

        ; If error in subclassing then remove this control from the array
        If $aHandle_Proc[$aHandle_Proc[0][0]][1] = 0 Then $aHandle_Proc[0][0] -= 1

    Next

    ; Remove any empty elements after a ReDim
    ReDim $aHandle_Proc[$aHandle_Proc[0][0] + 1][2]

    ; Check if subclassing was successful
    If $aHandle_Proc[0][0] > 0 Then
        $aHandle_Proc[0][1] = "Local"
    Else
        ; Free WndProc memory
        DllCallbackFree($hNoFocusLines_Proc)
        $hNoFocusLines_Proc = 0
    EndIf

    Return $aHandle_Proc[0][0]

EndFunc   ;==>_NoFocusLines_Set

; #FUNCTION# =========================================================================================================
; Name...........: _NoFocusLines_Clear
; Description ...: Repermits the dotted focus lines on controls if previously prevented by _NoFocusLines_Set
; Syntax.........: _NoFocusLines_Clear($vCID)
; Parameters ....: $vCID - ControlIDs of control(s) - multiple ControlIDs must be passed as a 0-based array
;                  If no parameter passed, all previously set controls are reset
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns number of controls currently subclassed
;                  Failure:  Sets @error as follows:
;                  1 = Global function already run
;                  2 = Invalid controlID
; Author ........: Melba23, based on code from Siao, aec, martin and Yashied
; Remarks .......: If controls which have had focus lines removed by the _SET function are deleted before the script
;                  exits, it is advisable to use this function on them BEFORE deletion.
; Example........: Yes
;=====================================================================================================================
Func _NoFocusLines_Clear($vCID = "")

    Local $aCID[1]

    ; Check if Global function already used
    If $aHandle_Proc[0][1] = "Global" Then Return SetError(1, 0, 0)

    If $vCID = "" Then

        ; Reset all controls to original WndProc
        For $i = 1 To $aHandle_Proc[0][0]
            _NoFocusLines_SubClass($aHandle_Proc[$i][0], $aHandle_Proc[$i][1])
        Next

        ; Reset array
        Dim $aHandle_Proc[1][2] = [[0, "Local"]]

    Else

        ; Check parameters are valid
        If Not IsArray($vCID) Then
            If Not IsHWnd(GUICtrlGetHandle($vCID)) Then Return SetError(2, 0, 0)
            $aCID[0] = $vCID
        Else
            For $i = 0 To UBound($vCID) - 1
                If Not IsHWnd(GUICtrlGetHandle($vCID[$i])) Then Return SetError(2, 0, 0)
            Next
            $aCID = $vCID
        EndIf

        ; For each specified control
        For $j = 0 To UBound($aCID) - 1
            ; Run through array to see if control has been subclassed
            For $i = 1 To $aHandle_Proc[0][0]
                ; Control found
                If $aHandle_Proc[$i][0] = GUICtrlGetHandle($aCID[$j]) Then
                    ; Unsubclass the control
                    _NoFocusLines_SubClass($aHandle_Proc[$i][0], $aHandle_Proc[$i][1])
                    ; Remove control handle and orginal WindowProc from array
                    $aHandle_Proc[$i][0] = 0
                    $aHandle_Proc[$i][1] = 0
                EndIf
            Next
        Next

        ; Remove zeroed elements of array
        For $i = $aHandle_Proc[0][0] To 1 Step -1
            If $aHandle_Proc[$i][0] = 0 Then
                ; Reduce control count
                $aHandle_Proc[0][0] -= 1
                ; Move up all following elements
                For $j = $i To $aHandle_Proc[0][0]
                    $aHandle_Proc[$j][0] = $aHandle_Proc[$j + 1][0]
                    $aHandle_Proc[$j][1] = $aHandle_Proc[$j + 1][1]
                Next
            EndIf
        Next
        ReDim $aHandle_Proc[$aHandle_Proc[0][0] + 1][2]

    EndIf

    Return $aHandle_Proc[0][0]

EndFunc   ;==>_NoFocusLines_Clear

; #FUNCTION# ====================================================================================================================
; Name...........: _NoFocusLines_Exit
; Description ...: Resets any remaining subclassed controls and frees the memory used by the UDF created WndProc
; Syntax.........: _NoFocusLines_Exit()
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Remarks .......: This function should be called on exit to avoid reliance on internal AutoIt procedures for memory clean up
; Example........: Yes
;================================================================================================================================
Func _NoFocusLines_Exit()

    ; Check if _Set function used
    If $aHandle_Proc[0][1] <> "Local" Then Return SetError(1, 0, 0)

    ; First unsubclass any remaining subclassed controls
    _NoFocusLines_Clear()

    ; Now free UDF created WndProc
    DllCallbackFree($hNoFocusLines_Proc)

    Return 1

EndFunc   ;==>_NoFocusLines_Exit

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _NoFocusLines_Proc
; Description ...: Replacement WindowProc to prevent focus lines appearing on button and slider class controls
; Author ........: Melba23, based on code from Siao, aec, martin and Yashied
; Modified.......:
; Remarks .......: This function is used internally by _NoFocus_Set
; ===============================================================================================================================
Func _NoFocusLines_Proc($hWnd, $iMsg, $wParam, $lParam)

    ; Ignore SETFOCUS message from all subclassed controls
    If $iMsg = 0x0007 Then Return 0 ; $WM_SETFOCUS
    ; Locate control handle in array
    For $i = 1 To $aHandle_Proc[0][0]
        ; And pass other messages to original WindowProc
        If $hWnd = $aHandle_Proc[$i][0] Then Return _WinAPI_CallWindowProc($aHandle_Proc[$i][1], $hWnd, $iMsg, $wParam, $lParam)
    Next

EndFunc   ;==>_NoFocusLines_Proc

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _NoFocusLines_SubClass
; Description ...: Sets new WindowProc for controls
; Syntax ........: _NoFocusLines_SubClass($hWnd, $pNew_WindowProc)
; Parameters ....: $hWnd - Handle of control to subclass
;                  $pNew_WindowProc - Pointer to new WindowProc
; Author ........: Melba23, based on code from Siao, aec and martin
; Modified.......:
; Remarks .......: This function is used internally by _NoFocusLines_Set and _NoFocusLines_Clear
; ===============================================================================================================================
Func _NoFocusLines_SubClass($hWnd, $pNew_WindowProc)

    Local $iRes = _WinAPI_SetWindowLong($hWnd, -4, $pNew_WindowProc)
    If @error Then Return SetError(1, 0, 0)
    If $iRes = 0 Then Return SetError(1, 0, 0)
    Return $iRes

EndFunc   ;==>_NoFocusLines_SubClass

; #FUNCTION# ====================================================================================================================
; Name...........: _NoFocusLines_Global_Set
; Description ...: Prevents the dotted focus lines on ALL subsequently created button and slider class controls
; Syntax.........: _NoFocusLines_Global_Set()
; Requirement(s).: v3.3 +
; Return values .: Success:  1
;                  Failure:  0 and sets @error as follows:
;                  1 = Specific function already run
; Author ........: rover
; Remarks .......: The _Global Exit function should be called on script exit
; Note ..........; CAUTION is advised when using the _Global_Set function as even though the use of the _Global_Exit function on
;                  exit deletes all such controls and frees the memory used by the UDF, full clean up relies on internal AutoIt
;                  procedures.
; Example........: Yes
;================================================================================================================================
Func _NoFocusLines_Global_Set()

    ; Run once check
    If $aHandle_Proc[0][1] <> "" Then Return SetError(1, 0, 0)

    ; Create callback
    $hNoFocusLines_Proc = DllCallbackRegister("_NoFocusLines_Global_Proc", "int", "hwnd;uint;wparam;lparam")
    Local $pCallbackPtr = DllCallbackGetPtr($hNoFocusLines_Proc)

    ; Create temp gui with button and slider
    Local $hGUITemp = GUICreate("", 1, 1, -10, -10)
    Local $hButtonTemp = GUICtrlGetHandle(GUICtrlCreateButton("", -10, -10, 1, 1))
    Local $hSliderTemp = GUICtrlGetHandle(GUICtrlCreateSlider(-10, -10, 1, 1))

    ; Globally subclass Button class (includes buttons, radios and checkboxes)
    $pOrg_ButtonProc = DllCall("User32.dll", "dword", "SetClassLongW", "hwnd", $hButtonTemp, "int", -24, "ptr", $pCallbackPtr)
    $pOrg_ButtonProc = $pOrg_ButtonProc[0]

    ; Globally subclass Slider(Trackbar) class
    $pOrg_SliderProc = DllCall("User32.dll", "dword", "SetClassLongW", "hwnd", $hSliderTemp, "int", -24, "ptr", $pCallbackPtr)
    $pOrg_SliderProc = $pOrg_SliderProc[0]

    GUIDelete($hGUITemp)

    $aHandle_Proc[0][1] = "Global"

    Return SetError(0, 0, 1)

EndFunc   ;==>_NoFocusLines_Global_Set

; #FUNCTION# ====================================================================================================================
; Name...........: _NoFocusLines_Global_Exit
; Description ...: Deletes all controls and frees the memory used by the UDF created WndProc
; Syntax.........: _NoFocusLines_Global_Exit()
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Remarks .......: This function should be called on script exit if the _Global_Set function has been used
; Note ..........; CAUTION is advised as even though the use of the _Global_Exit function on exit deletes all controls and frees
;                  the memory used by the UDF, full clean up relies on internal AutoIt procedures.
; Example........: Yes
;================================================================================================================================
Func _NoFocusLines_Global_Exit()

    ; Check if _Set function used
    If $aHandle_Proc[0][1] <> "Global" Then Return SetError(1, 0, 0)

    ; First delete all controls - any subclassed controls are now deleted
    For $i = 3 To 65532
        GUICtrlDelete($i)
    Next

    ; Now free UDF created WndProc
    DllCallbackFree($hNoFocusLines_Proc)

    Return 1

EndFunc   ;==>_NoFocusLines_Global_Exit

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _NoFocusLines_AutoExit
; Description ...: Automatically deletes all controls and frees the memory used by the UDF created WndProc on exit
; Author ........: M23
; Modified.......:
; Remarks .......: This function is used internally by NoFocusLines
; ===============================================================================================================================
Func _NoFocusLines_AutoExit()

    Switch $aHandle_Proc[0][1]
        Case "Global"
            _NoFocusLines_Global_Exit()
        Case "Local"
            _NoFocusLines_Exit()
    EndSwitch

EndFunc

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _NoFocusLines_Global_Proc
; Description ...: Replacement WindowProc to prevent focus lines appearing on button and slider class controls
; Author ........: rover
; Modified.......:
; Remarks .......: This function is used internally by _NoFocusLines_Global_Set
; ===============================================================================================================================
Func _NoFocusLines_Global_Proc($hWnd, $iMsg, $wParam, $lParam)

    If $iMsg = 0x0007 Then Return 0 ; $WM_SETFOCUS
    Switch _WinAPI_GetClassName($hWnd)
        Case "Button"
            ; pass the unhandled messages to default ButtonProc
            Return _WinAPI_CallWindowProc($pOrg_ButtonProc, $hWnd, $iMsg, $wParam, $lParam)
        Case "msctls_trackbar32"
            ; pass the unhandled messages to default SliderProc
            Return _WinAPI_CallWindowProc($pOrg_SliderProc, $hWnd, $iMsg, $wParam, $lParam)
        Case Else
            Return 0
    EndSwitch

EndFunc   ;==>_NoFocusLines_Global_Proc

[NEW] And an example script to show it working - and to show it does not affect other aspects of the control behaviour. It assumes the include is in the same folder.

#include <GuiConstantsEx.au3>
#include <ButtonConstants.au3>
#include "NoFocusLines.au3"

Global $aCID[1]
$iPos_1 = 0
$iPos_2 = 0
$fGlobal = False

$hGUI = GUICreate("Choose Method", 200, 140)

$sMsg = "Choose how you want the focus lines to be removed:" & @CRLF & @CRLF & _
        "Global" & @TAB & "= All controls permanently" & @CRLF & _
        "Specific" & @TAB & "= By choice"
GUICtrlCreateLabel($sMsg, 10, 10, 180, 70)
$hRadio_1 = GUICtrlCreateRadio("Global",   10,  90, 90, 20)
$hRadio_2 = GUICtrlCreateRadio("Specific", 10, 110, 90, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$hButton_OK = GUICtrlCreateButton("OK", 110, 100, 80, 30)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hButton_OK
            ExitLoop
    EndSwitch

WEnd

; If required remove focus lines from all controls
If GUICtrlRead($hRadio_1) = $GUI_CHECKED Then
    If _NoFocusLines_Global_Set() = 1 Then $fGlobal = True
    ConsoleWrite("Global: " & @error & @CRLF)
EndIf

GUIDelete($hGUI)

$hGUI = GUICreate("Subclassed Controls without Focus Lines", 500, 210)

$hLabel_S1 = GUICtrlCreateLabel("Slider 1: " & $iPos_1, 20,  15, 100)
$hLabel_S2 = GUICtrlCreateLabel("Slider 2: " & $iPos_2, 20, 115, 100)

$hSlider_1 = GUICtrlCreateSlider(20,  50, 160, 30)
$hSlider_2 = GUICtrlCreateSlider(20, 150, 160, 30)

$hLabel_B1 = GUICtrlCreateLabel("", 200,  15, 80, 20)
$hLabel_B2 = GUICtrlCreateLabel("", 200, 115, 80, 20)

$hButton_1 = GUICtrlCreateButton("Button 1", 200,  50, 90, 30)
$hButton_2 = GUICtrlCreateButton("Button 2", 200, 150, 90, 30)

$hLabel_R1 = GUICtrlCreateLabel("", 300,  15, 80, 20)
$hLabel_R2 = GUICtrlCreateLabel("", 300, 115, 80, 20)

$hRadio_1 = GUICtrlCreateRadio("Radio 1", 300,  35, 90, 20)
$hRadio_2 = GUICtrlCreateRadio("Radio 2", 300, 135, 90, 20)

$hLabel_C1 = GUICtrlCreateLabel("", 300,  65, 80, 20)
$hLabel_C2 = GUICtrlCreateLabel("", 300, 165, 80, 20)

$hCheck_1 = GUICtrlCreateCheckbox("Check 1", 300,  85, 90, 20)
$hCheck_2 = GUICtrlCreateCheckbox("Check 2", 300, 185, 90, 20)



$hButton_Action = GUICtrlCreateButton("Hide upper control focus lines", 400,  45, 80, 50, $BS_MULTILINE)
$hButton_Tab    = GUICtrlCreateButton("Show all control focus lines",  400, 145, 80, 50, $BS_MULTILINE)

$hLabel_Global = GUICtrlCreateLabel("Global = " & $fGlobal, 400, 15, 100)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            #cs
            If $fGlobal = true Then
                _NoFocusLines_Global_Exit()
            Else
                _NoFocusLines_Exit()
            EndIf
            #ce
            Exit
        Case $hButton_1
            GUICtrlSetData($hLabel_B1, "Button pressed")
            Sleep(500)
            GUICtrlSetData($hLabel_B1, "")
        Case $hButton_2
            GUICtrlSetData($hLabel_B2, "Button pressed")
            Sleep(500)
            GUICtrlSetData($hLabel_B2, "")
        Case $hRadio_1
            If GUICtrlRead($hRadio_1) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_R1, "Selected")
                GUICtrlSetData($hLabel_R2, "")
            Else
                GUICtrlSetData($hLabel_R2, "Selected")
                GUICtrlSetData($hLabel_R1, "")
            EndIf
        Case $hRadio_2
            If GUICtrlRead($hRadio_2) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_R2, "Selected")
                GUICtrlSetData($hLabel_R1, "")
            Else
                GUICtrlSetData($hLabel_R1, "Selected")
                GUICtrlSetData($hLabel_R2, "")
            EndIf
        Case $hCheck_1
            If GUICtrlRead($hCheck_1) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_C1, "Selected")
            Else
                GUICtrlSetData($hLabel_C1, "")
            EndIf
        Case $hCheck_2
            If GUICtrlRead($hCheck_2) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_C2, "Selected")
            Else
                GUICtrlSetData($hLabel_C2, "")
            EndIf
        Case $hButton_Action
            ; Remove focus lines from slider_1
            _NoFocusLines_Set($hSlider_1)
            ConsoleWrite("Slider: " & @error & @CRLF)

            ; Remove focus lines from top button, radio and checkbox
            Dim $aCID[4] = [$hButton_1, $hRadio_1, $hCheck_1, $hButton_Action] ; Place multiple ControlIDs in an array
            _NoFocusLines_Set($aCID)
            ConsoleWrite("Button: " & @error & @CRLF)

            ; Shows it will not work if used with other control type
            _NoFocusLines_Set($hLabel_B1)
            ConsoleWrite("Label:  " & @error & @CRLF)

            ; Show Global function will not work after Specific, or previous Global, call
            _NoFocusLines_Global_Set()
            ConsoleWrite("Global: " & @error & @CRLF)

        Case $hButton_Tab
            ; Force focus lines to appear
            Send("{TAB}")
            ; Allow lines to appear
            Dim $aCID[5] = [$hSlider_1, $hButton_1, $hRadio_1, $hCheck_1, $hButton_Action]
            _NoFocusLines_Clear($aCID)
            ConsoleWrite("Clear:  " & @error & @CRLF)

    EndSwitch

    If GUICtrlRead($hSlider_1) <> $iPos_1 Then
        $iPos_1 = GUICtrlRead($hSlider_1)
        GUICtrlSetData($hLabel_S1, "Slider 1: " & $iPos_1)
    EndIf

    If GUICtrlRead($hSlider_2) <> $iPos_2 Then
        $iPos_2 = GUICtrlRead($hSlider_2)
        GUICtrlSetData($hLabel_S2, "Slider 2: " & $iPos_2)
    EndIf

WEnd

On running the example script you are asked to choose either "Global" or "Specific" mode:

"Global" mode permanently prevents focus lines on all controls - there is no easy way to reallow the lines (or at least one I am prepared to develop!).

"Specific" mode allows you to prevent/allow the focus lines on specified controls. At first, as long as you only use the mouse to change focus you should find no focus lines on the controls - because a button is present. Pressing the "Show all focus lines" button, or pressing TAB yourself to change focus, will allow the lines become visible when the control has focus - remember you still have to select the sliders with the mouse, they have no TABSTOP property. Pressing the "Hide upper" button will, not surprisingly, prevent the lines from appearing on the top set of controls (if one of these controls has focus at that time, the lines will remain until the focus is changed - obviously we cannot intercept a previous message!). Repressing the "Show all focus lines" button will reallow focus lines on the upper controls. You can toggle the lines on and off as often as you wish.

The 2 modes are obviously mutually exclusive - but the UDF will automatically detect the first mode used and prevent the other from running. This can be seen as the example script runs and the various errorlevels from the UDF calls made are printed in the SciTE console.

A few points:

1. As previously stated, the _NoFocusLines_Global function can only be called once - BEFORE any controls are created. The _NoFocusLines_Set and _NoFocusLines_Clear functions can be called as and when required - but only AFTER the specified controls have been created.

2. When you want to delete controls which have been subclassed by _NoFocusLines_Set before the script exits, you should use _NoFocusLines_Clear before deleting - just in case Windows reallocates the handle. [NEW] Calling _NoFocusLines_Clear with no parameter resets all currently subclassed controls without having to specify the ControlIDs.

3. [NEW] In either mode, on finally exiting the script, AutoIt will run the cleanup script to delete all subclassed controls and free the memory used by the UDF created WndProc.

4. The "Specific" mode functions require the ControlIDs in array format if there is more than one. I accept that this means having to declare an array just to use the function, but I could not think of any other way to get an undefined number of parameters into the function.

5. The code uses _WinAPI_SetWindowLong, which according to MSDN means that it will not work on x64 systems. If anyone wants to modify the code for x64, please do so.

[NEW] Here are the 2 files in zip form: NoFocusLines.zip

Just to reiterate my thanks to Siao, aec and martin, whose basic code I plundered without pity; Yashied, whose "hint" made the whole UDF much better; rover for the "Global" mode code; and Valik for advice on the exit strategy. :D "Standing on the shoulders of giants", as Newton once put it, always makes life easier!

As always, happy to hear comments and suggestions. :D

M23

Edited by Melba23

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

Nice UDF, Melba23, well done.

One question. Why did you do separate functions for Buttons and Sliders? They have little different from each other. In my opinion, you can to combine them into one function, such as _GUICtrlFocusDisable(). You can also add other controls such as Combo, Checkbox, Radio, etc. Anyway, 5* from me for useful and easy to use UDF.

Link to comment
Share on other sites

  • Moderators

Yashied,

Thanks for the compliments.

During the research I did for this UDF, I came to the conclusion that each type of control had a specific WindowProc. I could not think of a way to use a common intercept of the WM_SETFOCUS message and then redirect other messages to the correct WindowProc without a lot of overhead. My thinking was that I would have to do something like this:

Func _NoFocusLinesProc($hWnd, $iMsg, $wParam, $lParam)

    ;If SETFOCUS message
    If $iMsg = $WM_SETFOCUS Then Return 0
    ; Pass other messages to their original WindowProc
    ; Determine the control type (I presume one of parameters will do this - after some massaging!)
    Switch "control type"
        Case "Button"
            Return _WinAPI_CallWindowProc($pOriginal_ButtonProc, $hWnd, $iMsg, $wParam, $lParam)
        Case "msctls_trackbar32"
            Return _WinAPI_CallWindowProc($pOriginal_SliderProc, $hWnd, $iMsg, $wParam, $lParam)
        ; and so on.....

I thought this was getting a bit too complicated - and I was in deep enough water anyway!

By the way, the Button function also works for Radios and Checkboxes as stated in the header. I did find that they used the same WindowProc - rather to my surprise. :D

I freely admit I am a long way from my normal habitat here :D - if I misunderstood the WindowProc situation or you have a good idea of how to modify the curent code, I woudl be delighted to hear it. You have probably forgotten more about this stuff than I ever knew!

M23

Edit: speeling

Edited by Melba23

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

Hint:

Dim $aWnd[1][2] = [0]

#cs

$aWnd[0][0] - Count item of array
     [0][2] - Don`t used
     
$hkTb[i][0] - Handle to the window (control)
     [i][1] - Handle to the default window proc

#ce

...

Func _WndProc($hWnd, $iMsg, $wParam, $lParam)
    If $iMsg = $WM_SETFOCUS Then
        Return 0
    EndIf
    For $i = 1 To $aWnd[0][0]
        If $hWnd = $aWnd[$i][0] Then
            Return _WinAPI_CallWindowProc($aWnd[$i][1], $hWnd, $iMsg, $wParam, $lParam)
        EndIf
    Next
EndFunc   ;==>_WndProc
Link to comment
Share on other sites

Greetings Melba23 and Yashied

hope you don't mind me posting this example in your thread :D

it uses global subclassing of the button and trackbar classes

so all subsequently created button and slider controls do not have a focus rectangle

you could incorporate this idea into your UDF

SetClassLongPtr for 64 bit OS (MSDN says for 32 and 64 bit compatibility, but not available in XP (Vista, Win 7))

#include-once
#include <GUIConstantsEX.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <WinAPI.au3>


;Global subclass vars
Global Const $GCL_WNDPROC = -24
Global $hNew_ControlProc = 0, $pOriginal_SliderProc, $pOriginal_ButtonProc

;must be run before any buttons or sliders created
_ControlGlobalSubclass()
;all subsequently created buttons and sliders will be subclassed
;individual controls original wndproc cannot be restored without side effects (e.g. text corruption on buttons)


$iPos_1 = 0
$iPos_2 = 0

$hGUI = GUICreate("Globally Subclassed Controls without Focus Lines", 500, 210)

$hLabel_S1 = GUICtrlCreateLabel("Slider 1: " & $iPos_1, 20, 15, 200)
$hLabel_S2 = GUICtrlCreateLabel("Slider 2: " & $iPos_2, 20, 115, 200)

$hSlider_1 = GUICtrlCreateSlider(20, 50, 160, 30)
$hSlider_2 = GUICtrlCreateSlider(20, 150, 160, 30)

$hLabel_B1 = GUICtrlCreateLabel("", 200, 15, 80, 20)
$hLabel_B2 = GUICtrlCreateLabel("", 200, 115, 80, 20)

$hButton_1 = GUICtrlCreateButton("Button 1", 200, 50, 90, 30)
$hButton_2 = GUICtrlCreateButton("Button 2", 200, 150, 90, 30)

$hLabel_R1 = GUICtrlCreateLabel("", 300, 15, 80, 20)
$hLabel_R2 = GUICtrlCreateLabel("", 300, 115, 80, 20)

$hRadio_1 = GUICtrlCreateRadio("Radio 1", 300, 35, 90, 20)
$hRadio_2 = GUICtrlCreateRadio("Radio 2", 300, 135, 90, 20)

$hLabel_C1 = GUICtrlCreateLabel("", 300, 65, 80, 20)
$hLabel_C2 = GUICtrlCreateLabel("", 300, 165, 80, 20)

$hCheck_1 = GUICtrlCreateCheckbox("Check 1", 300, 85, 90, 20)
$hCheck_2 = GUICtrlCreateCheckbox("Check 2", 300, 185, 90, 20)

$hButton_Action = GUICtrlCreateButton("Prevent upper control focus lines", 400, 45, 80, 50, $BS_MULTILINE)
$hButton_Tab = GUICtrlCreateButton("Force focus lines to appear", 400, 145, 80, 50, $BS_MULTILINE)

GUISetState()

Sleep(2000)
GUICtrlDelete($hButton_Action)
Sleep(1000)
$hButton_Action = GUICtrlCreateButton("Prevent upper control focus lines", 400, 45, 80, 50, $BS_MULTILINE)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ; Must delete subclassed controls before freeing DLLCallbacks <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            GUIDelete($hGUI)
            ; Now free DLLCallbacks - not strictly necessary, but "good idea" according to Help file <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            DllCallbackFree($hNew_ControlProc)
            Exit
        Case $hButton_1
            GUICtrlSetData($hLabel_B1, "Button pressed")
            Sleep(500)
            GUICtrlSetData($hLabel_B1, "")
        Case $hButton_2
            GUICtrlSetData($hLabel_B2, "Button pressed")
            Sleep(500)
            GUICtrlSetData($hLabel_B2, "")
        Case $hRadio_1
            If GUICtrlRead($hRadio_1) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_R1, "Selected")
                GUICtrlSetData($hLabel_R2, "")
            Else
                GUICtrlSetData($hLabel_R2, "Selected")
                GUICtrlSetData($hLabel_R1, "")
            EndIf
        Case $hRadio_2
            If GUICtrlRead($hRadio_2) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_R2, "Selected")
                GUICtrlSetData($hLabel_R1, "")
            Else
                GUICtrlSetData($hLabel_R1, "Selected")
                GUICtrlSetData($hLabel_R2, "")
            EndIf
        Case $hCheck_1
            If GUICtrlRead($hCheck_1) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_C1, "Selected")
            Else
                GUICtrlSetData($hLabel_C1, "")
            EndIf
        Case $hCheck_2
            If GUICtrlRead($hCheck_2) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_C2, "Selected")
            Else
                GUICtrlSetData($hLabel_C2, "")
            EndIf
        Case $hButton_Tab
            ; Force focus lines to appear
            Send("{TAB}")
    EndSwitch

    If GUICtrlRead($hSlider_1) <> $iPos_1 Then
        $iPos_1 = GUICtrlRead($hSlider_1)
        GUICtrlSetData($hLabel_S1, "Slider 1: " & $iPos_1)
    EndIf

    If GUICtrlRead($hSlider_2) <> $iPos_2 Then
        $iPos_2 = GUICtrlRead($hSlider_2)
        GUICtrlSetData($hLabel_S2, "Slider 2: " & $iPos_2)
    EndIf

WEnd

Func _ControlGlobalSubclass()
    ;run once check
    If $hNew_ControlProc <> 0 Then Return SetError(1, 0, 0)

    ;create temp gui for button and slider
    Local $hGUITemp = GUICreate("", 1, 1, -10, -10)

    ;create temporary button
    Local $hButtonTemp = GUICtrlGetHandle(GUICtrlCreateButton("", -10, -10, 1, 1))

    ;create temporary slider
    Local $hSliderTemp = GUICtrlGetHandle(GUICtrlCreateSlider(-10, -10, 1, 1))

    ;create callback
    $hNew_ControlProc = DllCallbackRegister("_WndProc", "int", "hwnd;uint;wparam;lparam")
    Local $pCallbackPtr = DllCallbackGetPtr($hNew_ControlProc)

    ;Globally subclass Button class
    ;set wndproc for button class WndClassEx struct
    $pOriginal_ButtonProc = DllCall("User32.dll", "dword", "SetClassLongW", "hwnd", $hButtonTemp, "int", $GCL_WNDPROC, "ptr", $pCallbackPtr)
    $pOriginal_ButtonProc = $pOriginal_ButtonProc[0]

    ;Globally subclass Slider(Trackbar) class
    ;set wndproc for Slider class WndClassEx struct
    $pOriginal_SliderProc = DllCall("User32.dll", "dword", "SetClassLongW", "hwnd", $hSliderTemp, "int", $GCL_WNDPROC, "ptr", $pCallbackPtr)
    $pOriginal_SliderProc = $pOriginal_SliderProc[0]

    ;destroy temporary gui, button and slider controls
    GUIDelete($hGUITemp)
    Return SetError(0, 0, 1)
EndFunc   ;==>_ControlGlobalSubclass

Func _WndProc($hWnd, $iMsg, $wParam, $lParam)
    If $iMsg = $WM_SETFOCUS Then Return 0
    Switch _WinAPI_GetClassName($hWnd)
        Case "Button"
            ; pass the unhandled messages to default ButtonProc
            Return _WinAPI_CallWindowProc($pOriginal_ButtonProc, $hWnd, $iMsg, $wParam, $lParam)
        Case "msctls_trackbar32"
            ; pass the unhandled messages to default SliderProc
            Return _WinAPI_CallWindowProc($pOriginal_SliderProc, $hWnd, $iMsg, $wParam, $lParam)
        Case Else
            Return 0
    EndSwitch
EndFunc   ;==>_WndProc
Edited by rover

I see fascists...

Link to comment
Share on other sites

  • Moderators

rover,

I knew someone would come along and spoil my fun! :D

Seriously, that is an excellent piece of code which really does the job without the inconveniences of clearing the subclassing if you have to delete the control prior to the script exiting.

Thank you for sharing it.

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

Link to comment
Share on other sites

  • Moderators

Yashied,

I think we can easily combine the 2 approaches. Then the user has a choice of how to proceed.

I will work on it over the next few days when I get a chance - pretty full diary for an old(ish) man! :D

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

  • Moderators

New version of the UDF now available in the first post.

2 modes now available:

"Global" prevents focus lines on all button and slider controls created in the script.

"Specific" mode permits the lines to be prevented/allowed on specified controls.

The first post has a full explanation and code.

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

  • 4 weeks later...
  • Moderators

New version in first post.

Changes: Added _Exit functions to reset/delete subclassed controls and restore WndProc memory.

More details in the first post and UDF itself.

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

  • 1 month later...

New version in first post.

Changes: Added _Exit functions to reset/delete subclassed controls and restore WndProc memory.

More details in the first post and UDF itself.

M23

You rock! I now have half a clue on how sub-classing works because of this example.

:) <-- Well, not graduated yet, but not failing the class anymore!

;)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • Moderators

PSaltyDS,

I am flattered - thank you.

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

  • 7 months later...

I edited the example to include TabSheets and it works fine, but I can't figure out how to do it on a simple form with just TabSheets.

; Updated to include TabSheets

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GuiConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <TabConstants.au3>
#include <WindowsConstants.au3>
#include <NoFocusLines.au3>
#include <Constants.au3>
#include <WinAPI.au3>

Global $aCID[1]
$iPos_1 = 0
$iPos_2 = 0
$fGlobal = False

$hGUI = GUICreate("Choose Method", 200, 140)

$sMsg = "Choose how you want the focus lines to be removed:" & @CRLF & @CRLF & _
        "Global" & @TAB & "= All controls permanently" & @CRLF & _
        "Specific" & @TAB & "= By choice"
GUICtrlCreateLabel($sMsg, 10, 10, 180, 70)
$hRadio_1 = GUICtrlCreateRadio("Global", 10, 90, 90, 20)
$hRadio_2 = GUICtrlCreateRadio("Specific", 10, 110, 90, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$hButton_OK = GUICtrlCreateButton("OK", 110, 100, 80, 30)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hButton_OK
            ExitLoop
    EndSwitch

WEnd

If GUICtrlRead($hRadio_1) = $GUI_CHECKED Then

    ; Remove focus lines from all controls
    ConsoleWrite("Setting Global NoFocusLines" & @CRLF)
    If _NoFocusLines_Global_Set() = 1 Then $fGlobal = True
    ConsoleWrite("Global Error: " & @error & @CRLF)

EndIf

GUIDelete($hGUI)

$hGUI = GUICreate("Subclassed Controls without Focus Lines", 500, 230)

$Tab1 = GUICtrlCreateTab(2, 2, 496, 220, $TCS_MULTILINE)
GUICtrlSetResizing(-1, $GUI_DOCKWIDTH+$GUI_DOCKHEIGHT)
$TabSheet1 = GUICtrlCreateTabItem("TabSheet1")

$hLabel_S1 = GUICtrlCreateLabel("Slider 1: " & $iPos_1, 20, 45, 100)
$hLabel_S2 = GUICtrlCreateLabel("Slider 2: " & $iPos_2, 20, 145, 100)

$hSlider_1 = GUICtrlCreateSlider(20, 60, 160, 30)
$hSlider_2 = GUICtrlCreateSlider(20, 160, 160, 30)

$hLabel_B1 = GUICtrlCreateLabel("", 200, 25, 80, 20)
$hLabel_B2 = GUICtrlCreateLabel("", 200, 125, 80, 20)

$hButton_1 = GUICtrlCreateButton("Button 1", 200, 60, 90, 30)
$hButton_2 = GUICtrlCreateButton("Button 2", 200, 160, 90, 30)

$hLabel_R1 = GUICtrlCreateLabel("", 300, 25, 80, 20)
$hLabel_R2 = GUICtrlCreateLabel("", 300, 125, 80, 20)

$hRadio_1 = GUICtrlCreateRadio("Radio 1", 300, 45, 90, 20)
$hRadio_2 = GUICtrlCreateRadio("Radio 2", 300, 145, 90, 20)

$hLabel_C1 = GUICtrlCreateLabel("", 300, 75, 80, 20)
$hLabel_C2 = GUICtrlCreateLabel("", 300, 175, 80, 20)

$hCheck_1 = GUICtrlCreateCheckbox("Check 1", 300, 95, 90, 20)
$hCheck_2 = GUICtrlCreateCheckbox("Check 2", 300, 195, 90, 20)

$hButton_Action = GUICtrlCreateButton("Hide upper control focus lines", 400, 45, 80, 50, $BS_MULTILINE)
$hButton_Tab = GUICtrlCreateButton("Show all control focus lines", 400, 145, 80, 50, $BS_MULTILINE)

$hLabel_Global = GUICtrlCreateLabel("Global = " & $fGlobal, 400, 25, 100)

$TabSheet2 = GUICtrlCreateTabItem("TabSheet2")

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            If $fGlobal Then
                _NoFocusLines_Global_Exit()
            Else
                _NoFocusLines_Exit()
            EndIf
            Exit
        Case $hButton_1
            GUICtrlSetData($hLabel_B1, "Button pressed")
            Sleep(500)
            GUICtrlSetData($hLabel_B1, "")
        Case $hButton_2
            GUICtrlSetData($hLabel_B2, "Button pressed")
            Sleep(500)
            GUICtrlSetData($hLabel_B2, "")
        Case $hRadio_1
            If GUICtrlRead($hRadio_1) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_R1, "Selected")
                GUICtrlSetData($hLabel_R2, "")
            Else
                GUICtrlSetData($hLabel_R2, "Selected")
                GUICtrlSetData($hLabel_R1, "")
            EndIf
        Case $hRadio_2
            If GUICtrlRead($hRadio_2) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_R2, "Selected")
                GUICtrlSetData($hLabel_R1, "")
            Else
                GUICtrlSetData($hLabel_R1, "Selected")
                GUICtrlSetData($hLabel_R2, "")
            EndIf
        Case $hCheck_1
            If GUICtrlRead($hCheck_1) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_C1, "Selected")
            Else
                GUICtrlSetData($hLabel_C1, "")
            EndIf
        Case $hCheck_2
            If GUICtrlRead($hCheck_2) = $GUI_CHECKED Then
                GUICtrlSetData($hLabel_C2, "Selected")
            Else
                GUICtrlSetData($hLabel_C2, "")
            EndIf
        Case $hButton_Action

            ; Force focus lines to appear
            Send("{TAB}")

            ConsoleWrite("Setting NoFocusLines" & @CRLF)

            ; Remove focus lines from slider_1
            _NoFocusLines_Set($hSlider_1)
            ConsoleWrite("Slider Error: " & @error & @CRLF)

            ; Remove focus lines from top button, radio and checkbox
            Dim $aCID[4] = [$hButton_1, $hRadio_1, $hCheck_1, $hButton_Action] ; Place multiple ControlIDs in an array
            _NoFocusLines_Set($aCID)
            ConsoleWrite("Button Error: " & @error & @CRLF)

            ; Shows it will not work if used with other control type
            _NoFocusLines_Set($hLabel_B1)
            ConsoleWrite("Label Error:  " & @error & @CRLF)

            ; Show Global function will not work after Specific, or previous Global, call
            _NoFocusLines_Global_Set()
            ConsoleWrite("Global Error: " & @error & @CRLF)

        Case $hButton_Tab

            ConsoleWrite("Clearing NoFocusLines" & @CRLF)

            ; Force focus lines to appear
            Send("{TAB}")
            ; Allow lines to appear
            Dim $aCID[5] = [$hSlider_1, $hButton_1, $hRadio_1, $hCheck_1, $hButton_Action]
            _NoFocusLines_Clear($aCID)
            ConsoleWrite("Clear Error:  " & @error & @CRLF)

    EndSwitch

    If GUICtrlRead($hSlider_1) <> $iPos_1 Then
        $iPos_1 = GUICtrlRead($hSlider_1)
        GUICtrlSetData($hLabel_S1, "Slider 1: " & $iPos_1)
    EndIf

    If GUICtrlRead($hSlider_2) <> $iPos_2 Then
        $iPos_2 = GUICtrlRead($hSlider_2)
        GUICtrlSetData($hLabel_S2, "Slider 2: " & $iPos_2)
    EndIf

WEnd

I've tried putting the function call in various locations with no positive results. Can someone point out where I'm going wrong?

#include <GuiConstants.au3>
#include <NoFocusLines.au3>

$Form1 = GUICreate("NoFocusLines on TabSheets Example", 494, 351, -1, -1)
$Tab1 = GUICtrlCreateTab(16, 8, 465, 329)
GUICtrlSetResizing(-1, $GUI_DOCKWIDTH+$GUI_DOCKHEIGHT)
$TabSheet1 = GUICtrlCreateTabItem("TabSheet1")
$TabSheet2 = GUICtrlCreateTabItem("TabSheet2")
$TabSheet3 = GUICtrlCreateTabItem("TabSheet3")
$TabSheet4 = GUICtrlCreateTabItem("TabSheet4")
$TabSheet5 = GUICtrlCreateTabItem("TabSheet5")
GUICtrlCreateTabItem("")
GUISetState(@SW_SHOW)

While 1
    _NoFocusLines_Global_Set()
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            _NoFocusLines_Global_Exit()
        Exit
    EndSwitch
WEnd

Agreement is not necessary - thinking for one's self is!

My-Colors.jpg

cuniform2.gif

Link to comment
Share on other sites

  • Moderators

Fossil Rock,

I edited the example to include TabSheets and it works fine

Are you trying to remove the focus lines from the tab controls? Because you do not in either example - nor would I expect you to succeed! :P

Your examples do not work as the only controls subclassed by the UDF are of the "Button" and "msctls_trackbar32" classes. Tab controls are from the "SysTabControl32" class and so the UDF has no effect upon them.

I will look and see if I can do anything to modify the UDF to cover tabs - but no promises. :mellow:

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

Fossil Rock,

Are you trying to remove the focus lines from the tab controls? Because you do not in either example - nor would I expect you to succeed! :P

Your examples do not work as the only controls subclassed by the UDF are of the "Button" and "msctls_trackbar32" classes. Tab controls are from the "SysTabControl32" class and so the UDF has no effect upon them.

I will look and see if I can do anything to modify the UDF to cover tabs - but no promises. :mellow:

M23

Oddly enough, the modified script does work (sort of) on Windows 7 & using the latest version of AutoIt. Can't explain it, but I can see the difference.

post-9237-12777141953824_thumb.png

While it's running, the focus lines do not appear, but when I do an ALT+PRNTSCRN the lines appear when pasted in Paint. I tried again with just a PRNTSCRN (full screen) and the lines did not appear (odd).

I appreciate whatever you can do to add the TabSheets to your already brilliant UDF.

Agreement is not necessary - thinking for one's self is!

My-Colors.jpg

cuniform2.gif

Link to comment
Share on other sites

  • Moderators

Fossil Rock,

Weird! Certainly does not do that in Vista! :mellow:

OK, I think I have it working in part. There is still a problem with the tab headers - the lines return if you tab to a previously open header. I think it is because the Tab control sends additional messages to the TabItems inside it which will need to be trapped as well. I will investigate further.

Here is a zip file with the modified UDF and 2 examples - one Global, one individual:NoFocus_Test.zip

Please let me know how they work for you. :P

M23

Edit: I am not sure there is a great deal of difference in focus line behaviour with or without the UDF. :party: The tab control seems to set its internal focus via a different message. I am burrowing in MSDN, but I am getting more and more confused (not very difficult! :party: ).

Edited by Melba23

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

  • 1 month later...

Finally got around to testing and it seems to work flawlessly... thanks.

Fossil Rock,

Weird! Certainly does not do that in Vista! ;)

OK, I think I have it working in part. There is still a problem with the tab headers - the lines return if you tab to a previously open header. I think it is because the Tab control sends additional messages to the TabItems inside it which will need to be trapped as well. I will investigate further.

Here is a zip file with the modified UDF and 2 examples - one Global, one individual:NoFocus_Test.zip

Please let me know how they work for you. :)

M23

Edit: I am not sure there is a great deal of difference in focus line behaviour with or without the UDF. ;) The tab control seems to set its internal focus via a different message. I am burrowing in MSDN, but I am getting more and more confused (not very difficult! :P ).

Agreement is not necessary - thinking for one's self is!

My-Colors.jpg

cuniform2.gif

Link to comment
Share on other sites

  • 5 months later...
  • Moderators

Hi,

Updated version now available in first post.

Uses OnAutoItExitRegister to clear up - no longer any need to use the relevant _Exit function in your code. :)

Note you need AutoIt v3.3.4 or better to use this. ;)

M23

Edit: Fixed tags

Edited by Melba23

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

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