UEZ Posted Tuesday at 06:51 PM Posted Tuesday at 06:51 PM (edited) I tried to apply dark mode to the SampleControls.au3 example. What I did so far: expandcollapse popup; Coded by UEZ build 2025-10-17 beta ;not DPI aware! #include <APIConstants.au3> #include <AVIConstants.au3> #include <GUIConstantsEx.au3> #include <GuiDateTimePicker.au3> #include <GuiMenu.au3> #include <GuiMonthCal.au3> #include <GuiScrollBars.au3> #include <GuiTab.au3> #include <TreeViewConstants.au3> #include <ListViewConstants.au3> #include <WinAPIConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIRes.au3> #include <WinAPIShellEx.au3> #include <WinAPISys.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> Enum $IHCM_USE_CACHED_VALUE, $IHCM_REFRESH Enum $APPMODE_DEFAULT = 0, $APPMODE_ALLOWDARK, $APPMODE_FORCEDARK, $APPMODE_FORCELIGHT, $APPMODE_MAX Const $PRF_CLIENT = 0x04 ; Dark Mode Colors (RGB) Global Const $COLOR_BG_DARK = 0x202020 Global Const $COLOR_TEXT_LIGHT = 0xFFFFFF Global Const $COLOR_CONTROL_BG = 0x2B2B2B Global Const $COLOR_EDIT_BG = 0x1E1E1E Global Const $COLOR_BUTTON_BG = 0x333333 Global Const $COLOR_BORDER = 0x3F3F3F ; Global variables for subclassing (MUST be declared before _Example()!) Global $g_hGUI = 0, $g_hTab, $g_ListView Global $g_aControls[50][3] = [[0, 0, 0]] ; [ControlID, hWnd, OldWndProc] Global $g_iControlCount = 0 Global $g_pSubclassProc = 0 ; Global brushes for _WM_CTLCOLOR (avoids memory leaks) Global $g_hBrushEdit = 0 Global $g_hBrushButton = 0 Global $g_hBrushBg = 0 Global $g_hBrushGreen Global $g_hLabelGreen = 0, $g_idLabelGreen Global $g_idLabelPic, $g_hLabelPic Global $g_hMenu = 0 Global $g_idDate = 0, $g_hDate = 0 ; Global variable for tab subclassing Global $g_hTab_CB, $g_pTab_CB, $g_hProc ; Structure for NM_CUSTOMDRAW notification Global Const $tagNMCUSTOMDRAW = _ $tagNMHDR & ";" & _ ; Contains NM_CUSTOMDRAW / NMHDR header among other things "dword dwDrawStage;" & _ ; Current drawing stage (CDDS_*) "handle hdc;" & _ ; Device Context Handle "long left;long top;long right;long bottom;" & _ ; Drawing rectangle "dword_ptr dwItemSpec;" & _ ; Item index or other info (depending on the control) "uint uItemState;" & _ ; State Flags (CDIS_SELECTED, CDIS_FOCUS etc.) "lparam lItemlParam" ; lParam set by the item (e.g., via LVITEM.lParam) Global $g_hMenu = 0, $hMenuFont Global $g_aMenuText = [] ; dynamic array for top-level menu texts Global $arMenuItems[1][8] $arMenuItems[0][0] = 0 Global $arSideItems[1][10] $arSideItems[0][0] = 0 Const $ODT_MENU = 1 Const $ODS_SELECTED = 0x0001 Const $ODS_DISABLED = 0x0004 _Example() Func _Example() ; Create global brushes $g_hBrushEdit = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_EDIT_BG)) $g_hBrushButton = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BUTTON_BG)) $g_hBrushBg = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) #Region GUI $g_hGUI = GUICreate("Sample GUI with Dark Mode", 400, 400) GUISetIcon(@SystemDir & "\mspaint.exe", 0) GUISetBkColor($COLOR_BG_DARK, $g_hGUI) ; Register GUI-level WM_CTLCOLOR messages GUIRegisterMsg($WM_CTLCOLOREDIT, "_WM_CTLCOLOR") GUIRegisterMsg($WM_CTLCOLORLISTBOX, "_WM_CTLCOLOR") GUIRegisterMsg($WM_CTLCOLORBTN, "_WM_CTLCOLOR") GUIRegisterMsg($WM_CTLCOLORSTATIC, "_WM_CTLCOLOR") GUIRegisterMsg($WM_INITMENUPOPUP, "_OnInitMenuPopup") GUIRegisterMsg($WM_MEASUREITEM, "WM_MEASUREITEM_Handler") GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM_Handler") GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUIRegisterMsg($WM_ACTIVATE, "_WM_ACTIVATE_OverpaintLine") GUIRegisterMsg($WM_WINDOWPOSCHANGED, "_WM_WINDOWPOSCHANGED_OverpaintLine") #EndRegion GUI #Region MENU Global $g_aMenuText[4] $g_aMenuText[0] = "Menu &One" $g_aMenuText[1] = "Menu &Two" $g_aMenuText[2] = "Menu Th&ree" $g_aMenuText[3] = "Menu &Four" Local $idMenu1 = GUICtrlCreateMenu($g_aMenuText[0]) Local $idMenu2 = GUICtrlCreateMenu($g_aMenuText[1]) GUICtrlCreateMenu($g_aMenuText[2]) GUICtrlCreateMenu($g_aMenuText[3]) GUICtrlCreateMenuItem('SubMenu One &A', $idMenu1) GUICtrlCreateMenuItem('SubMenu One &B', $idMenu1) ; Owner-draw Top-Level Menu einrichten _MakeMenuOwnerDraw($g_hGUI) #EndRegion MENU #Region CONTEXT MENU Local $idContextMenu = GUICtrlCreateContextMenu() GUICtrlCreateMenuItem("Context Menu", $idContextMenu) GUICtrlCreateMenuItem("", $idContextMenu) GUICtrlCreateMenuItem("&Properties", $idContextMenu) #EndRegion CONTEXT MENU #Region PIC Local $idPic = GUICtrlCreatePic("", 0, 0, 169, 68) GUICtrlSetImage($idPic, "C:\Program Files (x86)\AutoIt3\Examples\GUI\logo4.gif") GUICtrlSetTip(-1, '#Region PIC') $g_idLabelPic = GUICtrlCreateLabel("Sample Pic", 75, 1, 53, 15) $g_hLabelPic = GUICtrlGetHandle($g_idLabelPic) #EndRegion PIC #Region AVI Local $idAvi = GUICtrlCreateAvi("C:\Program Files (x86)\AutoIt3\Examples\GUI\SampleAVI.avi", 0, 180, 10, 32, 32, $ACS_AUTOPLAY) GUICtrlSetTip(-1, '#Region AVI') GUICtrlCreateLabel("Sample avi", 175, 50) #EndRegion AVI #Region TAB Local $idTab = GUICtrlCreateTab(240, 0, 150, 70), $g_hTab = GUICtrlGetHandle($idTab) _AddControlForSubclass($idTab) GUICtrlCreateTabItem("One") GUICtrlSetTip(-1, '#Region TAB1') GUICtrlCreateLabel("Sample Tab", 250, 40) GUICtrlCreateTabItem("Two") GUICtrlSetTip(-1, '#Region TAB2') GUICtrlCreateTabItem("Three") GUICtrlSetTip(-1, '#Region TAB3') GUICtrlCreateTabItem("") $g_hTab = GUICtrlGetHandle($idTab) #EndRegion TAB #Region COMBO Local $idCombo = GUICtrlCreateCombo("Sample Combo", 250, 80, 120, 100) GUICtrlSetData($idCombo, "Item 2|Item 3", "Sample Combo") _AddControlForSubclass($idCombo) GUICtrlSetTip(-1, '#Region COMBO') #EndRegion COMBO #Region PROGRESS Local $idProgress = GUICtrlCreateProgress(60, 80, 150, 20) _AddControlForSubclass($idProgress) GUICtrlSetTip(-1, '#Region PROGRESS') GUICtrlSetData(-1, 60) GUICtrlCreateLabel("Progress:", 5, 82) #EndRegion PROGRESS #Region EDIT Local $idEdit = GUICtrlCreateEdit(@CRLF & " Sample Edit Control", 10, 110, 150, 70) _AddControlForSubclass($idEdit) GUICtrlSetTip(-1, '#Region EDIT') #EndRegion EDIT #Region LIST Local $idList = GUICtrlCreateList("", 5, 190, 100, 90) _AddControlForSubclass($idList) GUICtrlSetTip(-1, '#Region LIST') GUICtrlSetData(-1, "A.Sample|B.List|C.Control|D.Here", "B.List") #EndRegion LIST #Region ICON GUICtrlCreateIcon("explorer.exe", 0, 175, 120) GUICtrlSetTip(-1, '#Region ICON') GUICtrlCreateLabel("Icon", 180, 160, 50, 20) #EndRegion ICON #Region LIST VIEW Local $idListView = GUICtrlCreateListView("Sample|ListView|", 110, 190, 110, 80, $LVS_REPORT) _AddControlForSubclass($idListView) GUICtrlSetBkColor($idListView, $COLOR_EDIT_BG) GUICtrlSetColor($idListView, $COLOR_TEXT_LIGHT) GUICtrlSetTip(-1, '#Region LIST VIEW') GUICtrlCreateListViewItem("A|One", $idListView) GUICtrlCreateListViewItem("B|Two", $idListView) GUICtrlCreateListViewItem("C|Three", $idListView) $g_ListView = GUICtrlGetHandle($idListView) #EndRegion LIST VIEW #Region GROUP WITH RADIO BUTTONS Local $idGroup = GUICtrlCreateGroup("Sample Group", 230, 120) GUICtrlSetColor($idGroup, $COLOR_TEXT_LIGHT) Local $idRadio1 = GUICtrlCreateRadio("Radio One", 250, 140, 80) GUICtrlSetTip($idRadio1, '#Region RADIO1') GUICtrlSetState($idRadio1, $GUI_CHECKED) Local $idRadio2 = GUICtrlCreateRadio("Radio Two", 250, 165, 80) GUICtrlSetTip($idRadio2, '#Region RADIO2') GUICtrlCreateGroup("", -99, -99, 1, 1) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle($idGroup), "wstr", 0, "wstr", 0) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle($idRadio1), "wstr", 0, "wstr", 0) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle($idRadio2), "wstr", 0, "wstr", 0) #EndRegion GROUP WITH RADIO BUTTONS #Region UPDOWN GUICtrlCreateLabel("UpDown", 350, 115) GUICtrlSetColor(-1, $COLOR_TEXT_LIGHT) Local $idInput = GUICtrlCreateInput("42", 350, 130, 40, 20) _AddControlForSubclass($idInput) Local $idUpDown = GUICtrlCreateUpdown(-1) _AddControlForSubclass($idUpDown) #EndRegion UPDOWN #Region LABEL $g_idLabelGreen = GUICtrlCreateLabel("Green" & @CRLF & "Label", 350, 165, 40, 40) $g_hLabelGreen = GUICtrlGetHandle($g_idLabelGreen) GUICtrlSetTip($g_idLabelGreen, '#Region LABEL') $g_hBrushGreen = _WinAPI_CreateSolidBrush(_ColorToCOLORREF(0x00FF00)) ; green background #Region SLIDER GUICtrlCreateLabel("Slider:", 235, 215) Local $idSlider = GUICtrlCreateSlider(270, 210, 120, 30) _AddControlForSubclass($idSlider) GUICtrlSetTip(-1, '#Region SLIDER') GUICtrlSetData(-1, 30) #EndRegion SLIDER #Region INPUT Local $idInput2 = GUICtrlCreateInput("Sample Input Box", 235, 255, 130, 20) _AddControlForSubclass($idInput2) GUICtrlSetTip(-1, '#Region INPUT') #EndRegion INPUT #Region DATE $g_idDate = GUICtrlCreateDate("", 5, 280, 200, 20) $g_hDate = GUICtrlGetHandle($g_idDate) _AddControlForSubclass($g_idDate) GUICtrlSetTip(-1, '#Region DATE') GUICtrlCreateLabel("(Date control expands into a calendar)", 10, 305, 200, 20) #EndRegion DATE #Region BUTTON Local $idButton = GUICtrlCreateButton("Sample Button", 10, 330, 100, 30) _AddControlForSubclass($idButton) GUICtrlSetTip(-1, '#Region BUTTON') #EndRegion BUTTON #Region CHECKBOX Local $idCheckBox = GUICtrlCreateCheckbox("Checkbox", 130, 335, 80, 20) GUICtrlSetTip(-1, '#Region CHECKBOX') DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle($idCheckBox), "wstr", 0, "wstr", 0) #EndRegion CHECKBOX #Region TREEVIEW ONE Local $idTreeView1 = GUICtrlCreateTreeView(210, 290, 80, 80) _AddControlForSubclass($idTreeView1) GUICtrlSetBkColor($idTreeView1, $COLOR_EDIT_BG) GUICtrlSetColor($idTreeView1, $COLOR_TEXT_LIGHT) GUICtrlSetTip(-1, '#Region TREEVIEW ONE') Local $idTreeViewItem = GUICtrlCreateTreeViewItem("TreeView", $idTreeView1) GUICtrlCreateTreeViewItem("Item1", $idTreeViewItem) GUICtrlCreateTreeViewItem("Item2", $idTreeViewItem) GUICtrlCreateTreeViewItem("Foo", -1) GUICtrlSetState($idTreeViewItem, $GUI_EXPAND) #EndRegion TREEVIEW ONE #Region TREEVIEW TWO Local $idTreeView2 = GUICtrlCreateTreeView(295, 290, 103, 80, $TVS_CHECKBOXES) _AddControlForSubclass($idTreeView2) GUICtrlSetBkColor($idTreeView2, $COLOR_EDIT_BG) GUICtrlSetColor($idTreeView2, $COLOR_TEXT_LIGHT) GUICtrlSetTip(-1, '#Region TREEVIEW TWO') GUICtrlCreateTreeViewItem("TreeView", $idTreeView2) GUICtrlCreateTreeViewItem("With", $idTreeView2) GUICtrlCreateTreeViewItem("$TVS_CHECKBOXES", $idTreeView2) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateTreeViewItem("Style", $idTreeView2) #EndRegion TREEVIEW TWO ; Apply Dark Mode _ApplyDarkModeToAllControls() ; Handle scrollbars for windows that have them _EnableDarkScrollBars() ; Register a custom window procedure for the tab control for owner-drawing $g_hTab_CB = DllCallbackRegister('_WinProc', 'ptr', 'hwnd;uint;wparam;lparam') $g_pTab_CB = DllCallbackGetPtr($g_hTab_CB) $g_hProc = _WinAPI_SetWindowLong($g_hTab, $GWL_WNDPROC, $g_pTab_CB) GUISetState(@SW_SHOW) _OverpaintWhiteLine() _WinAPI_RedrawWindow($g_hGUI, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _CleanupSubclassing() _CleanupBrushes() ExitLoop EndSwitch WEnd ; Restore the original window procedure for the tab control _WinAPI_SetWindowLong($g_hTab, $GWL_WNDPROC, $g_hProc) DllCallbackFree($g_hTab_CB) GUIDelete() EndFunc ;==>_Example Func _OverpaintWhiteLine() Local $hDC = _WinAPI_GetWindowDC($g_hGUI) If Not $hDC Then Return Local $tWndRect = _WinAPI_GetWindowRect($g_hGUI) Local $iWndWidth = $tWndRect.right - $tWndRect.left ; 1. Caption height Local $iCaptionHeight = _WinAPI_GetSystemMetrics($SM_CYCAPTION) ; 2. Border height (top) Local $iBorderHeight = _WinAPI_GetSystemMetrics($SM_CYSIZEFRAME) If $iBorderHeight = 0 Then $iBorderHeight = _WinAPI_GetSystemMetrics($SM_CYFIXEDFRAME) ; 3. Determine menu height dynamically Local $iMenuHeight = _WinAPI_GetSystemMetrics($SM_CYMENU) ; standard menu height ; Alternative: get menu height via GetMenuBarInfo Local $tMenuBarInfo = DllStructCreate("dword cbSize;long left;long top;long right;long bottom;handle hwndMenu;handle hwndItem;bool fBarFocused;bool fFocused") DllStructSetData($tMenuBarInfo, "cbSize", DllStructGetSize($tMenuBarInfo)) Local $aResult = DllCall("user32.dll", "bool", "GetMenuBarInfo", "hwnd", $g_hGUI, "long", 0xFFFFFFFD, "long", 0, "ptr", DllStructGetPtr($tMenuBarInfo)) If IsArray($aResult) And $aResult[0] Then ; Calculate the actual menu height from the coordinates Local $iMenuTop = $tMenuBarInfo.top Local $iMenuBottom = $tMenuBarInfo.bottom ; Convert to window coordinates $iMenuHeight = ($iMenuBottom - $iMenuTop) EndIf ; The white line is directly below the menu Local $iWhiteLineY = $iCaptionHeight + $iBorderHeight + $iMenuHeight - _WinAPI_GetSystemMetrics($SM_CYFIXEDFRAME) * 2 ;~ ConsoleWrite("Caption: " & $iCaptionHeight & ", Border: " & $iBorderHeight & ", Menu: " & $iMenuHeight & " -> White Line at Y=" & $iWhiteLineY & @CRLF) ; Overpaint the white line (1x2 pixels) Local $tRect = DllStructCreate($tagRECT) With $tRect .left = 0 .top = $iWhiteLineY .right = $iWndWidth .bottom = $iWhiteLineY + 2 ; 2 pixels high EndWith Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) ;~ Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF(0xFF0000)) _WinAPI_FillRect($hDC, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) _WinAPI_ReleaseDC($g_hGUI, $hDC) EndFunc ;==>_OverpaintWhiteLine Func _WM_ACTIVATE_OverpaintLine($hWnd, $iMsg, $wParam, $lParam) If $hWnd <> $g_hGUI Then Return $GUI_RUNDEFMSG _OverpaintWhiteLine() Return $GUI_RUNDEFMSG EndFunc ;==>_WM_ACTIVATE_OverpaintLine Func _WM_WINDOWPOSCHANGED_OverpaintLine($hWnd, $iMsg, $wParam, $lParam) If $hWnd <> $g_hGUI Then Return $GUI_RUNDEFMSG _OverpaintWhiteLine() Return $GUI_RUNDEFMSG EndFunc ;==>_WM_WINDOWPOSCHANGED_OverpaintLine Func _OnInitMenuPopup($hWnd, $iMsg, $wParam, $lParam) ; wParam = HMENU of the popup, lParam = position/index - not needed here ; A small delay sometimes helps to ensure the popup window exists Sleep(100) ; The foreground window is most likely the new menu popup Local $hPopup = _WinAPI_GetForegroundWindow() If Not $hPopup Then Return $GUI_RUNDEFMSG Local $sCls = StringLower(_WinAPI_GetClassName($hPopup)) If $sCls <> "#32768" And $sCls <> "popupmenu" Then ; if no menu popup is detected -> do nothing Return $GUI_RUNDEFMSG EndIf ; Set Theme + AllowDarkMode on the popup itself _WinAPI_SetWindowTheme($hPopup, "DarkMode_Explorer", "") _WinAPI_AllowDarkModeForWindow($hPopup, True) ; Also apply the theme to all child windows of the popup (e.g., scrollbars) Local $hChild = _WinAPI_GetWindow($hPopup, $GW_CHILD) While $hChild Local $sChildCls = StringLower(_WinAPI_GetClassName($hChild)) ; apply theme specifically for scrollbars, UpDown, etc. If $sChildCls = "scrollbar" Or $sChildCls = "msctls_updown32" Or $sChildCls = "traynotifywnd" Then _WinAPI_SetWindowTheme($hChild, "DarkMode_Explorer", "") _WinAPI_AllowDarkModeForWindow($hChild, True) Else ; try generically _WinAPI_SetWindowTheme($hChild, "DarkMode_Explorer", "") _WinAPI_AllowDarkModeForWindow($hChild, True) EndIf $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT) WEnd ; Force refresh so the change is visible immediately _WinAPI_FlushMenuThemes() _WinAPI_RefreshImmersiveColorPolicyState() _WinAPI_RedrawWindow($hPopup, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) Return $GUI_RUNDEFMSG EndFunc ;==>_OnInitMenuPopup Func _ColorToCOLORREF($iColor) ;RGB to BGR Local $iR = BitAND(BitShift($iColor, 16), 0xFF) Local $iG = BitAND(BitShift($iColor, 8), 0xFF) Local $iB = BitAND($iColor, 0xFF) Return BitOR(BitShift($iB, -16), BitShift($iG, -8), $iR) EndFunc ;==>_ColorToCOLORREF Func _AddControlForSubclass($iCtrlID) Local $hCtrl = GUICtrlGetHandle($iCtrlID) If $hCtrl Then $g_aControls[$g_iControlCount][0] = $iCtrlID $g_aControls[$g_iControlCount][1] = $hCtrl $g_aControls[$g_iControlCount][2] = 0 ; Placeholder for OldWndProc $g_iControlCount += 1 EndIf EndFunc ;==>_AddControlForSubclass Func _ApplyDarkModeToAllControls() ; DWM Dark Mode for the main window _WinAPI_SetPreferredAppMode($APPMODE_FORCEDARK) ; Create subclass callback If Not $g_pSubclassProc Then $g_pSubclassProc = DllCallbackRegister("_SubclassProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") EndIf ; Subclass all controls For $i = 0 To $g_iControlCount - 1 Local $hCtrl = $g_aControls[$i][1] If $hCtrl Then Local $sClass = _WinAPI_GetClassName($hCtrl) ; Use SetWindowSubclass _WinAPI_SetWindowSubclass($hCtrl, DllCallbackGetPtr($g_pSubclassProc), $i, 0) ; Special themes for different control types Switch StringLower($sClass) Case "edit", "richedit", "richedit20a", "richedit20w" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_CFD", 0) Case "button" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "combobox" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_CFD", 0) ; Handle ComboBox child-edit Local $hEdit = _WinAPI_FindWindowEx($hCtrl, 0, "Edit", "") If $hEdit Then _WinAPI_SetWindowTheme($hEdit, "DarkMode_CFD", 0) _WinAPI_AllowDarkModeForWindow($hEdit, True) EndIf ; ComboBox dropdown list Local $hComboLBox = _WinAPI_FindWindowEx($hCtrl, 0, "ComboLBox", "") If $hComboLBox Then _WinAPI_SetWindowTheme($hComboLBox, "DarkMode_Explorer", 0) _WinAPI_AllowDarkModeForWindow($hComboLBox, True) EndIf Case "syslistview32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) ; ListView extended styles for better dark mode _SendMessage($hCtrl, $LVS_EX_DOUBLEBUFFER, 0x00010000, 0x00010000) ; Also make the ListView header dark Local $hHeader = _SendMessage($hCtrl, $LVM_GETHEADER, 0, 0) If $hHeader Then _WinAPI_SetWindowTheme($hHeader, "DarkMode_ItemsView", 0) EndIf Case "systreeview32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "msctls_trackbar32" ; Slider _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "systabcontrol32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", "") ;must be "" ; tab-Control background _SendMessage($hCtrl, 0x132D, 0, $COLOR_BG_DARK) ; TCM_SETBKCOLOR ; Try to make the UpDown (spinner for too many tabs) dark as well Local $hUpDown = _WinAPI_FindWindowEx($hCtrl, 0, "msctls_updown32", "") If $hUpDown Then _WinAPI_SetWindowTheme($hUpDown, "DarkMode_Explorer", 0) Case "listbox" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "msctls_progress32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "scrollbar" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case Else _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) EndSwitch _WinAPI_AllowDarkModeForWindow($hCtrl, True) EndIf Next ; Update theme system _WinAPI_RefreshImmersiveColorPolicyState() _WinAPI_FlushMenuThemes() _WinAPI_DwmSetWindowAttribute($g_hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) ; Redraw GUI _WinAPI_RedrawWindow($g_hGUI, 0, 0, $RDW_UPDATENOW) EndFunc ;==>_ApplyDarkModeToAllControls Func _CleanupSubclassing() ; Remove all subclasses If $g_pSubclassProc Then For $i = 0 To $g_iControlCount - 1 Local $hCtrl = $g_aControls[$i][1] If $hCtrl Then _WinAPI_RemoveWindowSubclass($hCtrl, DllCallbackGetPtr($g_pSubclassProc), $i) EndIf Next DllCallbackFree($g_pSubclassProc) $g_pSubclassProc = 0 EndIf EndFunc ;==>_CleanupSubclassing Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) Switch $iMsg Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hFrom = $tNMHDR.hWndFrom Local $iCode = $tNMHDR.Code ; --- Adjust ListView Header text color --- If $iCode = $NM_CUSTOMDRAW Then Local $tNMCUSTOMDRAW = DllStructCreate($tagNMCUSTOMDRAW, $lParam) Local $dwDrawStage = $tNMCUSTOMDRAW.dwDrawStage Local $hDC = $tNMCUSTOMDRAW.hdc Switch $dwDrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT _WinAPI_SetTextColor($hDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) ; White text _WinAPI_SetBkColor($hDC, _ColorToCOLORREF($COLOR_BG_DARK)) ; Dark background Return BitOR($CDRF_NEWFONT, $CDRF_NOTIFYPOSTPAINT) EndSwitch EndIf Case $WM_PAINT ; Custom Paint for better Dark Mode rendering Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndSwitch ; Forward standard message to DefSubclassProc Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc Func _MakeMenuOwnerDraw($hWnd) ; Get menu handle $g_hMenu = _GUICtrlMenu_GetMenu($hWnd) If Not $g_hMenu Then Return False Local $iCount = _GUICtrlMenu_GetItemCount($g_hMenu) If $iCount <= 0 Then Return False ReDim $g_aMenuText[$iCount] For $i = 0 To $iCount - 1 ; retrieve text via GetMenuStringW (works better than _GUICtrlMenu_GetItemText) Local $tText = DllStructCreate("wchar s[256]") Local $iLen = DllCall("user32.dll", "int", "GetMenuStringW", _ "handle", $g_hMenu, _ "uint", $i, _ "struct*", $tText, _ "int", 255, _ "uint", 0x0400) ; MF_BYPOSITION If IsArray($iLen) And $iLen[0] > 0 Then $g_aMenuText[$i] = $tText.s Else $g_aMenuText[$i] = "" EndIf ; set top-level item to owner-draw _GUICtrlMenu_SetItemType($g_hMenu, $i, $MFT_OWNERDRAW, True) Next ; redraw menu bar immediately _GUICtrlMenu_DrawMenuBar($hWnd) _WinAPI_RedrawWindow($hWnd, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) Return True EndFunc ;==>_MakeMenuOwnerDraw Func WM_MEASUREITEM_Handler($hWnd, $iMsg, $wParam, $lParam) Local $tagMEASUREITEM = "uint CtlType;uint CtlID;uint itemID;uint itemWidth;uint itemHeight;ulong_ptr itemData" Local $t = DllStructCreate($tagMEASUREITEM, $lParam) If Not IsDllStruct($t) Then Return $GUI_RUNDEFMSG If $t.CtlType <> $ODT_MENU Then Return $GUI_RUNDEFMSG Local $itemID = $t.itemID ; itemID is the control ID, not the position! ; We must derive the position from the itemID Local $iPos = -1 For $i = 0 To UBound($g_aMenuText) - 1 If $itemID = ($i + 3) Then ; Offset of 3 due to internal IDs $iPos = $i ExitLoop EndIf Next ; Fallback: try the itemID directly If $iPos < 0 Then $iPos = $itemID If $iPos < 0 Or $iPos >= UBound($g_aMenuText) Then $iPos = 0 Local $sText = $g_aMenuText[$iPos] ; Calculate text dimensions Local $hDC = _WinAPI_GetDC($hWnd) Local $hFont = _SendMessage($hWnd, $WM_GETFONT, 0, 0) If Not $hFont Then $hFont = _WinAPI_GetStockObject($DEFAULT_GUI_FONT) Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) Local $tSize = _WinAPI_GetTextExtentPoint32($hDC, $sText) Local $iTextWidth = $tSize.X Local $iTextHeight = $tSize.Y _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_ReleaseDC($hWnd, $hDC) ; Set dimensions with padding $t.itemWidth = $iTextWidth + 1 $t.itemHeight = $iTextHeight + 1 Return 1 EndFunc ;==>WM_MEASUREITEM_Handler Func WM_DRAWITEM_Handler($hWnd, $iMsg, $wParam, $lParam) Local $tagDRAWITEM = "uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;ptr hwndItem;handle hDC;" & _ "long left;long top;long right;long bottom;ulong_ptr itemData" Local $t = DllStructCreate($tagDRAWITEM, $lParam) If Not IsDllStruct($t) Then Return $GUI_RUNDEFMSG If $t.CtlType <> $ODT_MENU Then Return $GUI_RUNDEFMSG Local $hDC = $t.hDC Local $left = $t.left Local $top = $t.top Local $right = $t.right Local $bottom = $t.bottom Local $state = $t.itemState Local $itemID = $t.itemID ; convert itemID to position Local $iPos = -1 For $i = 0 To UBound($g_aMenuText) - 1 If $itemID = ($i + 3) Then $iPos = $i ExitLoop EndIf Next If $iPos < 0 Then $iPos = $itemID If $iPos < 0 Or $iPos >= UBound($g_aMenuText) Then $iPos = 0 Local $sText = $g_aMenuText[$iPos] $sText = StringReplace($sText, "&", "") ; Colors Local $clrBG = _ColorToCOLORREF($COLOR_BG_DARK) Local $clrSel = _ColorToCOLORREF(0x505050) Local $clrText = _ColorToCOLORREF($COLOR_TEXT_LIGHT) Static $iDrawCount = 0 Static $bFullBarDrawn = False ; Count how many items were drawn in this "draw cycle" $iDrawCount += 1 ; If we are at the first item AND the bar has not yet been drawn If $iPos = 0 And Not $bFullBarDrawn Then ; Get the full window width Local $tClient = _WinAPI_GetClientRect($hWnd) Local $iFullWidth = DllStructGetData($tClient, "right") ; Fill the entire menu bar Local $tFullMenuBar = DllStructCreate($tagRECT) With $tFullMenuBar .left = 0 .top = $top .right = $iFullWidth + 3 .bottom = $bottom EndWith Local $hFullBrush = _WinAPI_CreateSolidBrush($clrBG) _WinAPI_FillRect($hDC, $tFullMenuBar, $hFullBrush) _WinAPI_DeleteObject($hFullBrush) EndIf ; After drawing all items, mark as "drawn" If $iDrawCount >= UBound($g_aMenuText) Then $bFullBarDrawn = True $iDrawCount = 0 EndIf ; Draw background for the area AFTER the last menu item If $iPos = (UBound($g_aMenuText) - 1) Then ; Last menu Local $tClient = _WinAPI_GetClientRect($hWnd) Local $iFullWidth = DllStructGetData($tClient, "right") ; Fill only the area to the RIGHT of the last menu item If $right < $iFullWidth Then Local $tEmptyArea = DllStructCreate($tagRECT) With $tEmptyArea .left = $right .top = $top .right = $iFullWidth + _WinAPI_GetSystemMetrics(7) .bottom = $bottom EndWith Local $hEmptyBrush = _WinAPI_CreateSolidBrush($clrBG) _WinAPI_FillRect($hDC, $tEmptyArea, $hEmptyBrush) _WinAPI_DeleteObject($hEmptyBrush) EndIf EndIf ; Draw item background (selected = lighter) Local $bSelected = BitAND($state, $ODS_SELECTED) Local $hBrush = _WinAPI_CreateSolidBrush($bSelected ? $clrSel : $clrBG) Local $tItemRect = DllStructCreate($tagRECT) With $tItemRect .left = $left .top = $top .right = $right .bottom = $bottom EndWith _WinAPI_FillRect($hDC, $tItemRect, $hBrush) _WinAPI_DeleteObject($hBrush) ; Setup font Local $hFont = _SendMessage($hWnd, $WM_GETFONT, 0, 0) If Not $hFont Then $hFont = _WinAPI_GetStockObject($DEFAULT_GUI_FONT) Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) _WinAPI_SetBkMode($hDC, $TRANSPARENT) _WinAPI_SetTextColor($hDC, $clrText) ; Draw text Local $tTextRect = DllStructCreate($tagRECT) With $tTextRect .left = $left + 10 .top = $top + 4 .right = $right - 10 .bottom = $bottom - 4 EndWith DllCall("user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $sText, "int", -1, "ptr", DllStructGetPtr($tTextRect), "uint", BitOR($DT_SINGLELINE, $DT_VCENTER, $DT_LEFT)) If $hOldFont Then _WinAPI_SelectObject($hDC, $hOldFont) Return 1 EndFunc ;==>WM_DRAWITEM_Handler Func _WM_CTLCOLOR($hWnd, $iMsg, $wParam, $lParam) Local $hDC = $wParam Local $hCtrl = $lParam ; If the control is the special green label -> return green background If $hCtrl = $g_hLabelGreen Then ; black text on a green background _WinAPI_SetTextColor($hDC, _ColorToCOLORREF(0x000000)) _WinAPI_SetBkColor($hDC, _ColorToCOLORREF(0x00FF00)) _WinAPI_SetBkMode($hDC, $OPAQUE) ; important, otherwise it remains transparent and you cannot see the background If $g_hBrushGreen Then Return $g_hBrushGreen EndIf ; --- Special case: Make "Sample Pic" label transparent --- If $hCtrl = $g_hLabelPic Then ; set transparent background _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; set text color (if necessary) - e.g., white _WinAPI_SetTextColor($hDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) ; return NULL_BRUSH (stock object), so Windows does NOT fill with your dark brush Local $hNull = _WinAPI_GetStockObject(5) ; 5 = NULL_BRUSH If $hNull Then Return $hNull ; Fallback if not available: Return $GUI_RUNDEFMSG EndIf ; --- Default behavior for all other statics / controls --- _WinAPI_SetTextColor($hDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) Local $hBrush = $g_hBrushEdit Local $iColor = $COLOR_EDIT_BG Switch $iMsg Case $WM_CTLCOLORBTN $hBrush = $g_hBrushButton $iColor = $COLOR_BUTTON_BG Case $WM_CTLCOLORSTATIC $hBrush = $g_hBrushBg $iColor = $COLOR_BG_DARK EndSwitch _WinAPI_SetBkColor($hDC, _ColorToCOLORREF($iColor)) _WinAPI_SetBkMode($hDC, $TRANSPARENT) Return $hBrush EndFunc ;==>_WM_CTLCOLOR Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo, $tBuffer, $tBuffer2, $iCtrl $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd($tNMHDR.hWndFrom) $iIDFrom = $tNMHDR.IDFrom $iCode = $tNMHDR.Code Switch $hWndFrom Case $g_hDate ;thanks to argumentum for the code :-) Switch $iCode Case $NM_SETFOCUS ; Disable the visual theme when the DateTime control receives focus _WinAPI_SetThemeAppProperties(0) Case $DTN_DROPDOWN ; Apply dark colors when the calendar dropdown appears _WinAPI_SetWindowTheme($iCtrl, "", "") Local $iCtrl = _GUICtrlDTP_GetMonthCal($hWndFrom) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TEXT, $COLOR_TEXT_LIGHT) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TITLEBK, $COLOR_BG_DARK) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TITLETEXT, $COLOR_TEXT_LIGHT) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_MONTHBK, $COLOR_BG_DARK) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TRAILINGTEXT, $COLOR_TEXT_LIGHT) Case $DTN_CLOSEUP ; Calendar will closed EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func _CleanupBrushes() ; Delete all brushes If $g_hBrushEdit Then _WinAPI_DeleteObject($g_hBrushEdit) If $g_hBrushButton Then _WinAPI_DeleteObject($g_hBrushButton) If $g_hBrushBg Then _WinAPI_DeleteObject($g_hBrushBg) If $g_hBrushGreen Then _WinAPI_DeleteObject($g_hBrushGreen) EndFunc ;==>_CleanupBrushes Func _EnableDarkScrollBars() ; Try to enable Dark Mode for all scrollbars (also for TreeView with checkboxes) For $i = 0 To $g_iControlCount - 1 Local $hCtrl = $g_aControls[$i][1] If Not $hCtrl Then ContinueLoop ; 1️ Normal attempt (works for most controls) Local $tScrollInfo = _GUIScrollBars_GetScrollInfoEx($hCtrl, 1) If IsDllStruct($tScrollInfo) Then _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) EndIf ; 2️ Extension: If the control has its own scrollbar child windows (e.g., TreeView with $TVS_CHECKBOXES) Local $hChild = _WinAPI_GetWindow($hCtrl, $GW_CHILD) While $hChild Local $sClass = _WinAPI_GetClassName($hChild) If StringCompare($sClass, "ScrollBar") = 0 Then ; Set DarkMode on the ScrollBar itself _WinAPI_SetWindowTheme($hChild, "DarkMode_Explorer", 0) _WinAPI_AllowDarkModeForWindow($hChild, True) EndIf $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT) WEnd Next EndFunc ;==>_EnableDarkScrollBars Func _WinProc($hWnd, $iMsg, $wParam, $lParam) ; Custom window procedure for tab control with Dark Mode Switch $iMsg Case $WM_ERASEBKGND Return 1 ; Prevent background erase to avoid flicker Case $WM_PAINT Local $tPaint = DllStructCreate($tagPAINTSTRUCT) Local $hDC = DllCall("user32.dll", "handle", "BeginPaint", "hwnd", $hWnd, "struct*", $tPaint) If @error Or Not $hDC[0] Then Return _WinAPI_CallWindowProc($g_hProc, $hWnd, $iMsg, $wParam, $lParam) $hDC = $hDC[0] ; Get client rectangle Local $tClient = _WinAPI_GetClientRect($hWnd) If Not IsDllStruct($tClient) Then _WinAPI_EndPaint($hWnd, $tPaint) Return 0 EndIf Local $iWidth = $tClient.Right Local $iHeight = $tClient.Bottom ; Create memory DC for double buffering Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight) Local $hOldBmp = _WinAPI_SelectObject($hMemDC, $hBitmap) ; Fill background Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) _WinAPI_FillRect($hMemDC, $tClient, $hBrush) _WinAPI_DeleteObject($hBrush) ; Get tab info Local $iTabCount = _SendMessage($hWnd, 0x1304, 0, 0) ; TCM_GETITEMCOUNT Local $iCurSel = _SendMessage($hWnd, 0x130B, 0, 0) ; TCM_GETCURSEL ; Setup font Local $hFont = _SendMessage($hWnd, $WM_GETFONT, 0, 0) If Not $hFont Then $hFont = _WinAPI_GetStockObject($DEFAULT_GUI_FONT) Local $hOldFont = _WinAPI_SelectObject($hMemDC, $hFont) _WinAPI_SetBkMode($hMemDC, $TRANSPARENT) _WinAPI_SetTextColor($hMemDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) ; Draw each tab Local $tRect, $tRect, $iLeft, $iTop, $iRight, $iBottom For $i = 0 To $iTabCount - 1 ; Get tab rectangle using TCM_GETITEMRECT $tRect = DllStructCreate($tagRECT) $aResult = DllCall("user32.dll", "lresult", "SendMessageW", _ "hwnd", $hWnd, _ "uint", 0x130A, _ ; TCM_GETITEMRECT "wparam", $i, _ "struct*", $tRect) If @error Or Not $aResult[0] Then ContinueLoop $iLeft = $tRect.Left $iTop = $tRect.Top $iRight = $tRect.Right $iBottom = $tRect.Bottom ; Skip if rectangle is invalid If $iLeft >= $iRight Or $iTop >= $iBottom Then ContinueLoop ; Get tab text Local $tItem = DllStructCreate("uint Mask;dword dwState;dword dwStateMask;ptr pszText;int cchTextMax;int iImage;lparam lParam") Local $tText = DllStructCreate("wchar Text[256]") With $tItem .Mask = 0x0001 ; TCIF_TEXT .pszText = DllStructGetPtr($tText) .cchTextMax = 256 EndWith DllCall("user32.dll", "lresult", "SendMessageW", _ "hwnd", $hWnd, _ "uint", 0x133C, _ ; TCM_GETITEMW "wparam", $i, _ "struct*", $tItem) Local $sText = DllStructGetData($tText, "Text") ; Draw tab background Local $bSelected = ($i = $iCurSel) Local $iTabColor = $bSelected ? $COLOR_BUTTON_BG : $COLOR_BG_DARK Local $hTabBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($iTabColor)) Local $tTabRect = DllStructCreate($tagRECT) With $tTabRect .Left = $iLeft .Top = $iTop .Right = $iRight .Bottom = $iBottom EndWith _WinAPI_FillRect($hMemDC, $tTabRect, $hTabBrush) _WinAPI_DeleteObject($hTabBrush) ;~ Local $hTabPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) ;~ Local $hOldTabPen = _WinAPI_SelectObject($hMemDC, $hTabPen) ;~ _WinAPI_MoveTo($hMemDC, $iLeft, $iBottom) ;~ _WinAPI_LineTo($hMemDC, $iRight, $iBottom) ;~ _WinAPI_SelectObject($hMemDC, $hOldTabPen) ;~ _WinAPI_DeleteObject($hTabPen) ; Draw selection indicator (top border for selected tab) If $bSelected Then Local $hPen = _WinAPI_CreatePen(0, 2, _ColorToCOLORREF(0x0078D4)) ; Blue accent Local $hOldPen = _WinAPI_SelectObject($hMemDC, $hPen) _WinAPI_MoveTo($hMemDC, $iLeft, $iTop) _WinAPI_LineTo($hMemDC, $iRight - 2, $iTop) _WinAPI_SelectObject($hMemDC, $hOldPen) _WinAPI_DeleteObject($hPen) EndIf ; Draw separator between tabs If $i < $iTabCount - 1 Then Local $hPenSep = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) Local $hOldPenSep = _WinAPI_SelectObject($hMemDC, $hPenSep) _WinAPI_MoveTo($hMemDC, $iRight - 1, $iTop + 4) _WinAPI_LineTo($hMemDC, $iRight - 1, $iBottom - 4) _WinAPI_SelectObject($hMemDC, $hOldPenSep) _WinAPI_DeleteObject($hPenSep) EndIf ; Draw text centered in tab Local $tTextRect = DllStructCreate($tagRECT) With $tTextRect .Left = $iLeft + 6 .Top = $iTop + 3 .Right = $iRight - 6 .Bottom = $iBottom - 3 EndWith DllCall("user32.dll", "int", "DrawTextW", _ "handle", $hMemDC, _ "wstr", $sText, _ "int", -1, _ "struct*", $tTextRect, _ "uint", BitOR($DT_CENTER, $DT_VCENTER, $DT_SINGLELINE)) Next ; Draw border around entire control Local $hBorderPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) Local $hOldBorderPen = _WinAPI_SelectObject($hMemDC, $hBorderPen) Local $hNullBrush = _WinAPI_GetStockObject(5) ; NULL_BRUSH Local $hOldBorderBrush = _WinAPI_SelectObject($hMemDC, $hNullBrush) DllCall("gdi32.dll", "bool", "Rectangle", _ "handle", $hMemDC, _ "int", 0, _ "int", 0, _ "int", $iWidth, _ "int", $iHeight) _WinAPI_SelectObject($hMemDC, $hOldBorderPen) _WinAPI_SelectObject($hMemDC, $hOldBorderBrush) _WinAPI_DeleteObject($hBorderPen) ; Copy to screen _WinAPI_BitBlt($hDC, 0, 0, $iWidth, $iHeight, $hMemDC, 0, 0, $SRCCOPY) ; Cleanup _WinAPI_SelectObject($hMemDC, $hOldFont) _WinAPI_SelectObject($hMemDC, $hOldBmp) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) _WinAPI_EndPaint($hWnd, $tPaint) Return 0 EndSwitch Return _WinAPI_CallWindowProc($g_hProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_WinProc Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") Local $ret = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hAfter, "wstr", $sClass, "wstr", $sTitle) If @error Or Not IsArray($ret) Then Return 0 Return $ret[0] EndFunc ;==>_WinAPI_FindWindowEx #Region DarkMode API Func _WinAPI_ShouldAppsUseDarkMode() Local $aResult = DllCall("UxTheme.dll", "bool", 132) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_ShouldAppsUseDarkMode Func _WinAPI_AllowDarkModeForWindow($hWND, $bAllow = True) Local $aResult = DllCall("UxTheme.dll", "bool", 133, "hwnd", $hWND, "bool", $bAllow) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_AllowDarkModeForWindow Func _WinAPI_FlushMenuThemes() Local $aResult = DllCall("UxTheme.dll", "none", 136) If @error Then Return SetError(1, 0, False) Return True EndFunc ;==>_WinAPI_FlushMenuThemes Func _WinAPI_RefreshImmersiveColorPolicyState() Local $aResult = DllCall("UxTheme.dll", "none", 104) If @error Then Return SetError(1, 0, False) Return True EndFunc ;==>_WinAPI_RefreshImmersiveColorPolicyState Func _WinAPI_IsDarkModeAllowedForWindow($hWND) Local $aResult = DllCall("UxTheme.dll", "bool", 137, "hwnd", $hWND) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_IsDarkModeAllowedForWindow Func _WinAPI_GetIsImmersiveColorUsingHighContrast($iIMMERSIVE_HC_CACHE_MODE) Local $aResult = DllCall("UxTheme.dll", "bool", 106, "long", $iIMMERSIVE_HC_CACHE_MODE) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_GetIsImmersiveColorUsingHighContrast Func _WinAPI_OpenNcThemeData($hWND, $tClassList) Local $aResult = DllCall("UxTheme.dll", "hwnd", 49, "hwnd", $hWND, "struct*", $tClassList) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc ;==>_WinAPI_OpenNcThemeData Func _WinAPI_ShouldSystemUseDarkMode() Local $aResult = DllCall("UxTheme.dll", "bool", 138) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_ShouldSystemUseDarkMode Func _WinAPI_IsDarkModeAllowedForApp() Local $aResult = DllCall("UxTheme.dll", "bool", 139) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_IsDarkModeAllowedForApp Func _WinAPI_AllowDarkModeForApp($bAllow = True) ;Windows 10 Build 17763 Return _WinAPI_SetPreferredAppMode($bAllow ? 1 : 0) ; 1 = AllowDark, 0 = Default EndFunc ;==>_WinAPI_AllowDarkModeForApp Func _WinAPI_SetPreferredAppMode($iPreferredAppMode) ;Windows 10 Build 18362+ Local $aResult = DllCall("UxTheme.dll", "long", 135, "long", $iPreferredAppMode) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc ;==>_WinAPI_SetPreferredAppMode #EndRegion DarkMode API Does anyone know how to switch the date picker to dark mode? Edited Friday at 08:29 PM by UEZ Update Parsix and WildByDesign 2 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
ahmet Posted Tuesday at 07:28 PM Posted Tuesday at 07:28 PM There is some discussion here. I am not sure how much moder menu raw is used there. What was left as I xan remeber was the white bottom line. I think them menu needs to be ownerdrawn. I do not if that is the case for all other common controls and dark mode.
UEZ Posted Thursday at 09:07 PM Author Posted Thursday at 09:07 PM (edited) Updated the code -> see 1st post. To do: date picker Edited Thursday at 09:08 PM by UEZ argumentum 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
WildByDesign Posted Thursday at 09:45 PM Posted Thursday at 09:45 PM (edited) @UEZ Excellent work! EDIT: I just spent around an hour studying the code. The more that I read, the more my jaw dropped to the floor. Very impressive. I may have to find an excuse to create an app that uses tabs now. I had always dreamed of dark mode tabs in AutoIt for quite a while now. 😃 I noticed one problem. I see that you've added code to paint over the white line. However, I still see the white line under the menubar. EDIT2: I changed the color of the painted line so that I could see where it was ending up and get a screenshot for you. EDIT3: I've been using the following to get the height of the menubar recently which works when DPI is used or not: ; get menubar height $aMenubar = _GUICtrlMenu_GetMenuBarInfo($g_hGUI) $iMenubarHeight = $aMenubar[3] - $aMenubar[1] ConsoleWrite("menubar height: " & $iMenubarHeight & @CRLF) I wonder if it would be possible to measure the height of the titlebar combined with the height of the menubar to determine the coordinates to paint over the white line. The menubar height measurement is accurate. However, I have never been able to find an accurate measurement yet for the titlebar though. Edited Thursday at 11:16 PM by WildByDesign Parsix 1
UEZ Posted Friday at 08:25 AM Author Posted Friday at 08:25 AM (edited) Can you please try this? expandcollapse popupFunc _OverpaintWhiteLine() Local $hDC = _WinAPI_GetWindowDC($g_hGUI) If Not $hDC Then Return Local $tWndRect = _WinAPI_GetWindowRect($g_hGUI) Local $iWndWidth = $tWndRect.right - $tWndRect.left ; 1. Caption height Local $iCaptionHeight = _WinAPI_GetSystemMetrics($SM_CYCAPTION) ; 2. Border height (top) Local $iBorderHeight = _WinAPI_GetSystemMetrics($SM_CYSIZEFRAME) If $iBorderHeight = 0 Then $iBorderHeight = _WinAPI_GetSystemMetrics($SM_CYFIXEDFRAME) ; 3. Determine menu height dynamically Local $iMenuHeight = _WinAPI_GetSystemMetrics($SM_CYMENU) ; standard menu height ; Alternative: get menu height via GetMenuBarInfo Local $tMenuBarInfo = DllStructCreate("dword cbSize;long left;long top;long right;long bottom;handle hwndMenu;handle hwndItem;bool fBarFocused;bool fFocused") DllStructSetData($tMenuBarInfo, "cbSize", DllStructGetSize($tMenuBarInfo)) Local $aResult = DllCall("user32.dll", "bool", "GetMenuBarInfo", "hwnd", $g_hGUI, "long", 0xFFFFFFFD, "long", 0, "ptr", DllStructGetPtr($tMenuBarInfo)) If IsArray($aResult) And $aResult[0] Then ; Calculate the actual menu height from the coordinates Local $iMenuTop = $tMenuBarInfo.top Local $iMenuBottom = $tMenuBarInfo.bottom Local $tWndPos = _WinAPI_GetWindowRect($g_hGUI) Local $iWndTop = $tWndPos.top ; Convert to window coordinates $iMenuHeight = ($iMenuBottom - $iMenuTop) EndIf ; The white line is directly below the menu Local $iWhiteLineY = $iCaptionHeight + $iBorderHeight + $iMenuHeight - _WinAPI_GetSystemMetrics($SM_CYFIXEDFRAME) * 2 ConsoleWrite("Caption: " & $iCaptionHeight & ", Border: " & $iBorderHeight & ", Menu: " & $iMenuHeight & " -> White Line at Y=" & $iWhiteLineY & @CRLF) ; Overpaint the white line (1–2 pixels) Local $tRect = DllStructCreate($tagRECT) With $tRect .left = 0 .top = $iWhiteLineY .right = $iWndWidth .bottom = $iWhiteLineY + 2 ; 2 pixels high EndWith ;~ Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF(0xFF0000)) _WinAPI_FillRect($hDC, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) _WinAPI_ReleaseDC($g_hGUI, $hDC) EndFunc ;==>_OverpaintWhiteLine I marked the line in red to see where it is painted. Is it now calculated properly? Edited Friday at 11:45 AM by UEZ small update WildByDesign 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
WildByDesign Posted Friday at 09:47 AM Posted Friday at 09:47 AM (edited) 1 hour ago, UEZ said: I marked the line in red to see where it is painted. Is it now calculated properly? This works properly, yes. Thank you. It also worked once I applied DPI scaling of 125%. But once I tried 150% and higher the line did not line up anymore. But I understand that it is not supporting DPI yet. EDIT: By the way, I wanted to mention that not only is your coding incredible, but I really wanted to point out the fact that your code comments are also very easy to understand and therefore helpful for anyone reading your code. I appreciate the extra effort that you put into code comments. Edited Friday at 09:51 AM by WildByDesign Shark007 and UEZ 1 1
WildByDesign Posted Friday at 01:46 PM Posted Friday at 01:46 PM On 10/14/2025 at 2:51 PM, UEZ said: Does anyone know how to switch the date picker to dark mode? Nobody in AutoIt has had success with this. I was looking around at some open source projects that have great dark mode support (Notepad++, Explorer++, System Informer, etc.) to see if there was any source code examples but unfortunately none of these projects utilize SysDateTimePick32 from what I can tell.
argumentum Posted Friday at 01:58 PM Posted Friday at 01:58 PM Any of this code ( https://www.autoitscript.com/forum/topic/191058-datetime-pick-coloring ) useful ? WildByDesign and UEZ 1 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
UEZ Posted Friday at 08:31 PM Author Posted Friday at 08:31 PM 6 hours ago, argumentum said: Any of this code ( https://www.autoitscript.com/forum/topic/191058-datetime-pick-coloring ) useful ? Yes, thanks 👍 Updated the code for the window when date pick icon was clicked. Still searching for a way to change the date control itself. argumentum 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
WildByDesign Posted yesterday at 12:16 AM Posted yesterday at 12:16 AM By the way, Windows 11 stable channel build 25H2 (and probably 24H2), build 26200.6899, just added brand new visual styles in aero.msstyles version 10.0.26100.6725 that contains all of the new dark mode classes. DarkMode_CopyEngine::Progress DarkMode_CopyEngine_Indeterminate::Progress DarkMode_DarkTheme::Button DarkMode_DarkTheme::Combobox DarkMode_DarkTheme::Edit DarkMode_DarkTheme::Header DarkMode_DarkTheme::Link DarkMode_DarkTheme::Listbox DarkMode_DarkTheme::ListView DarkMode_DarkTheme::Progress DarkMode_DarkTheme::Rebar DarkMode_DarkTheme::ScrollBar DarkMode_DarkTheme::Spin DarkMode_DarkTheme::Static DarkMode_DarkTheme::Status DarkMode_DarkTheme::Tab DarkMode_DarkTheme::TaskDialog DarkMode_DarkTheme::Toolbar DarkMode_DarkTheme::Tooltip DarkMode_DarkTheme::TreeView DarkMode_DarkTheme_Indeterminate::Progress Keep in mind, the DarkMode_DarkTheme classes are completely new and different from the DarkMode_Explorer classes that we are used to using. argumentum 1
argumentum Posted yesterday at 12:18 AM Posted yesterday at 12:18 AM 1 minute ago, WildByDesign said: By the way,... so, you'll be updating the current "mod" zip we all use with these new values ? 😅 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
WildByDesign Posted 15 hours ago Posted 15 hours ago (edited) On 10/14/2025 at 2:51 PM, UEZ said: Case "msctls_progress32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) This no longer works on the latest stable channel builds of Windows 11. In particular, builds 24H2 (26100.6899) and 25H2 (26200.6899), it fails to theme the progress control at all. (I just get an empty white box) On these most recent stable channel builds of Windows 11, it now has to be: Case "msctls_progress32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_CopyEngine", 0) With your example for SampleControls and also the DarkMode UDF, we are going to have to start comparing the builds with macro @OSBuild to determine which theme class to use. These newer DarkMode_CopyEngine* and DarkMode_DarkTheme* theme classes seem to be improved significantly over the former DarkMode_Explorer* classes. A lot of visual issues are fixed now as well. So for any users who are on Windows 11 with the latest windows updates, using DarkMode_DarkTheme* is by far the better option over DarkMode_Explorer* classes. MS even added nice dark theme for statusbar as well in DarkMode_DarkTheme* class. ListViews are improved too. I'm not sure if we should update the older DarkMode UDF or start a new one. In my opinion, of the older DarkMode UDF versions, the GUIDarkMode_v0.02mod.au3 from the fabulous @argumentum is the most functional and best option to use as a base. Edited 15 hours ago by WildByDesign
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