Jump to content

Win 11 - My own border color ( Help area )


Go to solution Solved by argumentum,

Recommended Posts

Posted (edited)

image.png.0f05be2594ea2f468eb43f6ed15f0304.png 

These border colors are set by the app every time the window is created.
The example for this is already posted. Since this is more of an app than an example, I opened a thread here for support.

The script and compilation to .exe is the files area for download.

According to Microsoft, the possibility to set the border color is available from Windows 11 Build 22000 onwards.

image.png

image.png.4a4298628eda3d2d4797db4ee85e8a98.png

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

  • Solution
Posted (edited)

FAQ / Help

Q: What does this app do ?
A: Changes the border color around other apps.

Q: How do I install this app ?
A: Make a folder and put the file(s) there. Run the app.

Q: How do I uninstall this app ?
A: Remove from TaskScheduler ( if present ), Exit the app and delete it.
   This is a portable app without an installer.

Q: Why does it ask for "Do you want to allow this app to make changes to your device" ?
A: To change the border color of an elevated window, this app needs to be elaveted too.
   Otherwise only user level apps will have a custom border.
   This does not change anything in your device, other than coloring the borders when running.

Q: How can I stop this from asking to elevate each time I use it ?
A: In the .INI file, set AskToElevate=0
   Or with the argument /DontElevate

Q: How can I have it elevate itself ?, How do I make this app load on boot ?
A: There is a menu option to set a Task Scheduler entry to run on user login. Use that.
   Each user, if more than one, will have to set this for their own enviroment.

Q: I selected the Task Scheduler but it does not elevate in it's own.
A: It will use the elevation of the user level at the time.
   To have it self elevate, the app had to be elevated at the time.

Q: What happens when I double click the try icon ?
A: It can switch alternate colors (Yes/No) when this app is elevated.
   By default it enables or disables border coloring.
   Change via the menu or INI file.

Q: What happens when I right click the try icon ?
A: It shows a menu with options to choose from.

Q: Can I hide the tray icon ?. How do I bring it back ?.
A: You can hide it from the tray menu, or with the argument /HideTrayIcon, or as default in the INI HideTrayIcon=1
   Can unhide with the argument /ShowTrayIcon, or just run it again to show/hide as default setting in the INI file.
   When you first run this app, it creates a few shortcuts ( with those entries ) and finaly the INI file.
   To recreate the shortcuts, remove the INI and the app will recreate them.

Q: Some windows don't get the border colored. Why ?
A: The elevation of this app is lower, is a child window, is a custom GUI, etc.

Q: This is not working on my device !
A: It has to be Windows 11 (22000) onwards.
  https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute

Q: This app say that it will not work on my OS build, but I believe it would.
A: Set SkipOsBuildCheck=1 in the INI file to skip the build check.

Q: There are more than one user on this PC. Can we have each our own settings ?
A: Open the INI file and set MultiUser=1. You can remove the other entries.
   That will keep an INI file for each user.

Q: The other user on my PC does not like this. What can I do ?
A: In the user INI file, set ExemptUser=1. Then this will not run for that user.
   Don't set mutiuser=1 is another option.

Q: Can I have my own set of icons for it ?
A: Have 2 icons in the same folder: Win11GuiSetBorderColor.ico and Win11GuiSetBorderColor_GrayScale.ico
   and the app will use those instead of the default ones.

Q: My anti-virus say that this is a virus.
A: Is not but do check on the site to campare that the hash is the same as the developer claims it shoud be.
   Those that do create viruses can impersonate a legitamte app. by just giving it the same name and icon.
   If in doubt, compile it your self. If still in doubt, don't run anything you don't trust.

Q: There is an entry in the INI called "CaptionColorToo", what is it ?
A: Is a bad idea. But if you're curious of what would changing the caption bar look like, there you have it. Again, is a bad idea.

Q: There is an entry in the INI called "WatchForGuiRedraw", what is it ?
A: Is there but not needed. Is more in case of debug than anything else.

Q: There is an entry in the INI called "LogToFile", what is it ?
A: Is for debug. If you contact the developer, that log file will be useful to determine an issue.
    It does not auto-clean up, so make sure to disable it if not needed.

Q: There is an entry in the INI called "CustomColors" and say "Don't edit manually", why ?
A: That is the list of predefined colors. When you save a custom color in the color chooser, those colors are kept in that entry.

Q: There is an entry in the INI that say "TryToLoadCount=5" and the app don't load.
A: That happens when the Task Scheduler was added from a folder and the app is loaded from another path.

