BugFix Posted November 20, 2023 Share Posted November 20, 2023 I have already posted the script in the German forum, but I would like to make it available here as well. Highlighting the active tab item in SciTE Individual: Frame color Text color Background color Text color if not saved Marker "Inactive item unsaved" Marker position "Inactive item unsaved" optionally 'top' / 'bottom' / 'none' Active item marking can be deactivated (if only unsaved marking is desired). The active item then receives the same marking as the inactive item when "unsaved". Colors can be loaded as a scheme via INI The compiled script can be ended with CMDLine parameter "/Exit". Since Windows 10, the windows have a very "flat" look. One of the consequences of this is that it is not immediately apparent which item is active in a Tab-Ctrl. When programming in SciTE, I usually have many tabs open at the same time. To make the active tab more visible, I draw it with a colored frame. In addition, unsaved tabs are marked separately with coloring of the top or bottom edge. The colors used for this can be stored individually as a scheme in an INI file. Spoiler ; If INI is not available, default colors are loaded. ; INI-Name = Name_of_the_Exe.ini [appearance] ; rect_highlight=true/false "false" does NOT highlight the active item, default: "true". rect_highlight=true ; idlepos=top/bottom/none "none" does NOT mark unsaved inactive files, default: "top". idlepos=top [scheme] ; Specify which of the defined schemes should be active. current=default ; One section for each scheme. ; scheme name [default] ; the color of the rectangle of the active element rect=0xCC483F ; the color of the text of the active element text=0x800020 ; the color of the background of the active element bg=0xFFFFFF ; the color of the text of the active element if it is to be saved and is not saved unsaved=0x3030FF ; the color of the top/bottom edge of an inactive element if it is to be saved and is not currently saved idle=0x3030FF Some schemes are predefined at the beginning of the script. Just try out what you like best. I start the script via the autostart folder when Windows starts. Here are a few pictures: Active Tab Active Tab, unsaved Active Tab, BG: blue / Text: white ... BG: green / Text: white Active Tab, left & right idle unsaved Tabs Active Tab unsaved too expandcollapse popup;-- TIME_STAMP 2023-03-23 10:16:34 v 0.5 #cs v 0.5 [fixed] Flickering, a variable assignment was incorrect [fixed] Marking has failed by using keys ("F6", "Shift+F6") to change the buffer selection v 0.4 [added] Exit via CMDLine with parameter "/Exit" [added] Optionally adjustable via INI [appearance]: - Mark active item: rect_highlight=true/false - Position of the marker for "Inactive item unsaved": idlepos=top/bottom/none v 0.3 [added] Separate marker (colored line top) for "Inactive item unsaved". v 0.2 [added] Separate marking (text color) for unsaved files. [added] Loading of colors from an INI (color schemes) possible #ce #include <FontConstants.au3> #include <GuiTab.au3> #include <Misc.au3> #include <WinAPIGdi.au3> #include <WinAPISys.au3> #include <WinAPIMisc.au3> #include <WindowsConstants.au3> Opt('TrayIconHide', 1) If $CMDLINE[0] And $CMDLINE[1] = '/Exit' Then ; CMD-Line: "@ScriptName.exe /Exit" Local $aProcessList = ProcessList(@ScriptName) For $i = 1 To $aProcessList[0][0] Step 1 If $aProcessList[$i][1] <> @AutoItPID Then ProcessClose($aProcessList[$i][1]) Next EndIf _Singleton(@ScriptName) ;~ HotKeySet("!{F8}", _End) ; <Alt><F8> Beenden OnAutoItExitRegister(_End) Global $sINI = StringFormat("%s\%s.ini", @ScriptDir, StringTrimRight(@ScriptName, 4)) Global $gm_SciTE[] $gm_SciTE.ExistsLast = 0 $gm_SciTE.ExistsCurr = 0 #cs The colors can be defined in an INI file in the script folder. If INI is not available, default colors are loaded. INI-Name = Name_of_the_Exe.ini [appearance] ; rect_highlight=true/false "false" does NOT highlight the active item, default: "true". rect_highlight=true ; idlepos=top/bottom/none "none" does NOT mark unsaved inactive files, default: "top". idlepos=top [scheme] ; Specify which of the defined schemes should be active. current=default ; One section for each scheme. [default] rect=0xCC483F text=0x800020 bg=0xFFFFFF unsaved=0x3030FF idle=0x3030FF [blue_invers] rect=0xCC483F text=0xFFF0F0 bg=0x800020 unsaved=0xA9A5F7 idle=0xA9A5F7 [green_invers] rect=0x005F00 text=0xEDFFED bg=0x409340 unsaved=0x1DE6B5 idle=0x1DE6B5 #ce ; appearance $gm_SciTE.bHighlight = (_IniOrDefault($sINI, 'rect_highlight', 'true', 'appearance') = 'true') $gm_SciTE.IdlePos = _IniOrDefault($sINI, 'idlepos', 'top', 'appearance') ; scheme: default (blue): $gm_SciTE.RectColor = _IniOrDefault($sINI, 'rect' , 0xCC483F) ; BGR $gm_SciTE.TextColor = _IniOrDefault($sINI, 'text' , 0x800020) ; BGR $gm_SciTE.BGColor = _IniOrDefault($sINI, 'bg' , 0xFFFFFF) ; BGR $gm_SciTE.TextColorUnsaved = _IniOrDefault($sINI, 'unsaved', 0x3030FF) ; BGR $gm_SciTE.IdleUnsaved = _IniOrDefault($sINI, 'idle' , 0x3030FF) ; BGR _CheckSciTE() ; the effect takes place immediately AdlibRegister(_CheckSciTE, 750) While True Sleep(5000) WEnd Func _End() AdlibUnRegister(_CheckSciTE) ;~ MsgBox(0, 'SciTE TabItem', 'Beendet!') Exit EndFunc Func _CheckSciTE() If ProcessExists("SciTE.exe") Then $gm_SciTE.ExistsCurr = 1 If $gm_SciTE.ExistsLast = 0 Then $gm_SciTE.ExistsLast = 1 If $gm_SciTE.bHighlight Then _DrawTabItem() AdlibRegister(_MouseHoversTab, 150) EndIf _MarkUnsavedIdleTab() Else $gm_SciTE.ExistsCurr = 0 If $gm_SciTE.ExistsLast = 1 Then $gm_SciTE.ExistsLast = 0 If $gm_SciTE.bHighlight Then AdlibUnRegister(_MouseHoversTab) EndIf EndIf EndFunc Func _MouseHoversTab() Local Static $iHoverLast = 1 ; when starting the program, exit from the item must be simulated Local $mTab = _SciTE_GetActiveTabInfo() If @error Then Return Local $tPoint = _WinAPI_GetMousePos(True, $mTab.hTab) Local $tRect = $mTab.RectItem Local $isHover = _WinAPI_PtInRect($tRect, $tPoint) If $isHover = 1 And $iHoverLast = 0 Then $iHoverLast = 1 ElseIf $isHover = 0 And $iHoverLast = 1 Then $iHoverLast = 0 Return _DrawTabItem() EndIf EndFunc Func _MarkUnsavedIdleTab() If $gm_SciTE.IdlePos = 'none' Then Return Local $hTab = __GetHwnd_SciTeTabCtrl() If @error Then Return SetError(1) Local $iActive = _GUICtrlTab_GetCurFocus($hTab) For $i = 0 To _GUICtrlTab_GetItemCount($hTab) -1 If $i = $iActive And $gm_SciTE.bHighlight Then ContinueLoop If StringRight(_GUICtrlTab_GetItemText($hTab, $i), 1) = '*' Then _DrawMarkerUnsaved($hTab, $i) EndIf Next EndFunc Func _DrawMarkerUnsaved($_hTab, $_iItem) Local $tRect = _GUICtrlTab_GetItemRectEx($_hTab, $_iItem) Local $tRectDraw = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") If $gm_SciTE.IdlePos = 'top' Then $tRectDraw.Left = $tRect.Left $tRectDraw.Top = $tRect.Top -1 $tRectDraw.Right = $tRect.Right $tRectDraw.Bottom = $tRect.Top Else $tRectDraw.Left = $tRect.Left $tRectDraw.Top = $tRect.Bottom +2 $tRectDraw.Right = $tRect.Right $tRectDraw.Bottom = $tRect.Bottom +3 EndIf Local $hDC = _WinAPI_GetDC($_hTab) Local $hPen = _WinAPI_CreatePen($PS_SOLID, 2, $gm_SciTE.IdleUnsaved) Local $hOldPen = _WinAPI_SelectObject($hDC, $hPen) _WinAPI_Rectangle($hDC, $tRectDraw) _WinAPI_SelectObject($hDC, $hOldPen) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC(0, $hDC) EndFunc Func _DrawTabItem() Local $mTab = _SciTE_GetActiveTabInfo() If @error Then Return Local $hDC = _WinAPI_GetDC($mTab.hTab) Local $hFont = _WinAPI_CreateFont(14.5, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _ $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Lucida Sans Unicode Standard') Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) Local $tRect = $mTab.RectItem ; extract to variable - otherwise no ByRef access possible Local $dY = (@OSVersion = "Win_7" ? 2 : 1) _WinAPI_InflateRect($tRect, 2, $dY) ; enlarge rectangle _WinAPI_OffsetRect($tRect, 0, 1) ; move rectangle down by 1px ; draw and fill rect Local $hPen = _WinAPI_CreatePen($PS_SOLID, 2, $gm_SciTE.RectColor) Local $hBrush = _WinAPI_CreateSolidBrush($gm_SciTE.BGColor) Local $hOldPen = _WinAPI_SelectObject($hDC, $hPen) Local $hOldBrush = _WinAPI_SelectObject($hDC, $hBrush) _WinAPI_Rectangle($hDC, $tRECT) ; draw text If StringRight($mTab.Item, 1) = '*' Then _WinAPI_SetTextColor($hDC, $gm_SciTE.TextColorUnsaved) Else _WinAPI_SetTextColor($hDC, $gm_SciTE.TextColor) EndIf _WinAPI_SetBkColor($hDC, $gm_SciTE.BGColor) ; move the text down a bit more _WinAPI_OffsetRect($tRect, 0, 3) _WinAPI_DrawText($hDC, $mTab.Item, $tRect, BitOR($DT_BOTTOM,$DT_CENTER)) ; clear ressources _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_DeleteObject($hFont) _WinAPI_SelectObject($hDC, $hOldPen) _WinAPI_DeleteObject($hPen) _WinAPI_SelectObject($hDC, $hOldBrush) _WinAPI_DeleteObject($hBrush) _WinAPI_ReleaseDC(0, $hDC) EndFunc Func _SciTE_GetActiveTabInfo() Local $mResult[], $hTab = __GetHwnd_SciTeTabCtrl() If @error Then Return SetError(1) $mResult.hTab = $hTab $mResult.Index = _GUICtrlTab_GetCurFocus($hTab) $mResult.Item = _GUICtrlTab_GetItemText($hTab, $mResult.Index) $mResult.RectItem = _GUICtrlTab_GetItemRectEx($hTab, $mResult.Index) Return $mResult EndFunc Func __GetHwnd_SciTE() Local $hScite = WinGetHandle('[ACTIVE]') If _WinAPI_GetClassName($hScite) = 'SciTEWindow' Then Return $hScite Else Return SetError(1, 0, Null) EndIf EndFunc Func __GetHwnd_SciTeTabCtrl() Local $hScite = __GetHwnd_SciTE() If @error Then Return SetError(1, 0, Null) Local $aChild, $hWndTab = Null $aChild = _WinAPI_EnumChildWindows($hScite) ; only visible 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 ; read from INI if exists Func _IniOrDefault($_sINI, $_sKey, $_sDefault, $_sec=Null) Local $sVal = $_sDefault, $sSec = $_sec = Null ? 'scheme' : $_sec If FileExists($_sINI) Then If $sSec = 'scheme' Then $sSec = IniRead($_sINI, 'scheme', 'current', 'default') $sVal = IniRead($_sINI, $sSec, $_sKey, $_sDefault) EndIf Return $sVal EndFunc SciTE_DrawTabItem.au3 Danyfirex and mLipok 2 Best Regards BugFix Link to comment Share on other sites More sharing options...
argumentum Posted November 20, 2023 Share Posted November 20, 2023 (edited) Nice. I did change all map to array and globals to use it in prior version(s) of AutoIt, as the switch was easy. Thanks for sharing Edited November 20, 2023 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted November 20, 2023 Moderators Share Posted November 20, 2023 bugfix, Very nice - thanks for posting. M23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
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