ioa747 Posted November 20, 2025 Posted November 20, 2025 (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. What's New Spoiler Version: 0.7 Feature: New "Significant" Tab Marking: Introduced a new visual layer to mark important tabs. Significant tabs are now highlighted with a 3px Purple top bar for quick identification. Added Ctrl+Shift+6 shortcut to instantly toggle the "Significant" status on the currently focused tab. Version: 0.8 Performance: I added an extra layer to the site's activity control to reduce processor activity. Version: 0.9 Fix: Resolved x64 memory alignment issues in TCITEM structure (manual 4-byte padding). Performance: Added State Signature Check (Checksum) to prevent redundant UI updates. Performance: Implemented Static Variable caching for process handles and memory allocation. Feature: Smart Garbage Collection for the Significant Tabs Map. Version: 0.10 Feature: DPI Awareness: added DPI Awareness to ensure overlays align correctly. Bugfix: I made LastState Global, so I can update it externally as well. Version: 0.11 Feature: Dynamic DPI Awareness alignment based on scite Awareness Version: 0.12 Feature: Architecture Selector: Runs on x86 or x64 depending on SciTE. Feature: State Management: Two colors (Purple, Ctrl+Shift+6 | Green, Ctrl+Shift+7) with smart toggle/switch. Feature: Proportional UI: The "Significant" line breathes with the Tab, change from 3 pixels to 0.15 ratio Version: 1.0 Performance: Change the approach, that reads the tabs from the Buffers menu now and not from the tabs, so to have the full path Feature: control to enable/disable HotKeys when scite is enabled/disabled Feature: Feature: added Ctrl+E HotKey in scite to open file location in Explorer (to overcome the problem that if a script is running, scite's OpenFileLocation option is disabled) Version: 1.1 Optimization: Added high-frequency update loop (Turbo Mode) for smooth overlay tracking during window move/resize. SciTE_OverlayTab.au3 expandcollapse popup; 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: 1.1 ; Note............: Testet in Windows 11 Pro 24H2 Date:27/03/2026 ; New Layer added (Significant 1) toggled with Ctrl+Shift+6 ; New Layer added (Significant 2) toggled with Ctrl+Shift+7 ;-------------------------------------------------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ;~ #AutoIt3Wrapper_UseX64=y #include <GuiTab.au3> #include <Misc.au3> #include <WinAPISysWin.au3> #include <WindowsStylesConstants.au3> #include <WinAPIProc.au3> #include <WinAPIMem.au3> #include <WinAPIGdiDC.au3> #include <GuiMenu.au3> Opt('TrayIconHide', 1) _Singleton(@ScriptName) Global $g_SciTE_Handle = _SciTE_ArchSlector() Global Const $g_hActiveColor = 0x0026FF ; Blue for active Global Const $g_hUnSavedColor = 0xFF6A00 ; Orange for not stored Global Const $g_hSign1Color = 0x800080 ; Purple for Significant 1 Global Const $g_hSign2Color = 0x007F0E ; Green for Significant 2 Global Const $g_iOpacity = 50 ; Background transparency Global Const $g_fTopBarRatio = 0.15 ; Significant line thickness Global $g_aOverlayHwnd[0] Global $g_aSigOverlayHwnd[0] Global $g_mSignificant[] Global $g_mSignColor[] Global $g_sLastState = "" Global $g_iActive Global $g_aItems ; === HotKeySet -> _EnableHotKey(True/False) === ; Ctrl+Shift+6 toggled Significant groub1 ; Ctrl+Shift+7 toggled Significant groub2 ; Ctrl+E Open File Location in Explorer OnAutoItExitRegister(_Exit) _EnableHighDPI(_GetProcessDPIAwarenessLevel($g_SciTE_Handle)) While WinExists($g_SciTE_Handle) ; Update only if SciTE is visible/active _SciTEState() Sleep(100) WEnd ;--------------------------------------------------------------------------------------- Func _SciTEState() ; Retrieve the state of the SciTEWindow. Local $iState = WinGetState($g_SciTE_Handle) Switch $iState Case 15, 47 ; exists+visible+enabled+active +maximized _EnableHotKey(True) _UpdateTabOverlays() Case Else _EnableHotKey(False) Sleep(500) EndSwitch EndFunc ;==>_SciTEState ;--------------------------------------------------------------------------------------- Func _UpdateTabOverlays() Local $hTab = ControlGetHandle($g_SciTE_Handle, "", "SciTeTabCtrl1") If @error Then Return Local $aPos = WinGetPos($g_SciTE_Handle) Local $sSciTEPosition = $aPos[0] & "|" & $aPos[1] & "|" & $aPos[2] & "|" & $aPos[3] Local $iCount = _GUICtrlTab_GetItemCount($hTab) $g_iActive = _GUICtrlTab_GetCurFocus($hTab) $g_aItems = _GetSciTE_Buffers() ; get Items from Buffers menu ; State Signature: 'C:\Path\To\File.au3|1|8|3|100|100|800|600' ; [Path | Dirty | TabCount | ActiveIdx | X | Y | W | H] Local $sCurrentState = $g_aItems[$g_iActive][0] & "|" & $g_aItems[$g_iActive][1] $sCurrentState &= "|" & $iCount & "|" & $g_iActive $sCurrentState &= "|" & $sSciTEPosition If $sCurrentState = $g_sLastState Then Return $g_sLastState = $sCurrentState ; ConsoleWrite("$sCurrentState=" & $sCurrentState & @CRLF) ; Synchronize tables if the number of Tabs changes If $iCount <> UBound($g_aOverlayHwnd) Then _CleanupOverlays() ReDim $g_aOverlayHwnd[$iCount] ReDim $g_aSigOverlayHwnd[$iCount] EndIf Local $sNewSciTEPosition = $sSciTEPosition Do ; move/resize high-frequency update loop. $sSciTEPosition = $sNewSciTEPosition For $i = 0 To $iCount - 1 Local $tRect = _GUICtrlTab_GetItemRectEx($hTab, $i) ; Active/Unsaved Overlay Local $iBgColor = 0 If $i = $g_iActive Then $iBgColor = $g_hActiveColor ElseIf $g_aItems[$i][1] Then $iBgColor = $g_hUnSavedColor EndIf $g_aOverlayHwnd[$i] = _ManageOverlay($hTab, $tRect, $iBgColor, $g_aOverlayHwnd[$i], False) ; Significant Overlay If MapExists($g_mSignificant, $g_aItems[$i][0]) Then $g_aSigOverlayHwnd[$i] = _ManageOverlay($hTab, $tRect, $g_mSignColor[$g_aItems[$i][0] & "_Color"], $g_aSigOverlayHwnd[$i], True) Else If IsHWnd($g_aSigOverlayHwnd[$i]) Then GUIDelete($g_aSigOverlayHwnd[$i]) EndIf Next Sleep(10) $aPos = WinGetPos($g_SciTE_Handle) $sNewSciTEPosition = $aPos[0] & "|" & $aPos[1] & "|" & $aPos[2] & "|" & $aPos[3] Until $sSciTEPosition = $sNewSciTEPosition _CleanSignificantMap() EndFunc ;==>_UpdateTabOverlays ;--------------------------------------------------------------------------------------- Func _CleanSignificantMap() If UBound($g_mSignificant) = 0 Then Return Local $aKeys = MapKeys($g_mSignificant) For $sKey In $aKeys Local $bFound = False For $i = 0 To UBound($g_aItems) - 1 If $g_aItems[$i][0] == $sKey Then $bFound = True ExitLoop EndIf Next If Not $bFound Then MapRemove($g_mSignificant, $sKey) MapRemove($g_mSignColor, $sKey & "_Color") EndIf Next EndFunc ;==>_CleanSignificantMap ;--------------------------------------------------------------------------------------- Func _ManageOverlay($hTab, $tRect, $iColor, $hExisting, $bIsTopBar) If $iColor = 0 Then If IsHWnd($hExisting) Then GUIDelete($hExisting) Return 0 EndIf ; Prepare point structure for coordinate conversion Local $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $tRect.Left) DllStructSetData($tPoint, "Y", $tRect.Top) ; Convert Tab's client coordinates to absolute screen coordinates ; Since we are DPI Aware, this returns physical pixels _WinAPI_ClientToScreen($hTab, $tPoint) Local $iX = DllStructGetData($tPoint, "X") Local $iY = DllStructGetData($tPoint, "Y") ; Calculate width and height directly from the Rect structure Local $iW = $tRect.Right - $tRect.Left Local $iH = $tRect.Bottom - $tRect.Top If $bIsTopBar Then $iH = Int($iH * $g_fTopBarRatio) If $iH < 2 Then $iH = 2 EndIf Local $hOverlay = $hExisting If Not IsHWnd($hOverlay) Then ; Create the overlay window $hOverlay = GUICreate("", $iW, $iH, $iX, $iY, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_NOACTIVATE, $WS_EX_TRANSPARENT), $hTab) GUISetBkColor($iColor) WinSetTrans($hOverlay, "", ($bIsTopBar ? 150 : $g_iOpacity)) GUISetState(@SW_SHOWNOACTIVATE, $hOverlay) Else ; If it already exists, just move and resize WinMove($hOverlay, "", $iX, $iY, $iW, $iH) GUISetBkColor($iColor, $hOverlay) EndIf Return $hOverlay EndFunc ;==>_ManageOverlay ;--------------------------------------------------------------------------------------- Func _CleanupOverlays() For $i = 0 To UBound($g_aOverlayHwnd) - 1 GUIDelete($g_aOverlayHwnd[$i]) GUIDelete($g_aSigOverlayHwnd[$i]) Next EndFunc ;==>_CleanupOverlays ;--------------------------------------------------------------------------------------- Func _Exit() _CleanupOverlays() Exit EndFunc ;==>_Exit ;--------------------------------------------------------------------------------------- Func _GetProcessDPIAwarenessLevel($hWnd) Local $iPID _WinAPI_GetWindowThreadProcessId($hWnd, $iPID) Local $hProcess = DllCall("kernel32.dll", "ptr", "OpenProcess", "dword", 0x0400, "bool", False, "dword", $iPID) ; PROCESS_QUERY_INFORMATION If @error Or Not $hProcess[0] Then Return SetError(@error, 1, -2) ; 0 = Unaware, 1 = System Aware, 2 = Per Monitor Aware Local $aRet = DllCall("Shcore.dll", "long", "GetProcessDpiAwareness", "ptr", $hProcess[0], "int*", 0) _WinAPI_CloseHandle($hProcess[0]) If @error Then Return SetError(@error, 2, -2) Switch $aRet[2] Case 0 ; PROCESS_DPI_UNAWARE ; ConsoleWrite("PROCESS_DPI_UNAWARE -1" & @CRLF) Return -1 Case 1 ; PROCESS_SYSTEM_DPI_AWARE ; ConsoleWrite("PROCESS_SYSTEM_DPI_AWARE -2" & @CRLF) Return -2 Case 2 ; PROCESS_PER_MONITOR_DPI_AWARE ; ConsoleWrite("PROCESS_PER_MONITOR_DPI_AWARE -4" & @CRLF) Return -4 Case Else ; ConsoleWrite("Else -> PROCESS_SYSTEM_DPI_AWARE -2" & @CRLF) Return -2 EndSwitch EndFunc ;==>_GetProcessDPIAwarenessLevel ;--------------------------------------------------------------------------------------- Func _EnableHighDPI($Awareness = -2) Local $hUser32 = DllOpen("user32.dll") Local $aRet = DllCall($hUser32, "bool", "SetProcessDpiAwarenessContext", "int_ptr", $Awareness) ; Fallback to basic DPI Awareness If @error Or Not $aRet[0] Then DllCall($hUser32, "bool", "SetProcessDPIAware") EndIf DllClose($hUser32) EndFunc ;==>_EnableHighDPI ;--------------------------------------------------------------------------------------- Func _SciTE_ArchSlector() Local $hSciTE = WinGetHandle('[CLASS:SciTEWindow]') If Not $hSciTE Then Exit Local $iPID _WinAPI_GetWindowThreadProcessId($hSciTE, $iPID) ; 2. ARCHITECTURE CHECK: Is SciTE 64-bit? Local $bSciTEIs64 = False If @OSArch = "X64" Then If Not _WinAPI_IsWow64Process($iPID) Then $bSciTEIs64 = True EndIf ; If SciTE is 64-bit but the script runs as 32-bit (or vice versa), restart to the correct one! If ($bSciTEIs64 And Not @AutoItX64) Or (Not $bSciTEIs64 And @AutoItX64) Then Local $sAutoItExe = $bSciTEIs64 ? StringReplace(@AutoItExe, "AutoIt3.exe", "AutoIt3_x64.exe") : StringReplace(@AutoItExe, "_x64.exe", ".exe") ; ConsoleWrite("$sAutoItExe=" & $sAutoItExe & @CRLF) If FileExists($sAutoItExe) Then Exit ShellExecute($sAutoItExe, '"' & @ScriptFullPath & '"') * 0 + 1 EndIf EndIf Return $hSciTE EndFunc ;==>_SciTE_ArchSlector ;--------------------------------------------------------------------------------------- Func _GetSciTE_Buffers() Local $iStart = 5, $iSubItem = 7 Local $hMenu = _GUICtrlMenu_GetMenu($g_SciTE_Handle) Local $hSubMenu = _GUICtrlMenu_GetItemSubMenu($hMenu, $iSubItem) Local $sCount = _GUICtrlMenu_GetItemCount($hSubMenu) If $sCount <= $iStart Then Local $aEmpty[1][2] = [["", 0]] Return $aEmpty EndIf Local $aResult[$sCount - $iStart][2] Local $sName, $idx For $i = $iStart To $sCount - 1 $idx = $i - $iStart $sName = _GUICtrlMenu_GetItemText($hSubMenu, $i) $aResult[$idx][1] = 0 ; not dirty If StringLeft($sName, 1) = "&" Then $sName = StringTrimLeft($sName, 3) If StringRight($sName, 1) = "*" Then $sName = StringTrimRight($sName, 2) $aResult[$idx][1] = 1 ; dirty EndIf $aResult[$idx][0] = $sName Next Return $aResult EndFunc ;==>_GetSciTE_Buffers ;--------------------------------------------------------------------------------------- Func _EnableHotKey($bEnable = True) Local Static $bHotKeyStatus If $bHotKeyStatus = $bEnable Then Return $bHotKeyStatus = $bEnable If $bEnable Then HotKeySet("^+6", "_ToggleSignificant") ; <<--( toggled Significant with Ctrl+Shift+6 )--<< HotKeySet("^+7", "_ToggleSignificant") ; <<--( toggled Significant with Ctrl+Shift+7 )--<< HotKeySet("^e", "_OpenFileLocation") ; <<--( Open File Location in Explorer with Ctrl+E )--<< Else HotKeySet("^+6") HotKeySet("^+7") HotKeySet("^e") EndIf EndFunc ;==>_EnableHotKey ;--------------------------------------------------------------------------------------- Func _ToggleSignificant() Local $iColor Switch @HotKeyPressed Case "^+6" $iColor = $g_hSign1Color Case "^+7" $iColor = $g_hSign2Color EndSwitch Local $sID = $g_aItems[$g_iActive][0] If MapExists($g_mSignificant, $sID) Then If $g_mSignColor[$sID & "_Color"] = $iColor Then MapRemove($g_mSignificant, $sID) MapRemove($g_mSignColor, $sID & "_Color") Else $g_mSignificant[$sID] = True $g_mSignColor[$sID & "_Color"] = $iColor EndIf Else $g_mSignificant[$sID] = True $g_mSignColor[$sID & "_Color"] = $iColor EndIf $g_sLastState = "update" EndFunc ;==>_ToggleSignificant ;--------------------------------------------------------------------------------------- Func _OpenFileLocation() If FileExists($g_aItems[$g_iActive][0]) Then Run('explorer.exe /select, "' & $g_aItems[$g_iActive][0] & '"') EndIf EndFunc ;==>_OpenFileLocation ;--------------------------------------------------------------------------------------- Please, every comment is appreciated! leave your comments and experiences here! Thank you very much Edited 11 hours ago by ioa747 Version: 1.1 donnyh13, UEZ and argumentum 3 I know that I know nothing
ioa747 Posted March 22 Author Posted March 22 (edited) What's New in Version 0.7 New "Significant" Tab Marking: Introduced a new visual layer to mark important tabs. Significant tabs are now highlighted with a 3px Purple top bar for quick identification. Added Ctrl+Shift+6 shortcut to instantly toggle the "Significant" status on the currently focused tab. Update to Version 0.8 I added an extra layer to the site's activity control to reduce processor activity. Edited March 22 by ioa747 donnyh13 1 I know that I know nothing
UEZ Posted March 22 Posted March 22 (edited) I'm getting a crash AutoIt3 ended. rc:-1073740940 when starting it as x64 execution. x86 runs properly. I must add a Sleep(10) to the _ManageOverlay() function. I don't know why but the Tab blue rectangle was topmost painted althouth SciTE was in the background. Just wondering why SciTE doesn't have this feature already onboard... Edited March 22 by UEZ ioa747 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
ioa747 Posted Sunday at 11:25 PM Author Posted Sunday at 11:25 PM (edited) I prefer to run it on x86, and I didn't encounter any problems. But I also tried it on x64, without Sleep(10), and I didn't encounter any problems here either. (not even with the blue rectangle) Can I ask what version of AutoIt and what version of SciTE you're running? My combination AutoIt Version..: 3.3.18.0 SciTE, 32-bit, Version 4.4.6, Mar 12 2022 10:14:43 Windows 11 Pro, Version 25H2 Edited Monday at 05:38 AM by ioa747 add AutoIt too I know that I know nothing
UEZ Posted Monday at 03:28 PM Posted Monday at 03:28 PM I'm using the x64 version of SciTE -> Version 5.5.8 Scintilla:5.5.8 Lexilla:5.4.6 Jan 12 2026 12:26:07 Autoit: 3.3.18.0 Win: 24H2 ioa747 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
bladem2003 Posted Monday at 03:45 PM Posted Monday at 03:45 PM (edited) When you call _GUICtrlTab_GetItemText, then _GUICtrlTab_GetItem is called that crashe on x64. The error does not always occur. https://www.autoitscript.com/forum/topic/213108-_guictrltab_getitemtext-the-target-crashes-on-dissimilar-architecture/ Edited Monday at 03:49 PM by bladem2003 ioa747 1
ioa747 Posted Monday at 04:30 PM Author Posted Monday at 04:30 PM I have the impression that this was fixed in Autoit version: 3.3.18.0 I also tried it on x64, and I didn't encounter any problems here either. with AutoIt Version..: 3.3.18.0 SciTE, 64-bit, Version 5.5.8 Windows 11 Pro, Version 25H2 I know that I know nothing
bladem2003 Posted Monday at 05:21 PM Posted Monday at 05:21 PM This bug drove me crazy, I couldn't find the error in one of my scripts for a long time. The bug still exists in version 3.3.18.0.
UEZ Posted Tuesday at 09:27 PM Posted Tuesday at 09:27 PM (edited) Can somebody test if this works? SciTeTabHook (I create two small DLLs (x86/x64) to hook SciTE which is apparently not possible using Autoit due to Memory Barrier / Local Address limits) It should work with SciTE x86/x64. It is important to run AutoIt on the same architecture as SciTE! Tray icon can be used to close Autoit script. Thx. @ioa747 sorry for hijacking your thread, but this fits in well here. Edited Tuesday at 09:30 PM by UEZ ioa747 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
ioa747 Posted Tuesday at 10:15 PM Author Posted Tuesday at 10:15 PM (edited) @UEZ Τhere is no problem, and I am still looking for it I think the problem is in the function __GUICtrl_TagOutProcess which is called internally by _GUICtrlTab_GetItem While the function correctly scales pointers to UINT64 for x64 targets, it completely ignores Structure Alignment/Padding requirements. In x64 architecture, a 64-bit pointer must be aligned to an 8-byte boundary. Current Logic: uint Mask (4); uint State (4); uint StateMask (4); ptr pszText (8) -> Puts pszText at Offset 12. Windows x64 Requirement: Requires 4 bytes of padding after StateMask to align pszText at Offset 16. (I think, it's at the limit of my knowledge) and based on this logic I proceeded to an bypass of _GUICtrlTab_GetItem -> __GUICtrl_TagOutProcess to see what happens expandcollapse popup; 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.10 ; Note............: Testet in Windows 11 Pro 24H2 Date:22/03/2026 ; New Layer added (Significant) toggled with Ctrl+Shift+6 ;-------------------------------------------------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ;~ #AutoIt3Wrapper_UseX64=y #include <GuiTab.au3> #include <Misc.au3> #include <WinAPISysWin.au3> #include <WindowsStylesConstants.au3> #include <WinAPIProc.au3> #include <WinAPIMem.au3> Opt('TrayIconHide', 1) _Singleton(@ScriptName) DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext", "int_ptr", -2) Global Const $g_hActiveColor = 0x0026FF ; Blue for active Global Const $g_hUnSavedColor = 0xFF6A00 ; Orange for not stored Global Const $g_hSignificantColor = 0x800080 ; Purple for Significant Global Const $g_iOpacity = 50 ; Background transparency Global Const $g_iTopBarHeight = 3 ; Significant line thickness Global $g_aOverlayHwnd[0] Global $g_aItemsText[0] Global $g_aSigOverlayHwnd[0] Global $g_mSignificant[] Global $g_SciTE_Handle = WinGetHandle('[CLASS:SciTEWindow]') Global $g_sLastState = "" If Not $g_SciTE_Handle Then Exit HotKeySet("^+6", "_ToggleSignificant") ; <<--( toggled Significant with Ctrl+Shift+6 )--<< OnAutoItExitRegister(_Exit) While WinExists($g_SciTE_Handle) ; Update only if SciTE is visible/active _SciTEState() Sleep(100) WEnd ;--------------------------------------------------------------------------------------- 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(1000) EndSwitch EndFunc ;==>_SciTEState ;--------------------------------------------------------------------------------------- Func _UpdateTabOverlays() Local $hTab = _GetHwnd_SciTeTabCtrl() If @error Then Return Local $iCount = _GUICtrlTab_GetItemCount($hTab) Local $iActive = _GUICtrlTab_GetCurFocus($hTab) Local $aPos = WinGetPos($g_SciTE_Handle) ; State Signature: '&6 SciTE_OverlayTab.au3|6|5|280|0|1647|1039' Local $sCurrentState = _SciTE_GetTabText($hTab, $iActive) $sCurrentState &= "|" & $iCount & "|" & $iActive $sCurrentState &= "|" & $aPos[0] & "|" & $aPos[1] & "|" & $aPos[2] & "|" & $aPos[3] If $sCurrentState = $g_sLastState Then Return $g_sLastState = $sCurrentState ; Synchronize tables if the number of Tabs changes If $iCount <> UBound($g_aOverlayHwnd) Then _CleanupOverlays() ReDim $g_aOverlayHwnd[$iCount] ReDim $g_aSigOverlayHwnd[$iCount] ReDim $g_aItemsText[$iCount] EndIf For $i = 0 To $iCount - 1 Local $sRawText = _SciTE_GetTabText($hTab, $i) Local $sCleanID = _GetCleanTabID($sRawText) Local $tRect = _GUICtrlTab_GetItemRectEx($hTab, $i) $g_aItemsText[$i] = $sCleanID ; Active/Unsaved Overlay Local $iBgColor = 0 If $i = $iActive Then $iBgColor = $g_hActiveColor ElseIf StringRight($sRawText, 1) = '*' Then $iBgColor = $g_hUnSavedColor EndIf $g_aOverlayHwnd[$i] = _ManageOverlay($hTab, $tRect, $iBgColor, $g_aOverlayHwnd[$i], False) ; Significant Overlay If MapExists($g_mSignificant, $sCleanID) Then $g_aSigOverlayHwnd[$i] = _ManageOverlay($hTab, $tRect, $g_hSignificantColor, $g_aSigOverlayHwnd[$i], True) Else If IsHWnd($g_aSigOverlayHwnd[$i]) Then _DeleteHandle($g_aSigOverlayHwnd[$i]) EndIf Next _CleanSignificantMap() EndFunc ;==>_UpdateTabOverlays ;--------------------------------------------------------------------------------------- Func _GetCleanTabID($sText) If StringLeft($sText, 1) = "&" Then $sText = StringTrimLeft($sText, 3) If StringRight($sText, 1) = "*" Then $sText = StringTrimRight($sText, 2) Return $sText EndFunc ;==>_GetCleanTabID ;--------------------------------------------------------------------------------------- Func _CleanSignificantMap() If UBound($g_mSignificant) = 0 Then Return Local $aKeys = MapKeys($g_mSignificant) For $sKey In $aKeys Local $bFound = False For $i = 0 To UBound($g_aItemsText) - 1 If $g_aItemsText[$i] == $sKey Then $bFound = True ExitLoop EndIf Next If Not $bFound Then MapRemove($g_mSignificant, $sKey) Next EndFunc ;==>_CleanSignificantMap ;--------------------------------------------------------------------------------------- Func _ToggleSignificant() Local $hTab = _GetHwnd_SciTeTabCtrl() If @error Then Return Local $sID = _GetCleanTabID(_SciTE_GetTabText($hTab, _GUICtrlTab_GetCurFocus($hTab))) If MapExists($g_mSignificant, $sID) Then MapRemove($g_mSignificant, $sID) Else $g_mSignificant[$sID] = True EndIf $g_sLastState = "?" EndFunc ;==>_ToggleSignificant ;--------------------------------------------------------------------------------------- Func _ManageOverlay($hTab, $tRect, $iColor, $hExisting, $bIsTopBar) If $iColor = 0 Then If IsHWnd($hExisting) Then _DeleteHandle($hExisting) Return 0 EndIf Local $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $tRect.Left) DllStructSetData($tPoint, "Y", $tRect.Top) _WinAPI_ClientToScreen($hTab, $tPoint) Local $iX = DllStructGetData($tPoint, "X") Local $iY = DllStructGetData($tPoint, "Y") Local $iW = $tRect.Right - $tRect.Left Local $iH = ($bIsTopBar ? $g_iTopBarHeight : ($tRect.Bottom - $tRect.Top)) Local $hOverlay = $hExisting If Not IsHWnd($hOverlay) Then $hOverlay = GUICreate("", $iW, $iH, $iX, $iY, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_NOACTIVATE, $WS_EX_TRANSPARENT), $hTab) GUISetBkColor($iColor) WinSetTrans($hOverlay, "", ($bIsTopBar ? 150 : $g_iOpacity)) GUISetState(@SW_SHOWNOACTIVATE, $hOverlay) Else WinMove($hOverlay, "", $iX, $iY, $iW, $iH) GUISetBkColor($iColor, $hOverlay) EndIf Return $hOverlay EndFunc ;==>_ManageOverlay ;--------------------------------------------------------------------------------------- Func _DeleteHandle(ByRef $hWnd) GUIDelete($hWnd) $hWnd = 0 EndFunc ;==>_DeleteHandle ;--------------------------------------------------------------------------------------- Func _CleanupOverlays() For $i = 0 To UBound($g_aOverlayHwnd) - 1 _DeleteHandle($g_aOverlayHwnd[$i]) _DeleteHandle($g_aSigOverlayHwnd[$i]) Next EndFunc ;==>_CleanupOverlays ;--------------------------------------------------------------------------------------- Func _GetHwnd_SciTeTabCtrl() Local $hTabCtrl = ControlGetHandle($g_SciTE_Handle, "", "SciTeTabCtrl1") If @error Then Return SetError(1, 0, Null) Return $hTabCtrl EndFunc ;==>_GetHwnd_SciTeTabCtrl ;--------------------------------------------------------------------------------------- Func _Exit() _CleanupOverlays() Exit EndFunc ;==>_Exit ;--------------------------------------------------------------------------------------- Func _SciTE_GetTabText($hTab, $iIndex) ; Static variables - Allocated ONLY ONCE Local Static $hProcess = 0 Local Static $bIsTarget64 = False Local Static $pRemoteText = 0 Local Static $pRemoteItem = 0 Local Static $sTag = "" Local Static $bInitialized = False Local Static $tLocalItem = 0 Local Static $iMaxLen = 512 ; === Initialization Block: Runs ONLY ONCE === If Not $bInitialized Then Local $iPID _WinAPI_GetWindowThreadProcessId($hTab, $iPID) $hProcess = _WinAPI_OpenProcess(BitOR($PROCESS_VM_OPERATION, $PROCESS_VM_READ, $PROCESS_VM_WRITE, $PROCESS_QUERY_INFORMATION), False, $iPID) If Not $hProcess Then Return "" If @OSArch = "X64" Then If Not _WinAPI_IsWow64Process($iPID) Then $bIsTarget64 = True EndIf $pRemoteText = _MemVirtualAllocEx($hProcess, 0, $iMaxLen * 2, $MEM_COMMIT, $PAGE_READWRITE) ; Define proper struct with padding for x64 alignment $sTag = $bIsTarget64 ? _ "struct;uint Mask;uint State;uint StateMask;uint Padding;ptr Text;int TextMax;int Image;int Padding2;int64 Param;endstruct" : _ "struct;uint Mask;uint State;uint StateMask;uint TextPtr;int TextMax;int Image;uint Param;endstruct" $tLocalItem = DllStructCreate($sTag) $pRemoteItem = _MemVirtualAllocEx($hProcess, 0, DllStructGetSize($tLocalItem), $MEM_COMMIT, $PAGE_READWRITE) $bInitialized = True EndIf ; === Fast Execution Block: Minimal CPU cycles === DllStructSetData($tLocalItem, "Mask", 1) ; $TCIF_TEXT If $bIsTarget64 Then DllStructSetData($tLocalItem, "Text", $pRemoteText) Else DllStructSetData($tLocalItem, "TextPtr", $pRemoteText) EndIf DllStructSetData($tLocalItem, "TextMax", $iMaxLen) ; Write the local struct to the pre-allocated remote memory _WinAPI_WriteProcessMemory($hProcess, $pRemoteItem, DllStructGetPtr($tLocalItem), DllStructGetSize($tLocalItem), 0) ; Request data from SciTE (0x133C = TCM_GETITEMW) Local $iRet = _SendMessage($hTab, 0x133C, $iIndex, $pRemoteItem) Local $sText = "" If $iRet Then Local $tResult = DllStructCreate("wchar[" & $iMaxLen & "]") _WinAPI_ReadProcessMemory($hProcess, $pRemoteText, DllStructGetPtr($tResult), $iMaxLen * 2, 0) $sText = DllStructGetData($tResult, 1) EndIf Return $sText EndFunc ;==>_SciTE_GetTabText ;--------------------------------------------------------------------------------------- Edited Wednesday at 01:17 AM by ioa747 Script Version: 0.10 - LastState as Global argumentum and UEZ 1 1 I know that I know nothing
argumentum Posted Tuesday at 10:41 PM Posted Tuesday at 10:41 PM (edited) < All fixed in v0.11. Removed the images to save on forum disk space > ...reporting from a browser in Miami, this was @argumentum. Back to you.. Edited Wednesday at 02:44 PM by argumentum ioa747 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
ioa747 Posted Wednesday at 09:22 AM Author Posted Wednesday at 09:22 AM Update to Version: 0.11 Feature: Dynamic DPI Awareness alignment based on scite Awareness @argumentum please try it ...need a reliable beta tester UEZ and argumentum 1 1 I know that I know nothing
UEZ Posted Wednesday at 11:59 AM Posted Wednesday at 11:59 AM Looks good now - no x64 crash and DPI seems to work, too. ioa747 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
water Posted Wednesday at 01:23 PM Posted Wednesday at 01:23 PM I tested version 0.11 (both compiled as 32 and 64 bit) on Windows 11 Home 25H2. Everything works fine 👍 ioa747 1 My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
argumentum Posted Wednesday at 02:35 PM Posted Wednesday at 02:35 PM Excellent !. Brilliant ! Spoiler Note: The above French and British is because in the US those languages are "superior". Didn't use Spanish or Italian because, too sexy ioa747 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted Wednesday at 03:02 PM Posted Wednesday at 03:02 PM ... _Singleton(@ScriptName) While Not WinExists(WinGetHandle('[CLASS:SciTEWindow]')) ; added this.. Sleep(2000) WEnd ... While WinExists($g_SciTE_Handle) ; Update only if SciTE is visible/active _SciTEState() Sleep(100) WEnd ShellExecute(@AutoItExe, '"' & @ScriptFullPath & '"') ; ..because of the self restart =) ... That way it's always on. Note: don't do what I do. Am dangerous ( because am lazy ) 😅 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted Wednesday at 03:27 PM Posted Wednesday at 03:27 PM (edited) oops. I think is all good 😅 Spoiler ..interesting: Spoiler ... ;~ Opt('TrayIconHide', 1) TraySetIcon(StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1) - 1) & "\SciTE\SciTE.exe", 0) TraySetToolTip(@ScriptName & ' - ' & (@AutoItX64 ? "x64" : "x86") & @LF & "SciTE not loaded" & @LF & " ") _Singleton(@ScriptName) While Not WinExists(WinGetHandle('[CLASS:SciTEWindow]')) Sleep(2000) WEnd ... _EnableHighDPI(_GetProcessDPIAwarenessLevel($g_SciTE_Handle)) TraySetToolTip(@ScriptName & ' - ' & (@AutoItX64 ? "x64" : "x86") & @LF & "DPI_AWARE: " & _GetProcessDPIAwarenessLevel($g_SciTE_Handle) & @LF & " ") While WinExists($g_SciTE_Handle) ; Update only if SciTE is visible/active _SciTEState() Sleep(100) WEnd ShellExecute(@AutoItExe, '"' & @ScriptFullPath & '"') ... I did more to my edit than what I showed. I first tested on a remote desktop via RDP. And the prior versions didn't show the DPI mishap and toying with the tray icon I saw that on my hardware PC it shows DPI awareness -4 and that makes sense but the RDP one shows -1 🤔 Don't know how the OS does anything but ... this is something that had no clue would be like that. It all works great in v0.11. But I wanted to share this because I just did not know: Why did v0.7 worked on the RDP session and not on the local one, and now I know Note: limited testing on a single monitor RDP. Would have to dig deeper on "Use all my monitors for the remote session" but am not that curious. Edit1: Did not try on the same version of SciTE 😕 Edit2: ...on RDP Ctrl+Shift+6 does the above on "Version 5.5.6 Scintilla:5.5.6 Lexilla:5.4.4 Jun 5 2025 10:01:05 " Edited Wednesday at 04:08 PM by argumentum oops Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
ioa747 Posted Wednesday at 03:56 PM Author Posted Wednesday at 03:56 PM I discovered it and that's why I did it Feature: Dynamic DPI Awareness alignment based on scite Awareness argumentum 1 I know that I know nothing
argumentum Posted Wednesday at 03:58 PM Posted Wednesday at 03:58 PM ..updated my prior report Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted Wednesday at 04:05 PM Posted Wednesday at 04:05 PM (edited) ..lol, that happens running as x86. As x64 works well 🤷♂️ I guess it needs to match x86/x86 and x64/x64 🤔 Edited Wednesday at 04:06 PM by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now