Q: How much is the pro version ?
A: This is it. No "pro" version. Always free. Nonetheless donations are always welcomed.

Q: My question is not listed. Where can I ask ?
A: In the forum ( here ) at: https://www.autoitscript.com/forum/topic/212446-win-11-my-own-border-color-help-area/


These are all the questions I can imagine a new user of this could ask.

Edited by argumentum
v0.2411.14.1 update

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

  • argumentum changed the title to Win 11 - My own border color ( Help area )
Posted (edited)

What's New in Version 0.2411.9.38
SHA-1:       AA15D6C911CEC5E2EC639B892DD96A5082425A1C
SHA-256:   0F7F2B14A4FBE1D998AA977BD042E7270D38146A7807A137EB6866A3491E4F8B

  • Changed the tray menu a bit.
  • Added hide/show tray icon.
  • Added an about box.
  • Use your own icon set ( optionally )
  • Renamed the project to something more meaningful, I hope.
Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted (edited)

What's New in Version 0.2411.14.2
Fixed: The shortcuts would recreate on each run instead of once the first run.

What's New in Version 0.2411.14.1
Added: Reset coloring to default on exit.
Added: DClick the tray icon will optionally pause it.
Added: create default links on first run, as an aid to the command line options.

Edited by argumentum
fixed an oops

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

  • 2 weeks later...
  • 4 months later...
Posted

I am glad that you brought this to my attention because I was not aware of this app of yours. I actually want and need this functionality. And if I use this, I can get rid of another app now which is great.

Suggestion: This can cause a lot of visual distraction. If possible, the best way to go about this would be to only color the border of the window that is in focus. When that window goes out of focus, the color should be removed.

For example, if you have a big monitor with 4 or 5 apps open, it would be visually distracting and difficult to know exactly which app is in focus. Harder on the eyes. But if you color the borders of only the app that is in focus, this would be the best way to go. This is how Microsoft implements it as well.

Posted
3 minutes ago, WildByDesign said:

Suggestion: This can cause a lot of visual distraction. If possible, the best way to go about this would be to only color the border of the window that is in focus. When that window goes out of focus, the color should be removed.

That is baked in Windows 11. No need to code for that.
This is when you'd like every window to have a well defined border on every window, that in my case is because my eyesight sucks.

11 minutes ago, WildByDesign said:

For example, if you have a big monitor with 4 or 5 apps open, it would be visually distracting and difficult to know exactly which app is in focus. Harder on the eyes. But if you color the borders of only the app that is in focus, this would be the best way to go. This is how Microsoft implements it as well.

hmm, this is not a fix for ADHD :P 
c'mon !, if the user don't know what window/app he/she is working on, is time to take a break :) 

I have 2 big monitors and seeing the borders ( in dark mode ) is a blessing compared with many windows only defined by the X at the end of the caption bar.
Again, all this in dark mode, because in light mode what you claim is understandable.

PS: For those out in the open, under the sun or well lit office, dark mode would be a pain to see anything in. Dark mode is in my view when the ambient lighting is not that bright and you spend all day looking at it.
Then again, we ( humans ) are all mutants/mutations ( because that is what "male-female" reproduction does ( I should say that that is the reason for sex )), and that make us so different, that we can agree to call a color the same name, but not that we see the same or are affected in the same way hence, coloring is very personal. There is not a one-fit-all coloring scheme.
Expand/open the "hidden contents" in this post and you'll get a feeling on how every coloring scheme hits you. If none of these "hit you", then your eyesight is enviable :)

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted (edited)
On 11/9/2024 at 9:42 PM, argumentum said:

Q: Some windows don't get the border colored. Why ?
A: The elevation of this app is lower, is a child window, is a custom GUI, etc.

From your FAQ, I understand that there are limits to what windows you can catch with this. Particularly child windows.

If I understand correctly, Notepad - Help menu - About Notepad would be considered a child window. Similar to the Font dialog in Notepad.

Are there any possible techniques to catch these child windows?

I would assume that anything that might catch them would also likely be more CPU intensive.

EDIT: I spent some more time thinking about this. I also spent a bunch of time over the weekend studying your script. Please keep in mind that I still only understand some of it.

If anything comes to fruition from my suggestions/ideas, I would expect that it would be an option, instead of default. As it might be more CPU intensive.

Thought? Why not harass (poll) the active window to check for child windows?

My current thought is to only bother the active (focused) window to keep CPU down as much as possible.

