WildByDesign Posted Saturday at 11:45 PM Author Posted Saturday at 11:45 PM 1 hour ago, mLipok said: Try change theme for the secret hidden window created automaticaly by AutoIt. Oh yes, I am familiar with that hidden AutoIt window. I have actually used it before for applying dark mode to system tray menu on tray tool apps which had no GUI. Good idea. I will try this.
WildByDesign Posted Sunday at 12:27 AM Author Posted Sunday at 12:27 AM GUIDarkTheme 2.3.2 Fixed a bug in _GUIDarkTheme_MsgBox preventing dark MsgBox before GUI creation Fixed a bug in _GUIDarkTheme_MsgBox causing focus rectangle to be solid white Fixed issue with Group control getting overpainted by tab control brush 7 hours ago, bladem2003 said: Can we display a dark message box before the graphical user interface is created? This issue should be fixed now. 9 hours ago, jpm said: he group is not showing switching to tab fic)ve and back to four sometime show same pb with light theme I understand what you mean now. It was a problem redrawing the Group control. I found a better way to handle it. It should be fixed in 2.3.2 now. Please let me know. bladem2003 and argumentum 2
mLipok Posted Sunday at 12:33 AM Posted Sunday at 12:33 AM (edited) 6 minutes ago, WildByDesign said: Fixed a bug in _GUIDarkTheme_MsgBox preventing dark MsgBox before GUI creation 6 minutes ago, WildByDesign said: 7 hours ago, bladem2003 said: Can we display a dark message box before the graphical user interface is created? This issue should be fixed now. what was the solution ? EDIT: sorry I not follow code, only discussion Edited Sunday at 12:34 AM by mLipok Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24
WildByDesign Posted Sunday at 01:38 AM Author Posted Sunday at 01:38 AM 1 hour ago, mLipok said: what was the solution ? There are two brushes responsible for coloring the dark MsgBox. I just had to create those two brushes earlier when the UDF is first initiated. All of the other brushes are still created later. mLipok 1
xuankhanh1982 Posted Sunday at 10:47 AM Posted Sunday at 10:47 AM (edited) @WildByDesign How do I fix the error shown in the image? https://ibb.co/JRwWKLhZ This is the code in the image: expandcollapse popup#include <ButtonConstants.au3> #include <ComboConstants.au3> #include <GUIConstantsEx.au3> #include <TabConstants.au3> #include <WindowsConstants.au3> #include <GUIDarkTheme.au3> Opt("TrayAutoPause", 0) Opt("GUICoordMode", 1) Opt("TrayMenuMode", 3) Global $g_DpiRatio = _ApplyDpiScaling(), $idAbout[3], $icon[4], $msguide $idAbout[2] = TrayCreateMenu("Menu") $idAbout[1] = TrayCreateItem("About", $idAbout[2]) TrayCreateItem("") $idAbout[0] = TrayCreateItem("Exit") $icon[0] = _WinAPI_ExtractIcon("shell32.dll", 17, True) $icon[1] = _WinAPI_ExtractIcon("shell32.dll", 130, True) $icon[2] = _WinAPI_ExtractIcon("shell32.dll", 131, True) _TrayMenuAddIcon($icon[0], 0) _TrayMenuAddIcon($icon[1], 0, $idAbout[2]) _TrayMenuAddIcon($icon[2], 2) _GUIDarkTheme_ApplyDark("") ;~ _GUIDarkTheme_ApplyLight("") While 1 $msguide = TrayGetMsg() If ($msguide = $idAbout[1]) Then Local $sMsg = "GUIDarkTheme UDF" & @CRLF $sMsg &= "Version: " & @TAB & _GUIDarkTheme_Version() _GUIDarkTheme_MsgBox(64+262144, "About", $sMsg, 0, "") EndIf If ($msguide = $idAbout[0]) Then Exit EndIf WEnd Func _TrayMenuAddIcon(ByRef $hIcon, $TrayMenuNr, $ParentMenu = 0, $IndexType = 0x00000400); $MF_POSITION=0x00000400 dim $pIcoInfo, $hBmp If _IconGetInfo($hIcon, $pIcoInfo) <> 0 Then ; Get a handel to the bmp in the icon def. $hBmp = DllStructGetData($pIcoInfo,5) _TrayMenuAddImage($hBmp, $TrayMenuNr, $ParentMenu, $IndexType) $pIcoInfo = 0 Else ;~ If $Debug Then ConsoleWrite($ModuleName & " ERROR: In _TrayMenuAddIcon($hIcon:=" & $hIcon & _ ;~ ", $TrayMenuNr:=" & $TrayMenuNr _ ;~ & ") Call to _GetIconInfo Trying to use $hIcon as bmp handel" & @LF) _TrayMenuAddImage($hIcon, $TrayMenuNr, $ParentMenu, $IndexType) EndIf EndFunc ; ==>_TrayMenuAddIcon Func _IconGetInfo(ByRef $hIcon, ByRef $structICONINFO) local $def = "int; dword; dword; ptr; ptr" $structICONINFO = DllStructCreate($def) ; PROTO: BOOL GetIconInfo( HICON hIcon, PICONINFO piconinfo); Local $ret = DllCall("user32.dll", "long", "GetIconInfo", "ptr", $hIcon, "ptr", DllStructGetPtr($structICONINFO)) ;~ if $Debug AND @error <> 0 then ConsoleWrite( $ModuleName & "_IconGetInfo: @ERROR:=" & @error & @CRLF & _ ;~ "@ERROR:=1 > unable to use the DLL file: user32.dll" & @CRLF & _ ;~ "@ERROR:=2 > unknown return type" & @CRLF & _ ;~ "@ERROR:=3 > function: GetIconInfo not found in user32.dll" & @LF) ; 0 Is failure andything else is success. return $ret[0] EndFunc ; ==> _IconGEtInfo Func _TrayMenuAddImage(ByRef $hBmp, $MenuIndex, $ParentMenu = 0, $IndexType = 0x00000400); $MF_POSITION=0x00000400 ;~ if $Debug Then ConsoleWrite("_TrayMenuAddIcon( $hBmp:=" & $hBmp & ", $MenuIndex:=" & _ ;~ $MenuIndex & ", $ParentMenu:=" & $ParentMenu & ", $IndexType:=" & $IndexType &" )" & @LF) local $ret = DllCall("user32.dll", "int", "SetMenuItemBitmaps", "hwnd", TrayItemGetHandle($ParentMenu), _ "int", $MenuIndex, _ "int", $IndexType, _ "hwnd", $hBmp, _ "hwnd", $hBmp) EndFunc ; ==>_TrayMenuAddImage Edited Sunday at 10:48 AM by xuankhanh1982
WildByDesign Posted Sunday at 11:31 AM Author Posted Sunday at 11:31 AM 39 minutes ago, xuankhanh1982 said: How do I fix the error shown in the image? It looks like something wrong with transparency of icon background. It is not something specific with GUIDarkTheme UDF though. I tested by removing all dark mode code and the problem is still there. I don't know how to fix bitmap and icon issues like that. Suggestion: I would suggest sharing the shorter code (below) over in the AutoIt Help and Support section of the forum. More users with experience working directly with bitmaps and icons can help you. This code removes dark mode stuff and hopefully makes it easier for someone in Help and Support area to find problem with icon transparency. expandcollapse popup#include <ButtonConstants.au3> #include <ComboConstants.au3> #include <GUIConstantsEx.au3> #include <TabConstants.au3> #include <WindowsConstants.au3> #include <WinAPIIcons.au3> Opt("TrayAutoPause", 0) Opt("GUICoordMode", 1) Opt("TrayMenuMode", 3) Global $idAbout[3], $icon[4], $msguide $idAbout[2] = TrayCreateMenu("Menu") $idAbout[1] = TrayCreateItem("About", $idAbout[2]) TrayCreateItem("") $idAbout[0] = TrayCreateItem("Exit") $icon[0] = _WinAPI_ExtractIcon("shell32.dll", 17, True) $icon[1] = _WinAPI_ExtractIcon("shell32.dll", 130, True) $icon[2] = _WinAPI_ExtractIcon("shell32.dll", 131, True) _TrayMenuAddIcon($icon[0], 0) _TrayMenuAddIcon($icon[1], 0, $idAbout[2]) _TrayMenuAddIcon($icon[2], 2) While 1 $msguide = TrayGetMsg() If ($msguide = $idAbout[1]) Then Local $sMsg = "Test" MsgBox(64+262144, "About", $sMsg, 0, "") EndIf If ($msguide = $idAbout[0]) Then Exit EndIf WEnd Func _TrayMenuAddIcon(ByRef $hIcon, $TrayMenuNr, $ParentMenu = 0, $IndexType = 0x00000400); $MF_POSITION=0x00000400 dim $pIcoInfo, $hBmp If _IconGetInfo($hIcon, $pIcoInfo) <> 0 Then ; Get a handel to the bmp in the icon def. $hBmp = DllStructGetData($pIcoInfo,5) _TrayMenuAddImage($hBmp, $TrayMenuNr, $ParentMenu, $IndexType) $pIcoInfo = 0 Else ;~ If $Debug Then ConsoleWrite($ModuleName & " ERROR: In _TrayMenuAddIcon($hIcon:=" & $hIcon & _ ;~ ", $TrayMenuNr:=" & $TrayMenuNr _ ;~ & ") Call to _GetIconInfo Trying to use $hIcon as bmp handel" & @LF) _TrayMenuAddImage($hIcon, $TrayMenuNr, $ParentMenu, $IndexType) EndIf EndFunc ; ==>_TrayMenuAddIcon Func _IconGetInfo(ByRef $hIcon, ByRef $structICONINFO) local $def = "int; dword; dword; ptr; ptr" $structICONINFO = DllStructCreate($def) ; PROTO: BOOL GetIconInfo( HICON hIcon, PICONINFO piconinfo); Local $ret = DllCall("user32.dll", "long", "GetIconInfo", "ptr", $hIcon, "ptr", DllStructGetPtr($structICONINFO)) ;~ if $Debug AND @error <> 0 then ConsoleWrite( $ModuleName & "_IconGetInfo: @ERROR:=" & @error & @CRLF & _ ;~ "@ERROR:=1 > unable to use the DLL file: user32.dll" & @CRLF & _ ;~ "@ERROR:=2 > unknown return type" & @CRLF & _ ;~ "@ERROR:=3 > function: GetIconInfo not found in user32.dll" & @LF) ; 0 Is failure andything else is success. return $ret[0] EndFunc ; ==> _IconGEtInfo Func _TrayMenuAddImage(ByRef $hBmp, $MenuIndex, $ParentMenu = 0, $IndexType = 0x00000400); $MF_POSITION=0x00000400 ;~ if $Debug Then ConsoleWrite("_TrayMenuAddIcon( $hBmp:=" & $hBmp & ", $MenuIndex:=" & _ ;~ $MenuIndex & ", $ParentMenu:=" & $ParentMenu & ", $IndexType:=" & $IndexType &" )" & @LF) local $ret = DllCall("user32.dll", "int", "SetMenuItemBitmaps", "hwnd", TrayItemGetHandle($ParentMenu), _ "int", $MenuIndex, _ "int", $IndexType, _ "hwnd", $hBmp, _ "hwnd", $hBmp) EndFunc ; ==>_TrayMenuAddImage
xuankhanh1982 Posted Sunday at 11:52 AM Posted Sunday at 11:52 AM @WildByDesign I'm sorry, I don't know who to ask. I think, since you created the light and dark modes, you should be able to fix the error shown in the image. Thank you very much, have a nice day! WildByDesign 1
Nine Posted Sunday at 03:36 PM Posted Sunday at 03:36 PM (edited) @xuankhanh1982 You would need to specify the actual background color to your bitmap. Here an example with white BK. expandcollapse popup; From Nine #include <WinAPI.au3> #include <GuiMenu.au3> Opt("TrayAutoPause", 0) Opt("TrayMenuMode", 3) Example() Func Example() Local $idMenu = TrayCreateMenu("Menu") Local $idAbout = TrayCreateItem("About") TrayCreateItem("") Local $idExit = TrayCreateItem("Exit") Local $hMenu = TrayItemGetHandle(0) _GUICtrlMenu_SetItemBmp($hMenu, 0, BitmapFromIcon(0xFFFFFF, "shell32.dll", 17, True)) _GUICtrlMenu_SetItemBmp($hMenu, 1, BitmapFromIcon(0xFFFFFF, "shell32.dll", 130, True)) _GUICtrlMenu_SetItemBmp($hMenu, 3, BitmapFromIcon(0xFFFFFF, "shell32.dll", 131, True)) Do Until TrayGetMsg() = $idExit EndFunc ;==>Example Func BitmapFromIcon($nClrBK, $sIcon, $iIndex, $bSmall) Local $iSize = $bSmall ? 16 : 32 Local $hDC = _WinAPI_GetDC(0) Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = _WinAPI_CreateSolidBitmap(0, $nClrBK, $iSize, $iSize) Local $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap) Local $hIcon = _WinAPI_ExtractIcon($sIcon, $iIndex, $bSmall) _WinAPI_DrawIconEx($hMemDC, 0, 0, $hIcon, $iSize, $iSize, 0, 0, $DI_NORMAL) _WinAPI_DestroyIcon($hIcon) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteDC($hDC) _WinAPI_DeleteDC($hMemDC) Return $hBitmap EndFunc ;==>BitmapFromIcon If you want true transparency, here another example : ; From Nine #include <GUIMenu.au3> #include <GDIPlus.au3> #include <WinAPI.au3> Opt("TrayAutoPause", 0) Opt("TrayMenuMode", 3) Example() Func Example() _GDIPlus_Startup() Local $idMenu = TrayCreateMenu("Menu") Local $idAbout = TrayCreateItem("About") TrayCreateItem("") Local $idExit = TrayCreateItem("Exit") Local $hMenu = TrayItemGetHandle(0) SetMenuItemIcon("shell32.dll", 17, $hMenu, 0) SetMenuItemIcon("shell32.dll", 130, $hMenu, 1) SetMenuItemIcon("shell32.dll", 131, $hMenu, 3) Do Until TrayGetMsg() = $idExit _GDIPlus_Shutdown() EndFunc ;==>Example Func SetMenuItemIcon($sFile, $iIconID, $hMenu, $iMenuID) Local $hIcon = _WinAPI_ExtractIcon($sFile, $iIconID, True) Local $hBitmap = _GDIPlus_BitmapCreateFromHICON32($hIcon) Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _GUICtrlMenu_SetItemBmp($hMenu, $iMenuID, $hHBitmap) _WinAPI_DestroyIcon($hIcon) _GDIPlus_ImageDispose($hBitmap) EndFunc ;==>SetMenuItemIcon Edited Sunday at 07:07 PM by Nine xuankhanh1982 and WildByDesign 2 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
WildByDesign Posted Sunday at 09:46 PM Author Posted Sunday at 09:46 PM (edited) For quite a while now, I have wanted to know with absolute certainty that a users' OS supports the newer DarkMode_DarkTheme. And preferably, before the GUI even starts. In help topic How to search string resources in executable files I was asking for help on searching the aero.msstyles and/or uxtheme.dll binary files for whether Unicode string "DarkMode_DarkTheme" exists or not. The idea was similar to SysInternals Strings program. It was not successful in the end. Microsoft didn't add DarkMode_DarkTheme until later builds of 24H2/25H2 but earlier builds of 24H2/25H2 did not have it. So in GUIDarkTheme UDF, I currently check for OS build 26100.6899 or higher since 6899 was the revision in which MS added it. Potential problem? Microsoft has been doing a lot of A / B testing in Windows in recent years. Sometimes users of the very same OS build and revision may have completely different features that MS enables/disables server side and by various percentages of the user base. Anyway, I finally had an idea and came up with something. It works without GUI and therefore can be decided before a GUI is shown. The function simply gives True if the modern DarkMode_DarkTheme is supported or False if not. So in theory, Windows 10 and earlier Windows 11 builds should return False. More recent Windows 11 builds should return True. If anyone wants to test it on various OS builds or VMs, please feel free. If anyone has any suggestions for improvement, please let me know. If everything checks out OK, I will add this to the UDF. expandcollapse popup#include <WinAPITheme.au3> ; Obtain handle for AutoIt process without GUI Local $hWnd = _GetHwndFromPID(@AutoItPID) ConsoleWrite("Does OS support DarkMode_DarkTheme?" & @TAB & _isModernTheme($hWnd) & @CRLF) Func _isModernTheme($hWnd) Local Const $BP_PUSHBUTTON = 1 Local Const $EP_BACKGROUND = 3 Local Const $EBS_NORMAL = 1 Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_DarkTheme::Edit") If @error Then Return False Local $iColor = _WinAPI_GetThemeColor($hTheme, $EP_BACKGROUND, $EBS_NORMAL, $TMT_FILLCOLOR) If @error Then Return False _WinAPI_CloseThemeData($hTheme) $iColor = "0x" & Hex($iColor, 6) If $iColor = 0x262626 Then ; 0x262626 is official Edit brush color in DarkMode_DarkTheme Return True Else Return False EndIf EndFunc ;==>_isModernTheme ; 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 Edited Sunday at 09:48 PM by WildByDesign
argumentum Posted Sunday at 10:52 PM Posted Sunday at 10:52 PM (edited) expandcollapse popup#Region ; *** Dynamically added Include files *** #include <APIThemeConstants.au3> ; added:05/10/26 18:22:06 #EndRegion ; *** Dynamically added Include files *** #include <WinAPITheme.au3> ConsoleWrite("Does OS support DarkMode_DarkTheme?" & @TAB & _isModernTheme() & " ( " & "0x" & Hex(@extended, 6) & " )" & @CRLF) Func _isModernTheme($hWnd = Default) If Not _WinAPI_IsThemeActive() Then Return SetError(0, 1, False) Local Const $BP_PUSHBUTTON = 1 Local Const $EP_BACKGROUND = 3 Local Const $EBS_NORMAL = 1 If $hWnd = Default Then $hWnd = _GetHwndFromPID(@AutoItPID) ; Obtain handle for AutoIt process without GUI ;~ Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_Explorer::Edit") ; 0x212121 ;~ Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_CFD::Edit") ; 0x383838 Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_DarkTheme::Edit") ; 0x262626 If @error Then Return SetError(0, 2, False) Local $iColor = _WinAPI_GetThemeColor($hTheme, $EP_BACKGROUND, $EBS_NORMAL, $TMT_FILLCOLOR) If @error Then Return SetError(0, 3, False) _WinAPI_CloseThemeData($hTheme) If Hex($iColor, 6) <> "FFFFFF" Then Return SetError(0, $iColor, True) ; 0x262626 is official Edit brush color in DarkMode_DarkTheme Return SetError(0, $iColor, False) EndFunc ;==>_isModernTheme ; 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 Does OS support DarkMode_DarkTheme? True ( 0x262626 ) for testing this is better because, if false, we'll see why. Edited Sunday at 11:10 PM by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
WildByDesign Posted Sunday at 11:30 PM Author Posted Sunday at 11:30 PM (edited) 44 minutes ago, argumentum said: for testing this is better because, if false, we'll see why. I really like all of the changes that you've made and I will include all of them. It also reminds mind that I really need to learn how to use SetError function and start using it in any functions that I create. I've had that on my list of things to go back and try for a while. I'm curious about getting rid of the _GetHwndFromPID function because it could potentially (very minimally) cause slower init of GUIDarkTheme UDF and therefore a users' GUI who is using it. I'm thinking of a few (hopefully more efficient) ideas and would like your opinion. 1. Use temporary GUICreate and GUIDelete after theme data is closed. Func _isModernTheme() If Not _WinAPI_IsThemeActive() Then Return SetError(0, 1, False) Local Const $EP_BACKGROUND = 3 Local Const $EBS_NORMAL = 1 Local $hWnd = GUICreate("GUIDarkTheme") ; ADDED - temporary GUI creation ;~ Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_Explorer::Edit") ; 0x212121 ;~ Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_CFD::Edit") ; 0x383838 Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_DarkTheme::Edit") ; 0x262626 If @error Then Return SetError(0, 2, False) Local $iColor = _WinAPI_GetThemeColor($hTheme, $EP_BACKGROUND, $EBS_NORMAL, $TMT_FILLCOLOR) If @error Then Return SetError(0, 3, False) _WinAPI_CloseThemeData($hTheme) GUIDelete($hWnd) ; ADDED - GUI delete resources after theme data has been closed If Hex($iColor, 6) <> "FFFFFF" Then Return SetError(0, $iColor, True) ; 0x262626 is official Edit brush color in DarkMode_DarkTheme Return SetError(0, $iColor, False) EndFunc ;==>_isModernTheme 2. Use AutoItWinSetTitle to set a unique name for the hidden AutoIt window which that unique window name can easily be used to get a handle with WinGetHandle. AutoItWinSetTitle("GUIDarkTheme") Local $hWnd = WinGetHandle("GUIDarkTheme") ConsoleWrite("Does OS support DarkMode_DarkTheme?" & @TAB & _isModernTheme($hWnd) & @CRLF) Edited Sunday at 11:36 PM by WildByDesign
WildByDesign Posted Sunday at 11:44 PM Author Posted Sunday at 11:44 PM We can also keep it all within the function: Func _isModernTheme() Local $sTitle = AutoItWinGetTitle() ; get original AutoIt hidden window title AutoItWinSetTitle("GUIDarkTheme") ; set temporary title Local $hWnd = WinGetHandle("GUIDarkTheme") ; get handle for hidden AutoIt window AutoItWinSetTitle($sTitle) ; restore original title ; ... EndFunc
argumentum Posted Monday at 01:37 AM Posted Monday at 01:37 AM (edited) "The Dragon Ball Z Kai and the Z order" When you run your script the last window created is yours so all the AutoItWinGetTitle() is not that important because of the Z order. If I wanted to make mine unique I'd code: AutoItWinSetTitle("PID:" & @AutoItPID) > Use temporary GUICreate and GUIDelete after theme data is closed. That can be done too. But if you're looking for speed, test both and see what's your preference in regards to this function. I would not care much for 20 ms. more or less... as long as we don't have a bunch of 20 ms. more and more ..play with it, see what you prefer Func _isModernTheme() If Not _WinAPI_IsThemeActive() Then Return SetError(0, 1, False) Local Const $EP_BACKGROUND = 3 Local Const $EBS_NORMAL = 1 Local $hWnd = GUICreate("GUIDarkTheme") ; ADDED - temporary GUI creation ;~ Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_Explorer::Edit") ; 0x212121 ;~ Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_CFD::Edit") ; 0x383838 Local $hTheme = _WinAPI_OpenThemeData($hWnd, "DarkMode_DarkTheme::Edit") ; 0x262626 If @error Then GUIDelete($hWnd) ; ADDED - GUI delete resources after theme data has been closed <<<< Return SetError(0, 2, False) Local $iColor = _WinAPI_GetThemeColor($hTheme, $EP_BACKGROUND, $EBS_NORMAL, $TMT_FILLCOLOR) If @error Then GUIDelete($hWnd) ; ADDED - GUI delete resources after theme data has been closed <<<< Return SetError(0, 3, False) EndIf _WinAPI_CloseThemeData($hTheme) GUIDelete($hWnd) ; ADDED - GUI delete resources after theme data has been closed If Hex($iColor, 6) <> "FFFFFF" Then Return SetError(0, $iColor, True) ; 0x262626 is official Edit brush color in DarkMode_DarkTheme Return SetError(0, $iColor, False) EndFunc ;==>_isModernTheme Edited Monday at 01:41 AM by argumentum edit the code a bit Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
argumentum Posted Monday at 02:16 AM Posted Monday at 02:16 AM (edited) expandcollapse popup#include <WinAPIInternals.au3> #include <WinAPISysInternals.au3> #include <WindowsSysColorConstants.au3> ; give or take #include <APIThemeConstants.au3> #include <WinAPITheme.au3> Local $hTimer = TimerInit() ConsoleWrite('+ _CanDarkMode type: ' & _CanDarkMode() & ' ( 2="DarkMode_DarkTheme", 1="DarkMode_Explorer", 0=None ) ' & TimerDiff($hTimer) & ' ms. to gather' & @CRLF) Func _CanDarkMode() If Not _WinAPI_IsThemeActive() Then Return SetError(0, 1, False) Local $hWnd = GUICreate("GUIDarkTheme") ; ADDED - temporary GUI creation Local $iCOLOR_WINDOW = _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_WINDOW)) ; because of alt. themes Local $iColor = __WinAPI_Simple_GetThemeColor("DarkMode_DarkTheme::Edit", $hWnd) If Not @error And Hex($iColor, 6) <> Hex($iCOLOR_WINDOW, 6) Then GUIDelete($hWnd) Return 2 ; newer, a next new type in the future would be returning 3 and not braking the prior code EndIf Local $iColor = __WinAPI_Simple_GetThemeColor("DarkMode_Explorer::Edit", $hWnd) If Not @error And Hex($iColor, 6) <> Hex($iCOLOR_WINDOW, 6) Then GUIDelete($hWnd) Return 1 ; oldest EndIf GUIDelete($hWnd) Return 0 EndFunc ;==>_CanDarkMode Func __WinAPI_Simple_GetThemeColor($sClass, $hWnd = Default) Local Const $EP_BACKGROUND = 3 Local Const $EBS_NORMAL = 1 Local $hWndWas = $hWnd If IsKeyword($hWnd) Then $hWnd = GUICreate("Simple_GetThemeColor") Local $hTheme = _WinAPI_OpenThemeData($hWnd, $sClass) If @error Then If IsKeyword($hWndWas) Then GUIDelete($hWnd) ; ADDED - GUI delete resources after theme data has been closed Return SetError(1, 0, False) EndIf Local $iColor = _WinAPI_GetThemeColor($hTheme, $EP_BACKGROUND, $EBS_NORMAL, $TMT_FILLCOLOR) If @error Then If IsKeyword($hWndWas) Then GUIDelete($hWnd) ; ADDED - GUI delete resources after theme data has been closed Return SetError(2, 0, False) EndIf _WinAPI_CloseThemeData($hTheme) Return $iColor EndFunc ;==>__WinAPI_Simple_GetThemeColor + _CanDarkMode type: 2 ( 2="DarkMode_DarkTheme", 1="DarkMode_Explorer", 0=None ) 5.4549 ms. to gather ; 25H2 + _CanDarkMode type: 1 ( 2="DarkMode_DarkTheme", 1="DarkMode_Explorer", 0=None ) 4.4149 ms. to gather ; 24H2 ..how do you like this take of the function ? Edited Monday at 02:38 AM by argumentum better Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
WildByDesign Posted Monday at 10:24 AM Author Posted Monday at 10:24 AM 8 hours ago, argumentum said: ..how do you like this take of the function ? This is really slick. I like it. It checks all of the theme capability that is available which will then allow us to proceed as we need to depending on the return. I also like how to check to ensure that the returned color is not $COLOR_WINDOW instead of checking a specific color (0x262626 or whatever) like I was doing. Your method is more "future-proof" in case MS decides to modify the colors in a future update. + _CanDarkMode type: 2 ( 2="DarkMode_DarkTheme", 1="DarkMode_Explorer", 0=None ) 1.0536 ms. to gather The function is very fast as well. 1-2 ms here. Just to confirm, I am not looking for a boolean return anymore, right? I need to proceed based on 0, 1, 2 and then maybe 3 or more in the future, is that correct?
WildByDesign Posted Monday at 12:45 PM Author Posted Monday at 12:45 PM 10 hours ago, argumentum said: ..how do you like this take of the function ? I'm using both functions exactly as you have them because it's fantastic. I went ahead and added the functionality into GUIDarkTheme UDF locally on my machine just to get an idea of how well it all works. The main goal is to provide the Global $__DM_g_b24H2Plus boolean with details on how to proceed with which theme to apply based on OS capabilities. The $__DM_g_b24H2Plus variable is used 20+ times throughout the UDF which are then used as Ternary. I think it was you who taught me a while back that boolean was faster in situations where you need things to be fast and efficient. Anyway, what I have done so far to accommodate the new functions is to add a little helper function: ; top of UDF - determine if DarkMode_DarkTheme is available on OS Global $__DM_g_b24H2Plus = _DarkModeThemeAvailability() ; ; Func _DarkModeThemeAvailability() Local $iRet = _CanDarkMode() Switch $iRet Case 2 ; DarkMode_DarkTheme is available Return True Case 1 ; DarkMode_Explorer is available, used only when DarkMode_DarkTheme is not available Return False Case Else ; uh oh Return False EndSwitch EndFunc ;==>_DarkModeThemeAvailability What are your thoughts on this approach?
argumentum Posted Monday at 01:42 PM Posted Monday at 01:42 PM "Local Static $iRet = _CanDarkMode()" will be better because it needs to be called once. In regards of using Booleans everywhere, that's an architectural choice. Say you like chocolate ice cream or vanilla ice cream, having a yes or no answer would only say that you like ice cream, but not the type. So you could have one for chocolate, two for vanilla, and zero for no thank you, I don't like ice cream. In my case, it's a Boolean because I just woke up and the question is, do I need coffee or not? And the answer is, yes, I need coffee. And I always drink expresso coffee, so there's no question on what type of coffee. But it's just for me. I would have to ask around if other people want coffee.... 🤔 "_CanDarkMode" It's not a good name, or maybe it is. Maybe "_AvailableDarkModes()" is truer to what it actually does. WildByDesign 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
argumentum Posted Monday at 02:10 PM Posted Monday at 02:10 PM 3 hours ago, WildByDesign said: I need to proceed based on 0, 1, 2 and then maybe 3 or more in the future, is that correct? That's why I was asking how do you like this approach?, Because you can make a Boolean, but I was thinking that could work as, is there dark mode? And if there is, what type of dark mode.... , It's just an idea. 🧐 WildByDesign 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
WildByDesign Posted Monday at 02:22 PM Author Posted Monday at 02:22 PM 6 minutes ago, argumentum said: That's why I was asking how do you like this approach?, Because you can make a Boolean, but I was thinking that could work as, is there dark mode? And if there is, what type of dark mode.... , It's just an idea. 🧐 You made all great points in your previous reply, by the way. And you’ve got me craving a freshly ground Colombian coffee right now so I must do that first. I do like the approach and it does make good sense because there is also your return of 0 which could be important. I assume that would mean that IsThemeActive returned false and/or the older DarkMode_Explorer is not available. So that case would likely indicate that the script is running on an OS build that is not Win10 or Win11 and therefore incompatible with the UDF. Speaking of Case 0, what should I do in that case? I assume some sort of messaging would need to be presented to the user such as a MsgBox to mention incompatibility. In that case, MsgBox and then disengage the UDF?
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