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) 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.0 ; 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 $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 &= "|" & $aPos[0] & "|" & $aPos[1] & "|" & $aPos[2] & "|" & $aPos[3] 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 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 _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 ;--------------------------------------------------------------------------------------- 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 ;--------------------------------------------------------------------------------------- Please, every comment is appreciated! leave your comments and experiences here! Thank you very much Edited 12 hours ago by ioa747 Version: 1.0 argumentum, UEZ and donnyh13 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 Sunday at 12:54 PM by ioa747 donnyh13 1 I know that I know nothing
UEZ Posted Sunday at 12:55 PM Posted Sunday at 12:55 PM (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 Sunday at 01:02 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 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 UEZ and argumentum 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