What I did so far was to add a Hotkey to one of my tray apps, this way I could check the active window easy without stealing focus and getting incorrect results. So the hotkey would run the function that I am testing.

Func _check_active_window()
        ; get title for active window
        Local $sText = WinGetTitle("[ACTIVE]")

        ; title to PID
        ;Local $iPID = WinGetProcess($sText)

        ; get hWnd from PID
        ;$hWnd = _GetHwndFromPID($iPID)

        ; get hWnd from active title
        Local $hWnd = WinGetHandle($sText)

        ; Display the window title.
        MsgBox($MB_SYSTEMMODAL, "", $hWnd)

        ; run SetBorderColor_apply2this() function on this
EndFunc   ;==>Example


;Function for getting HWND from PID
Func _GetHwndFromPID($PID)
    $hWnd = 0
    $winlist = WinList()
    Do
        For $i = 1 To $winlist[0][0]
            If $winlist[$i][0] <> "" Then
                $iPID2 = WinGetProcess($winlist[$i][1])
                If $iPID2 = $PID Then
                    $hWnd = $winlist[$i][1]
                    ExitLoop
                EndIf
            EndIf
        Next
    Until $hWnd <> 0
    Return $hWnd
EndFunc;==>_GetHwndFromPID

First, I was testing getting the hWnd from PID of the active window. But then I realized that might not be best. So I switched to just getting the handle from the active window text. And at the moment, I left off with a simple msgbox. But my thought is to extend this to call your SetBorderColor_apply2this() function on that specific handle only.

But it would be good on CPU if we can somehow cache whether or not we have applied (SetBorderColor_apply2this) to this handle or not, and if yes, we can skip so that we can lower CPU and not keep applying to what has already been applied.

There is also the question of how we would poll the active window in the first place. Possibly Adlibregister every 250ms. There is probably more efficient ways to catch this than my idea because my understanding is still very limited and my AutoIt knowledge is still quite basic.

Also, what about $HSHELL_WINDOWACTIVATED? Would this be beneficial?

Edited by WildByDesign
Added suggestion/idea, $HSHELL_WINDOWACTIVATED
Posted

By the way, the reason why I wanted to dig into this child window thing is because I realized that if you have, for example Notepad with it's About Notepad child window, and than you start your Win11myOwnBorderColor.au3 script after that, it does color the Notepad window and the About Notepad child window properly.

So that is my thought process behind polling whichever window is currently active and possibly re-applying your function to color.

Posted (edited)

Ok so after some testing (all morning), I have it working for child windows:

