WildByDesign Posted 5 hours ago Posted 5 hours ago Recently, I have been experimenting with enabling a random color border coloring transitions (rainbow) effect in external processes with my Immersive UX (DwmColorBlurMica) project. The idea (and code) comes from the great @argumentum's Win11myOwnBorderColor project. Since my project would color the borders of whichever happens to be the active window at the time and therefore working with separate processes, I don't believe that I can use _Timer_SetTimer() and related functions because "This window must be owned by the calling thread", unfortunately. Therefore in my example, I have had to resort to using AdlibRegister. expandcollapse popup#include <GUIConstantsEx.au3> Global $hGUI Example() Func Example() ; Create a GUI with various controls. $hGUI = GUICreate("Example", 400, 400) Local $idBtn_OK = GUICtrlCreateButton("OK", 310, 370, 85, 25) ; dark titlebar _WinAPI_DwmSetWindowAttribute__($hGUI, 20, 1) ; Display the GUI. GUISetState(@SW_SHOW, $hGUI) AdlibRegister("BorderMeRandomColorViaTimer", 300) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $idBtn_OK ExitLoop EndSwitch WEnd ; Delete the previous GUI and all controls. AdlibUnRegister("BorderMeRandomColorViaTimer") GUIDelete($hGUI) EndFunc ;==>Example Func BorderMeRandomColorViaTimer() Local $color = '0x' & Hex(Random(2, 13, 1), 1) & Hex(Random(2, 13, 1), 1) & Hex(Random(2, 13, 1), 1) & Hex(Random(2, 13, 1), 1) & Hex(Random(2, 13, 1), 1) & Hex(Random(2, 13, 1), 1) DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hGUI, 'dword', 34, 'dword*', $color, 'dword', 4) ; border ;DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $g_hForm, 'dword', 35, 'dword*', $color, 'dword', 4) ; caption EndFunc ;==>BorderMeRandomColorViaTimer Func _WinAPI_DwmSetWindowAttribute__($hwnd, $attribute = 34, $value = 0x00FF00, $valLen = 4) Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $attribute, 'dword*', $value, 'dword', $valLen) If @error Then Return SetError(@error, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttribute__ Now the question that I have and what I am asking for help with is making those color transitions smoother. There is a recent example in a program that I follow that is in C# that has achieved a very smooth transition of colors. But since I am not very familiar with C#, I don't understand exactly how it is being done. Particularly, the transition of one color to the next. Link: https://github.com/HotCakeX/Harden-Windows-Security/blob/4966307bc06257b37307d0660e3d821b9944d67b/AppControl Manager/CustomUIElements/AppWindowBorderCustomization.cs#L211-L264 private static void TickUpdate() { long currentTimestamp = Stopwatch.GetTimestamp(); long deltaTicks = currentTimestamp - LastTimestamp; LastTimestamp = currentTimestamp; // Convert ticks to seconds. float deltaSeconds = deltaTicks * TickToSeconds; // Increment hue based on elapsed time and speed. Hue += deltaSeconds * InverseSpeed; // Wrap hue to [0,1) without using modulo. if (Hue >= 1f) { // (int)Hue removes the integer portion (if a long pause made it exceed by more than 1). Hue -= (int)Hue; } #region Convert hue to RGB border color. float t = Hue * 6f; float r = MathF.Abs(t - 3f) - 1f; float g = 2f - MathF.Abs(t - 2f); float b = 2f - MathF.Abs(t - 4f); r = r < 0f ? 0f : (r > 1f ? 1f : r); g = g < 0f ? 0f : (g > 1f ? 1f : g); b = b < 0f ? 0f : (b > 1f ? 1f : b); byte rr = (byte)(r * 255f); byte gg = (byte)(g * 255f); byte bb = (byte)(b * 255f); // https://learn.microsoft.com/windows/win32/gdi/colorref // COLORREF format expected: 0x00BBGGRR uint computedBorderColor = (uint)((bb << 16) | (gg << 8) | rr); #endregion // Main Apply int result = NativeMethods.DwmSetWindowAttribute(GlobalVars.hWnd, DWMWA_BORDER_COLOR, ref computedBorderColor, sizeof(uint)); if (result != 0) { // If setting the border color failed, stop the timer to avoid further errors. if (Timer is not null && Timer.IsRunning) { Timer.Stop(); } Logger.Write($"Failed to set window border color. DwmSetWindowAttribute returned error code: {result}", LogTypeIntel.Error); } } The app is in the Microsoft Store in case anyone wants to see the smooth transitions. It's called AppControl Manager and the rainbow border effect is in the Settings for it. Although many of you will probably understand better what is happening in the C# code. Does anybody have any ideas on what can be done to make the color transition appear smoother? I may be somewhat limited since I don't think I can use timers in external processes. Thank you for your time. argumentum 1
argumentum Posted 5 hours ago Posted 5 hours ago 8:00 here. Working on a Sunday Anywayz, .. float t = Hue * 6f; is the same in AutoIt, $t = $Hue * 0x6f .. float r = MathF.Abs(t - 3f) - 1f; would be $r = Abs($t - 0x3f) if nobody does it, I'll do it ... next week ? 😅 PS: you should be able to do it by throwing code at it. I have faith in you WildByDesign 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
WildByDesign Posted 5 hours ago Author Posted 5 hours ago I'm sorry to hear that you got stuck working early on a Sunday of all days. Thank you, I appreciate it. I will see what I can figure out with the color transitions. But I also don't really understand the timing of it either. Other users requested this feature, so it's not something I have thought much about. I did not even think that it could potentially look nice. But after seeing how smooth it is in that C# program, I can understand it can look nice if done right. It's really quite beautiful, surprisingly.
Werty Posted 4 hours ago Posted 4 hours ago 1 hour ago, argumentum said: .. float t = Hue * 6f; is the same in AutoIt, $t = $Hue * 0x6f .. float r = MathF.Abs(t - 3f) - 1f; would be $r = Abs($t - 0x3f) f in C# means float, but you are treating them as Hex. So it's just $t =$Hue * 6 in AU3, removing the f. WildByDesign 1 Some guy's script + some other guy's script = my script!
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