Jump to content

Recommended Posts

Posted (edited)

 SciTE_OverlayTab

Highlighting the active & unsaved tab item in SciTE

Inspired from  211131-highlighting-the-active-tab-item-in-scite/    (Thanks to BugFix 🏆

While the original was excellent, I found that I needed  to change some things.
Since I made these adjustments, I decided to share the revised code.

; https://www.autoitscript.com/forum/topic/213330-scite_overlaytab/
;--------------------------------------------------------------------------------------------------------------------------------
; Title...........: SciTE_OverlayTab.au3
; Description.....: Highlighting the active & unsaved tab item in SciTE
; AutoIt Version..: 3.3.18.0   Author: ioa747           Script Version: 0.4
; Note............: Testet in Windows 11 Pro 24H2       Date:17/11/2025
; Inspired by.....: https://www.autoitscript.com/forum/topic/211131-highlighting-the-active-tab-item-in-scite
;--------------------------------------------------------------------------------------------------------------------------------
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <GuiTab.au3>
#include <Misc.au3>
#include <WinAPISysWin.au3>
#include <WindowsStylesConstants.au3>

Opt('TrayIconHide', 1)

_Singleton(@ScriptName)

OnAutoItExitRegister(_Exit)

; Colors Const
Global Const $g_hActiveColor = 0x0026FF  ; 0x0026FF Blue
Global Const $g_hUnSavedColor = 0xFF6A00 ; 0xFF6A00 Orange
Global Const $g_iOpacity = 40            ; Set Overlay transparency to 40% opacity

; Global Variables
Global $g_aOverlayHwnd[0]        ; Array to store Hwnd of the overlays. Index in this array corresponds to the SciTE tab index.
Global $g_SciTE_Handle = WinGetHandle('[CLASS:SciTEWindow]')
If @error Then Exit

;~ While True
    While WinExists($g_SciTE_Handle)
        _SciTEState()
        Sleep(250)
    WEnd
;~  Sleep(1000)
;~  $g_SciTE_Handle = WinGetHandle('[CLASS:SciTEWindow]')
;~ WEnd

;---------------------------------------------------------------------------------------
Func _Exit()
    _DestroyAllOverlays()  ; Destroy all overlays
    Exit
EndFunc   ;==>_Exit
;---------------------------------------------------------------------------------------
Func _SciTEState()
    ; Retrieve the state of the SciTEWindow.
    Local $iState = WinGetState($g_SciTE_Handle)
    Switch $iState
        Case 15, 47 ; exists+visible+enabled+active +maximized
            _UpdateTabOverlays()
        Case Else
            Sleep(250)
    EndSwitch
EndFunc
;---------------------------------------------------------------------------------------
Func _UpdateTabOverlays()
    Local $hTab = _GetHwnd_SciTeTabCtrl()
    Local $iOldCount = UBound($g_aOverlayHwnd)

    If @error Then
        ; If the Tab Control is lost, destroy all existing overlays.
        If $iOldCount > 0 Then _DestroyAllOverlays()
        Return SetError(1)
    EndIf

    Local $iActive = _GUICtrlTab_GetCurFocus($hTab)
    Local $iCount = _GUICtrlTab_GetItemCount($hTab)

    If $iCount = 0 Then
        ; If the Tab Control is found but contains zero tabs, we must clean up any remaining overlays.
        If $iOldCount > 0 Then _DestroyAllOverlays()
        Return SetError(2)
    EndIf

    ; Array Cleanup and Resize
    If $iCount < $iOldCount Then
        ; Tab count decreased: Destroy overlays corresponding to the missing tabs (from iCount up to iOldCount-1)
        For $i = $iCount To $iOldCount - 1
            If IsHWnd($g_aOverlayHwnd[$i]) Then GUIDelete($g_aOverlayHwnd[$i])
        Next
        ReDim $g_aOverlayHwnd[$iCount] ; Resize the array to the new, smaller tab count
    ElseIf $iCount > $iOldCount Then
        ReDim $g_aOverlayHwnd[$iCount] ; Tab count increased: Resize the array to accommodate new tabs
    EndIf

    ; Update/Create necessary overlays
    For $i = 0 To $iCount - 1
        Local $sItemText = _GUICtrlTab_GetItemText($hTab, $i)
        Local $tRect = _GUICtrlTab_GetItemRectEx($hTab, $i)
        Local $iColor = 0 ; 0 means no custom coloring is needed (Saved & Inactive)
        Local $hOverlay = $g_aOverlayHwnd[$i] ; Get the existing handle

        If $i = $iActive Then
            $iColor = $g_hActiveColor  ; Active Tab
        ElseIf StringRight($sItemText, 1) = '*' Then
            $iColor = $g_hUnSavedColor ; Unsaved Tab
        EndIf

        If $iColor <> 0 Then
            ; Create or Update Overlay
            $g_aOverlayHwnd[$i] = _CreateOrUpdateOverlay($hTab, $i, $tRect, $iColor, $hOverlay)
        Else
            ; Destroy unnecessary overlay (if it's saved and inactive)
            If IsHWnd($hOverlay) Then
                GUIDelete($hOverlay)
                $g_aOverlayHwnd[$i] = 0 ; Reset array element
            EndIf
        EndIf
    Next
EndFunc   ;==>_UpdateTabOverlays
;---------------------------------------------------------------------------------------
Func _CreateOrUpdateOverlay($hTab, $iIndex, $tRectItem, $iColor, $hExistingOverlay)
    ; Calculates coordinates and creates/updates the transparent GUI.
    Local $iLeft = $tRectItem.Left
    Local $iTop = $tRectItem.Top
    Local $iWidth = $tRectItem.Right - $tRectItem.Left
    Local $iHeight = $tRectItem.Bottom - $tRectItem.Top

    Local $tPoint = DllStructCreate("int X;int Y")
    DllStructSetData($tPoint, "X", $iLeft)
    DllStructSetData($tPoint, "Y", $iTop)

    ; Convert client coordinates (relative to hTab) to screen coordinates
    _WinAPI_ClientToScreen($hTab, $tPoint)
    Local $iScrX = $tPoint.X
    Local $iScrY = $tPoint.Y

    Local $hOverlay = $hExistingOverlay

    If Not IsHWnd($hOverlay) Then
        ; Create the overlay GUI
        Local $sTitle = 'OverlayTab_' & $iIndex
        $hOverlay = GUICreate($sTitle, $iWidth, $iHeight, $iScrX, $iScrY, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_NOACTIVATE, $WS_EX_TRANSPARENT), $hTab)
        GUISetBkColor($iColor)
        WinSetTrans($hOverlay, "", $g_iOpacity)    ; Set transparency to 40% opacity
        GUISetState(@SW_SHOWNOACTIVATE, $hOverlay) ; Show without activating
    Else
        ; Update existing overlay GUI
        WinMove($hOverlay, "", $iScrX, $iScrY, $iWidth, $iHeight) ; Move and resize it
        GUISetBkColor($iColor, $hOverlay) ; Update color
    EndIf
    Return $hOverlay
EndFunc   ;==>_CreateOrUpdateOverlay
;---------------------------------------------------------------------------------------
Func _DestroyAllOverlays()
    ; Destroys all currently tracked overlay GUIs.
    For $i = 0 To UBound($g_aOverlayHwnd) - 1
        Local $hOverlay = $g_aOverlayHwnd[$i]
        If IsHWnd($hOverlay) Then GUIDelete($hOverlay)
    Next
    ReDim $g_aOverlayHwnd[0] ; Reset the array
EndFunc   ;==>_DestroyAllOverlays
;---------------------------------------------------------------------------------------
Func _GetHwnd_SciTeTabCtrl()
    ; Local $hScite = WinGetHandle('[CLASS:SciTEWindow]')
    ; If @error Then Return SetError(1, 0, Null)
    Local $aChild, $hWndTab = Null
    $aChild = _WinAPI_EnumChildWindows($g_SciTE_Handle)
    If Not @error Then
        For $i = 1 To $aChild[0][0]
            If $aChild[$i][1] = "SciTeTabCtrl" Then
                $hWndTab = $aChild[$i][0]
                ExitLoop
            EndIf
        Next
    EndIf
    Return SetError(($hWndTab = Null ? 1 : 0), 0, $hWndTab)
EndFunc   ;==>_GetHwnd_SciTeTabCtrl
;---------------------------------------------------------------------------------------

 

Please, every comment is appreciated!
leave your comments and experiences here!
Thank you very much  :)

 

Edited by ioa747

I know that I know nothing

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
×
×
  • Create New...