Func WM_SHELLHOOK($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg
    Switch $wParam
        Case $HSHELL_WINDOWCREATED, $g_HSHELL_REDRAW, $HSHELL_WINDOWACTIVATED, $HSHELL_REDRAW
            $sTitle = WinGetTitle($lParam)
            Local $sTextActive = WinGetTitle("[ACTIVE]")
            Local $hWndActive = WinGetHandle($sTextActive)
            SetBorderColor_apply2this($hWndActive, 0x0078D4)
            If $sTitle <> "" Then
                If $g_iChooseColorTitleChange Then
                    WinSetTitle($lParam, "", $g_sChooseColorTitleChangeTitle)
                    WinSetOnTop($lParam, "", 1) ; added on 0.2411.9.34
                    ConsoleWriteR('Color selectr: ' & ($g_iChooseColorTitleChange = 2 ? $g_iBorderColorElevated : $g_iBorderColor) & @CRLF)
                    SetBorderColor_apply2this($lParam, $g_iChooseColorTitleChange = 2 ? $g_iBorderColorElevated : $g_iBorderColor)
                    $g_iChooseColorTitleChange = 0
                    $g_sChooseColorTitleChangeTitle = ""
                    Return
                EndIf
                ConsoleWriteR("Window " & ($wParam = $HSHELL_WINDOWCREATED ? 'Created' : ' Redraw') & ": " & $lParam & " (" & $sTitle & ")" & @CRLF)
                If Not $g_iDisableBorderColoring Then SetBorderColor_apply2this($lParam, WinGetProcessElevation($lParam) ? $g_iBorderColorElevated : $g_iBorderColor)
            EndIf
    EndSwitch
EndFunc   ;==>WM_SHELLHOOK

 

The only issue is that there is about a 1 second delay before the child window gets colored.

 

EDIT: I don't see any increase in CPU usage which is nice.

Edited by WildByDesign
added cpu
Posted

Separated the Cases:

Func WM_SHELLHOOK($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg
    Switch $wParam
        Case $HSHELL_WINDOWACTIVATED, $HSHELL_REDRAW
            Local $sTextActive = WinGetTitle("[ACTIVE]")
            Local $hWndActive = WinGetHandle($sTextActive)
            SetBorderColor_apply2this($hWndActive, 0x0078D4)
        Case $HSHELL_WINDOWCREATED, $g_HSHELL_REDRAW
            $sTitle = WinGetTitle($lParam)
            If $sTitle <> "" Then
                If $g_iChooseColorTitleChange Then
                    WinSetTitle($lParam, "", $g_sChooseColorTitleChangeTitle)
                    WinSetOnTop($lParam, "", 1) ; added on 0.2411.9.34
                    ConsoleWriteR('Color selectr: ' & ($g_iChooseColorTitleChange = 2 ? $g_iBorderColorElevated : $g_iBorderColor) & @CRLF)
                    SetBorderColor_apply2this($lParam, $g_iChooseColorTitleChange = 2 ? $g_iBorderColorElevated : $g_iBorderColor)
                    $g_iChooseColorTitleChange = 0
                    $g_sChooseColorTitleChangeTitle = ""
                    Return
                EndIf
                ConsoleWriteR("Window " & ($wParam = $HSHELL_WINDOWCREATED ? 'Created' : ' Redraw') & ": " & $lParam & " (" & $sTitle & ")" & @CRLF)
                If Not $g_iDisableBorderColoring Then SetBorderColor_apply2this($lParam, WinGetProcessElevation($lParam) ? $g_iBorderColorElevated : $g_iBorderColor)
            EndIf
    EndSwitch
EndFunc   ;==>WM_SHELLHOOK

But still has 1 - 2 second delay. But works.

Posted
2 hours ago, WildByDesign said:

From your FAQ, I understand that there are limits to what windows you can catch with this. Particularly child windows.

The limits were that the coder ( yours truly ) devoted as much time as needed for the needed task and did not dig deeper than that :D

12 minutes ago, WildByDesign said:

Ok so after some testing (all morning), I have it working for child windows:
The only issue is that there is about a 1 second delay before the child window gets colored.
EDIT: I don't see any increase in CPU usage which is nice.

If you can get more out of it without much, do it ?.
I for once, just woke up, and have IRL drama to attend to. ( and that sucks because I'd love to revisit the code and look at what you're doing to better the code/functionality but don't have the time right now 😢 )

 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted (edited)

I had some fun with your script after learning some more about how it works.

  • Added title bar Dark, Mica, Acrylic/blur, Mica Alt options
  • Added ability to do rounded GUI corners or standard square corners

* These are build 22621+.

I'm still playing with some more fun options.

I understand that your script is related to border color, however, your script really is the perfect "vehicle" to enable all of these fun things system-wide. :)

Func SetBorderColor_apply2this($hwnd, $iBorderColor = $g_iBorderColor)  ; 0xffFFFFFF default ; else 0x00ABCDEF
    ; https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
    ; $DWMWA_BORDER_COLOR = 34 ; https://www.purebasic.fr/english/viewtopic.php?t=78732
    _WinAPI_DwmSetWindowAttribute__($hWnd, 20, 1) ; dark mode DWMWA_USE_IMMERSIVE_DARK_MODE
    _WinAPI_DwmSetWindowAttribute__($hWnd, 38, 4) ; build 22523+, DWMWA_SYSTEMBACKDROP_TYPE = 38 ; 0 auto, 1 none (dark), 2 mica, 3 acrylic, 4 mica alt
    _WinAPI_DwmSetWindowAttribute__($hWnd, 33, 1) ; DWMWA_CORNER_PREFERENCE = 33 ; 0 default, 1 not round, 2 round, 3 round small
    _WinAPI_DwmSetWindowAttribute__($hwnd, 34, _WinAPI_SwitchColor($iBorderColor)) ; border
EndFunc   ;==>SetBorderColor_apply2this

EDIT: The DWMWA_SYSTEMBACKDROP_TYPE option will mess up the Start menu. You can avoid that easily by adding exclusion for any window with title "Start".

Edited by WildByDesign
Posted

..and, if you feel like it:

On 11/9/2024 at 9:42 PM, argumentum said:

Q: There is an entry in the INI called "CaptionColorToo", what is it ?
A: Is a bad idea. But if you're curious of what would changing the caption bar look like, there you have it. Again, is a bad idea.

add a variable for the caption color to be independent of the border too.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...