-
Posts
7,448 -
Joined
-
Last visited
-
Days Won
94
UEZ last won the day on February 27
UEZ had the most liked content!
About UEZ

- Birthday 12/03/2007
Profile Information
-
Member Title
Never say never
-
Location
Germany
-
Interests
Computer, watching movies, football (soccer), being lazy :-)
UEZ's Achievements
-
Hmmm, I have no problems with the label sizes - thus I cannot reproduce it. Another white line seems to occur at 200% above the menus At 200% Red line is just for testing purposes.
-
WildByDesign reacted to a post in a topic:
SampleControls.au3 in Dark Mode
-
I cannot see in the screenshots any misplacement except the screenshot from @argumentum
-
Back in my office with 3 monitors: checked the _OverpaintWhiteLine() and yes, didn't work. Changed it to the code above and it seems to work now - please test!
-
UEZ reacted to a post in a topic:
SampleControls.au3 in Dark Mode
-
Hmm. when I start it at 175% or from 100% -> 175% . I had also the problems with the measurement of the menus but for me it works as you can see in the screenshot.
-
Can you please test if this is DPI aware? ; Coded by UEZ build 2026-03-13 beta ; Should be DPI aware #include <Array.au3> #include <APIConstants.au3> #include <AVIConstants.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <GuiDateTimePicker.au3> #include <GuiImageList.au3> #include <GuiMenu.au3> #include <GuiMonthCal.au3> #include <GuiScrollBars.au3> #include <GuiStatusBar.au3> #include <GuiTab.au3> #include <GuiTreeView.au3> #include <TreeViewConstants.au3> #include <ListViewConstants.au3> #include <WinAPIConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIProc.au3> #include <WinAPIRes.au3> #include <WinAPIShellEx.au3> #include <WinAPISys.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> #Region DPI Constants ;https://learn.microsoft.com/en-us/windows/win32/api/windef/ne-windef-dpi_awareness Global Enum $DPI_AWARENESS_INVALID = -1, $DPI_AWARENESS_UNAWARE = 0, $DPI_AWARENESS_SYSTEM_AWARE = 1, $DPI_AWARENESS_PER_MONITOR_AWARE = 2 ;https://learn.microsoft.com/en-us/windows/win32/hidpi/dpi-awareness-context Global Const $DPI_AWARENESS_CONTEXT_UNAWARE = $DPI_AWARENESS_UNAWARE - 1 Global Const $DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = $DPI_AWARENESS_UNAWARE - 2 Global Const $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = $DPI_AWARENESS_UNAWARE - 3 Global Const $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = $DPI_AWARENESS_UNAWARE - 4 Global Const $DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = $DPI_AWARENESS_UNAWARE - 5 ;enum _MONITOR_DPI_TYPE Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI ;Windows Message Codes Global Const $WM_DPICHANGED = 0x02E0, $WM_DPICHANGED_BEFOREPARENT = 0x02E2, $WM_DPICHANGED_AFTERPARENT = 0x02E3, $WM_GETDPISCALEDSIZE = 0x02E4 ;DpiChangeBehavior Global Const $DDC_DEFAULT = 0 Global Const $DDC_DISABLE_ALL = 1 Global Const $DDC_DISABLE_RESIZE = 2 Global Const $DDC_DISABLE_CONTROL_RELAYOUT = 4 Global Const $DCDC_DEFAULT = 0 Global Const $DCDC_DISABLE_FONT_UPDATE = 1 Global Const $DCDC_DISABLE_RELAYOUT = 2 #EndRegion DPI Constants Enum $IHCM_USE_CACHED_VALUE, $IHCM_REFRESH Enum $APPMODE_DEFAULT = 0, $APPMODE_ALLOWDARK, $APPMODE_FORCEDARK, $APPMODE_FORCELIGHT, $APPMODE_MAX Const $PRF_CLIENT = 0x04 Const $ODS_HOTLIGHT = 0x0040 Const $TCM_SETBKCOLOR = 0x132D ; Dark Mode Colors (RGB) - used throughout WM_CTLCOLOR, custom draw, and GDI painting Global Const $COLOR_BG_DARK = 0x202020 ; main window background Global Const $COLOR_TEXT_LIGHT = 0xF0F0F0 ; default text color Global Const $COLOR_CONTROL_BG = 0x2B2B2B ; generic control background Global Const $COLOR_EDIT_BG = 0x1E1E1E ; edit/list background Global Const $COLOR_BUTTON_BG = 0x333333 ; button / selected tab background Global Const $COLOR_BORDER = 0x3F3F3F ; subtle border (edit, listbox, tab) Global Const $COLOR_BORDER2 = 0xA0A0A0 ; brighter border (checkbox outline) Global Const $COLOR_HOTTRACK_MENU = 0x3A3A3A ; menu item hover highlight Global Const $COLOR_BORDER_LIGHT = 0xD8D8D8 ; bright border on hover (date control) Global Const $COLOR_MENU_SELECT = 0x505050 ; color selecting menu ; Global variables for subclassing (MUST be declared before _Example()!) Global $g_hGUI = 0, $g_hTab, $g_ListView Global $g_aControls[150][3] = [[0, 0, 0]] ; [ControlID, hWnd, OldWndProc] Global $g_aCtrlDPI[150][7] = [[0, 0, 0, 0, 0, 0, ""]] ; [CtrlID, xpos, ypos, w, h, fontsize, fontname] Global $g_iControlCount = 0, $g_iCtrlCountDPI = 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_idInput, $g_idUpDown, $g_hUpDown Global $g_hMenu = 0, $g_hMenu1, $g_hMenu2, $g_hMenuFont = 0 Global $g_idDate = 0, $g_hDate = 0 ; Global variable for tab subclassing Global $g_hTab_CB, $g_pTab_CB, $g_hProc ; Global variable for SysDateTimePick32 subclassing Global $g_hDateProc_CB, $g_pDateProc_CB, $g_hDateOldProc ; 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_aMenuText = [] ; top-level menu texts (populated by _MakeMenuOwnerDraw) Global $arMenuItems[1][8] ; owner-draw menu item data $arMenuItems[0][0] = 0 Global $arSideItems[1][10] ; side/context menu item data $arSideItems[0][0] = 0 Const $ODT_MENU = 1 Const $ODS_SELECTED = 0x0001 Const $ODS_DISABLED = 0x0004 Global Enum $idAbout = 5000 Global $g_hMenu_Sys, $g_idAboutMenu, $g_AboutDummy, $g_hStatusbar Global $g_bHover = False _GDIPlus_Startup() Global $AWARENESS ; Select DPI awareness level based on OS build: ; Win8.1-Win10 14393: PER_MONITOR_AWARE via Shcore.dll ; Win10 14393+: PER_MONITOR_AWARE_V2 (full non-client DPI scaling) ; older: SYSTEM_AWARE fallback Switch @OSBuild Case 9200 To 13999 $AWARENESS = $DPI_AWARENESS_PER_MONITOR_AWARE Case @OSBuild > 13999 $AWARENESS = $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 Case Else $AWARENESS = $DPI_AWARENESS_SYSTEM_AWARE EndSwitch ; Set DPI awareness and retrieve current DPI (96 = 100%) Global $g_iDPI = _WinAPI_SetDPIAwareness($AWARENESS), $aPos Global $g_fScale = $g_iDPI / 96.0, $g_aStatusbarParts[4] = [75, 150, 300, 400], $g_hCtrlFont = 0, $g_aCustomFonts[0] _Example() _GDIPlus_Shutdown() 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)) Local $sAutoitExample = StringRegExpReplace(@AutoItExe, "\\[^\\]+$", "") & "\Examples\GUI" #Region GUI $g_hGUI = GUICreate("Sample GUI with Dark Mode", 400 * $g_fScale, 424 * $g_fScale) GUISetIcon(@SystemDir & "\mspaint.exe", 0) GUISetBkColor($COLOR_BG_DARK, $g_hGUI) $g_hMenu_Sys = _GUICtrlMenu_GetSystemMenu($g_hGUI) _GUICtrlMenu_AppendMenu($g_hMenu_Sys, $MF_SEPARATOR, 0, 0) _GUICtrlMenu_AppendMenu($g_hMenu_Sys, $MF_STRING, $idAbout, "About") ; 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_MEASUREITEM, "_WM_MEASUREITEM") GUIRegisterMsg($WM_DRAWITEM, "_WM_DRAWITEM") GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUIRegisterMsg($WM_ACTIVATE, "_WM_ACTIVATE") GUIRegisterMsg($WM_WINDOWPOSCHANGED, "_WM_WINDOWPOSCHANGED") GUIRegisterMsg($WM_MENUCOMMAND, "_WM_MENUCOMMAND") GUIRegisterMsg($WM_SYSCOMMAND, "_WM_SYSCOMMAND") GUIRegisterMsg($WM_DPICHANGED, "_WM_DPICHANGED") #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) $g_idAboutMenu = GUICtrlCreateMenuItem("About", $idMenu1) $g_hMenu1 = GUICtrlGetHandle($idMenu1) $g_hMenu2 = GUICtrlGetHandle($idMenu2) ; Owner-draw Top-Level Menu creation _CreateMenuFont($g_fScale) _MakeMenuOwnerDraw($g_hGUI) _EnableMenuHotTrack($g_hMenu) #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, 2, 169, 68) GUICtrlSetImage($idPic, $sAutoitExample & "\logo4.gif") GUICtrlSetTip(-1, "#Region PIC") _AddControlForDPI($idPic, 0, 2, 169, 68, 0, "") $g_idLabelPic = GUICtrlCreateLabel("Sample Pic", 75, 1, 63, 15) $g_hLabelPic = GUICtrlGetHandle($g_idLabelPic) _AddControlForDPI($g_idLabelPic, 75, 1, 63, 15) #EndRegion PIC #Region AVI Local $idAvi = GUICtrlCreateAvi($sAutoitExample & "\SampleAVI.avi", 0, 184, 12, 32, 32, $ACS_AUTOPLAY) GUICtrlSetTip(-1, "#Region AVI") _AddControlForDPI($idAvi, 184, 12, 32, 32, 0, "") Local $idLabelAvi = GUICtrlCreateLabel("Sample avi", 175, 50) $aPos = ControlGetPos($g_hGUI, "", $idLabelAvi) _AddControlForDPI($idLabelAvi, 175, 50, $aPos[2], $aPos[3]) #EndRegion AVI #Region TAB Local $idTab = GUICtrlCreateTab(240, 2, 150, 70), $g_hTab = GUICtrlGetHandle($idTab) _AddControlForSubclass($idTab) _AddControlForDPI($idTab, 240, 2, 150, 70) GUICtrlCreateTabItem("One") GUICtrlSetTip(-1, "#Region TAB1") Local $idLabelTab = GUICtrlCreateLabel("Sample Tab with TabItems", 250, 40) $aPos = ControlGetPos($g_hGUI, "", $idLabelTab) _AddControlForDPI($idLabelTab, 250, 40, $aPos[2], $aPos[3]) GUICtrlCreateTabItem("Two") GUICtrlSetTip(-1, "#Region TAB2") Local $idCheckBoxTab2 = GUICtrlCreateCheckbox("Checkbox", 250, 30, 120, 20) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) _AddControlForDPI($idCheckBoxTab2, 250, 30, 120, 20) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idCheckBoxTab2), "DarkMode_DarkTheme", 0) GUICtrlCreateTabItem("Three") GUICtrlSetTip(-1, "#Region TAB3") GUICtrlCreateTabItem("") #EndRegion TAB #Region COMBO Local $idCombo = GUICtrlCreateCombo("", 250, 80, 120, 100, $CBS_DROPDOWNLIST) GUICtrlSetData($idCombo, "Sample Combo|Item 2|Item 3", "Sample Combo") _AddControlForSubclass($idCombo) GUICtrlSetTip(-1, "#Region COMBO") _AddControlForDPI($idCombo, 250, 80, 120, 100) #EndRegion COMBO #Region PROGRESS Local $idProgress = GUICtrlCreateProgress(60, 80, 150, 20) ;_AddControlForSubclass($idProgress) GUICtrlSetTip(-1, "#Region PROGRESS") GUICtrlSetData(-1, 60) _AddControlForDPI($idProgress, 60, 80, 150, 20) Local $idLabelProgress = GUICtrlCreateLabel("Progress:", 5, 82) $aPos = ControlGetPos($g_hGUI, "", $idLabelProgress) _AddControlForDPI($idLabelProgress, 5, 82, $aPos[2], $aPos[3]) #EndRegion PROGRESS #Region EDIT Local $idEdit = GUICtrlCreateEdit(@CRLF & " Sample Edit Control", 10, 110, 150, 70), $hEditCtrl = GUICtrlGetHandle($idEdit) _WinAPI_SetWindowLong($hEditCtrl, $GWL_EXSTYLE, BitAND(_WinAPI_GetWindowLong($hEditCtrl, $GWL_EXSTYLE), BitNOT($WS_EX_CLIENTEDGE))) _AddControlForSubclass($idEdit) GUICtrlSetTip(-1, "#Region EDIT") _AddControlForDPI($idEdit, 10, 110, 150, 70) #EndRegion EDIT #Region LIST Local $idList = GUICtrlCreateList("", 5, 190, 100, 90), $hList = GUICtrlGetHandle($idList) _WinAPI_SetWindowLong($hList, $GWL_EXSTYLE, BitAND(_WinAPI_GetWindowLong($hList, $GWL_EXSTYLE), BitNOT($WS_EX_CLIENTEDGE))) _AddControlForSubclass($idList) GUICtrlSetTip(-1, "#Region LIST") GUICtrlSetData(-1, "A.Sample|B.List|C.Control|D.Here", "B.List") _AddControlForDPI($idList, 5, 190, 100, 90) #EndRegion LIST #Region ICON Local $idIcon = GUICtrlCreateIcon("explorer.exe", 0, 175, 120) GUICtrlSetTip(-1, "#Region ICON") _AddControlForDPI($idIcon, 175, 120, 32, 32, 0, "") Local $idLabelIcon = GUICtrlCreateLabel("Icon", 180, 160, 50, 20) _AddControlForDPI($idLabelIcon, 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) _AddControlForDPI($idListView, 110, 190, 110, 80) #EndRegion LIST VIEW #Region GROUP WITH RADIO BUTTONS Local $idGroup = GUICtrlCreateGroup("Sample Group", 230, 120) GUICtrlSetColor($idGroup, $COLOR_TEXT_LIGHT) $aPos = ControlGetPos($g_hGUI, "", $idGroup) _AddControlForDPI($idGroup, 230, 120, $aPos[2], $aPos[3]) Local $idRadio1 = GUICtrlCreateRadio("Radio One", 250, 140, 80) GUICtrlSetTip($idRadio1, "#Region RADIO1") GUICtrlSetState($idRadio1, $GUI_CHECKED) $aPos = ControlGetPos($g_hGUI, "", $idRadio1) _AddControlForDPI($idRadio1, 250, 140, 80, $aPos[3]) Local $idRadio2 = GUICtrlCreateRadio("Radio Two", 250, 165, 80) GUICtrlSetTip($idRadio2, "#Region RADIO2") $aPos = ControlGetPos($g_hGUI, "", $idRadio2) _AddControlForDPI($idRadio2, 250, 165, 80, $aPos[3]) GUICtrlCreateGroup("", -99, -99, 1, 1) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idRadio1), "DarkMode_DarkTheme", 0) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idRadio2), "DarkMode_DarkTheme", 0) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idGroup), "DarkMode_DarkTheme", 0) #EndRegion GROUP WITH RADIO BUTTONS #Region UPDOWN Local $idLabelUpDown = GUICtrlCreateLabel("UpDown", 350, 115) GUICtrlSetColor(-1, $COLOR_TEXT_LIGHT) $aPos = ControlGetPos($g_hGUI, "", $idLabelUpDown) _AddControlForDPI($idLabelUpDown, 350, 115, $aPos[2], $aPos[3]) $g_idInput = GUICtrlCreateInput("42", 350, 130, 40, 20) _AddControlForSubclass($g_idInput) _AddControlForDPI($g_idInput, 350, 130, 40, 20) $g_idUpDown = GUICtrlCreateUpdown(-1) _AddControlForSubclass($g_idUpDown) $aPos = ControlGetPos($g_hGUI, "", $g_idUpDown) _AddControlForDPI($g_idUpDown, $aPos[0], $aPos[1], $aPos[2], $aPos[3]) $g_hUpDown = GUICtrlGetHandle($g_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 _AddControlForDPI($g_idLabelGreen, 350, 165, 40, 40) #Region SLIDER Local $idLabelSlider = GUICtrlCreateLabel("Slider:", 235, 215) $aPos = ControlGetPos($g_hGUI, "", $idLabelSlider) _AddControlForDPI($idLabelSlider, 235, 215, $aPos[2], $aPos[3]) Local $idSlider = GUICtrlCreateSlider(270, 210, 120, 30) _AddControlForSubclass($idSlider) GUICtrlSetTip(-1, "#Region SLIDER") GUICtrlSetData(-1, 30) _AddControlForDPI($idSlider, 270, 210, 120, 30) #EndRegion SLIDER #Region INPUT Local $idInput2 = GUICtrlCreateInput("Sample Input Box", 235, 255, 130, 20) _AddControlForSubclass($idInput2) GUICtrlSetTip(-1, "#Region INPUT") _AddControlForDPI($idInput2, 235, 255, 130, 20) #EndRegion INPUT #Region DATE $g_idDate = GUICtrlCreateDate("", 5, 280, 200, 20) $g_hDate = GUICtrlGetHandle($g_idDate) _AddControlForSubclass($g_idDate) GUICtrlSetTip(-1, "#Region DATE") _AddControlForDPI($g_idDate, 5, 280, 200, 20) Local $idLabelDate = GUICtrlCreateLabel("(Date control expands into a calendar)", 10, 305, 200, 20) _AddControlForDPI($idLabelDate, 10, 305, 200, 20) #EndRegion DATE #Region BUTTON Local $idButton = GUICtrlCreateButton("Sample Button", 10, 330, 100, 30) _AddControlForSubclass($idButton) GUICtrlSetTip(-1, "#Region BUTTON") _AddControlForDPI($idButton, 10, 330, 100, 30) #EndRegion BUTTON #Region CHECKBOX Local $idCheckBox = GUICtrlCreateCheckbox("Checkbox", 130, 335, 80, 20) GUICtrlSetTip(-1, "#Region CHECKBOX") GUICtrlSetState(-1, $GUI_CHECKED) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idCheckBox), "DarkMode_DarkTheme", 0) _AddControlForDPI($idCheckBox, 130, 335, 80, 20) #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") _AddControlForDPI($idTreeView1, 210, 290, 80, 80) 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) _AddControlForDPI($idTreeView2, 295, 290, 103, 80) 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) _SetDarkTreeViewCheckboxes(GUICtrlGetHandle($idTreeView2), 16, 16) #EndRegion TREEVIEW TWO #Region Statusbar $g_hStatusbar = _GUICtrlStatusBar_Create($g_hGUI) _AddControlHandleForSubclass($g_hStatusbar) _GUICtrlStatusBar_SetParts($g_hStatusbar, $g_aStatusbarParts) _GUICtrlStatusBar_SetText($g_hStatusbar, "Part 0", 0) _GUICtrlStatusBar_SetText($g_hStatusbar, "Part 1", 1) _GUICtrlStatusBar_SetText($g_hStatusbar, "Part 2", 2) _GUICtrlStatusBar_SetText($g_hStatusbar, "Part 3", 3) $aPos = ControlGetPos($g_hGUI, "", _WinAPI_GetDlgCtrlID($g_hStatusbar)) _AddControlForDPI(_WinAPI_GetDlgCtrlID($g_hStatusbar), $aPos[0], $aPos[1], $aPos[2], $aPos[3]) #EndRegion Statusbar ; 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) ; Register a custom window procedure for the date control for owner-drawing $g_hDateProc_CB = DllCallbackRegister("_DateProc", "ptr", "hwnd;uint;wparam;lparam") $g_pDateProc_CB = DllCallbackGetPtr($g_hDateProc_CB) $g_hDateOldProc = _WinAPI_SetWindowLong($g_hDate, $GWL_WNDPROC, $g_pDateProc_CB) $g_AboutDummy = GUICtrlCreateDummy() _ApplyDPIScaling($g_fScale) ; Applying dark mode to Tooltips - thanks to WildByDesign ; Applying dark mode to Tooltips - thanks to WildByDesign Local $aData = _WinAPI_EnumProcessWindows(0, False) For $i = 1 To $aData[0][0] If $aData[$i][1] = "tooltips_class32" Then _WinAPI_SetWindowTheme($aData[$i][0], "DarkMode_Explorer", "ToolTip") Next GUISetState(@SW_SHOW) _OverpaintWhiteLine() While 1 Switch GUIGetMsg() Case $GUI_EVENT_RESTORE ;~ _WinAPI_RedrawWindow($g_hGUI, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) _WinAPI_LockWindowUpdate($g_hGUI) _ApplyDPIScaling($g_fScale) _OverpaintWhiteLine() _WinAPI_LockWindowUpdate(0) Case $GUI_EVENT_CLOSE _CleanupSubclassing() _CleanupBrushes() ExitLoop Case $g_AboutDummy MsgBox($MB_SYSTEMMODAL, "About", "Example coded by UEZ :-)", 10, $g_hGUI) EndSwitch WEnd ; Restore the original window procedure for the tab control _WinAPI_SetWindowLong($g_hTab, $GWL_WNDPROC, $g_hProc) DllCallbackFree($g_hTab_CB) _WinAPI_SetWindowLong($g_hDate, $GWL_WNDPROC, $g_hDateOldProc) DllCallbackFree($g_hDateProc_CB) GUIDelete() EndFunc ;==>_Example Func _ApplyDPIScaling($fNewScale) ; Create new control font BEFORE applying - old font deleted AFTER all controls receive the new one. ; This avoids a brief moment where controls hold a deleted font handle (causes tiny/invisible text). ; _WinAPI_CreateFont with negative height = character height (matches GUICtrlSetFont point size behavior). Local $hOldFont = $g_hCtrlFont $g_hCtrlFont = _WinAPI_CreateFont(-Round(11.3 * $fNewScale), 0, 0, 0, $FW_NORMAL, False, False, False, _ $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, "Arial") ; Cleanup previous custom fonts from last DPI pass For $j = 0 To UBound($g_aCustomFonts) - 1 If $g_aCustomFonts[$j] Then _WinAPI_DeleteObject($g_aCustomFonts[$j]) Next ReDim $g_aCustomFonts[0] _WinAPI_LockWindowUpdate($g_hGUI) ; suppress repaints during bulk repositioning Local $i, $hCtrl For $i = 0 To $g_iCtrlCountDPI - 1 ; Reposition using logical coordinates - GUICtrlSetPos handles DPI translation internally GUICtrlSetPos($g_aCtrlDPI[$i][0], $g_aCtrlDPI[$i][1] * $fNewScale, $g_aCtrlDPI[$i][2] * $fNewScale, _ $g_aCtrlDPI[$i][3] * $fNewScale, $g_aCtrlDPI[$i][4] * $fNewScale) ; Apply font via WM_SETFONT - bypasses AutoIt's cached DC which would ignore DPI changes If $g_aCtrlDPI[$i][5] > 0 Then $hCtrl = GUICtrlGetHandle($g_aCtrlDPI[$i][0]) If $hCtrl Then Local $hFont If $g_aCtrlDPI[$i][5] = 8.5 And ($g_aCtrlDPI[$i][6] = "" Or $g_aCtrlDPI[$i][6] = "Arial") Then ; standard font — use shared handle $hFont = $g_hCtrlFont Else ; custom size/face — create dedicated font scaled to current DPI Local $iH = -Round(_WinAPI_MulDiv($g_aCtrlDPI[$i][5], Round($fNewScale * 96), 72)) Local $sName = ($g_aCtrlDPI[$i][6] <> "" ? $g_aCtrlDPI[$i][6] : "Arial") $hFont = _WinAPI_CreateFont($iH, 0, 0, 0, $FW_NORMAL, False, False, False, _ $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, $sName) ; track for cleanup on next DPI change ReDim $g_aCustomFonts[UBound($g_aCustomFonts) + 1] $g_aCustomFonts[UBound($g_aCustomFonts) - 1] = $hFont EndIf _SendMessage($hCtrl, $WM_SETFONT, $hFont, True) EndIf EndIf Next ; UpDown buddy positioning is controlled by Windows — override manually after scaling If $g_idInput And $g_idUpDown Then Local $tPos = ControlGetPos($g_hGUI, "", $g_idInput) If IsArray($tPos) Then ; Place UpDown directly to the right of the Input, same height Local $iUpDownW = _WinAPI_GetSystemMetricsForDpi($SM_CXVSCROLL, Round($g_fScale * 96)) _WinAPI_MoveWindow($g_hUpDown, $tPos[0] + $tPos[2], $tPos[1], $iUpDownW, $tPos[3], True) EndIf EndIf _WinAPI_LockWindowUpdate(0) _WinAPI_RedrawWindow($g_hGUI, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) ; Safe to delete old font now - all controls already hold the new handle If $hOldFont Then _WinAPI_DeleteObject($hOldFont) EndFunc ;==>_ApplyDPIScaling Func _CreateMenuFont($fScale = 1.0, $sFontName = "Arial") ; Creates the owner-draw menu font at the correct pixel size for the current DPI. ; Uses MulDiv(8.5pt, DPI, 72) for accurate point-to-pixel conversion. ; Called once at startup; DPI changes recreate the font inline in _WM_DPICHANGED. If $g_hMenuFont Then _WinAPI_DeleteObject($g_hMenuFont) Local $iHeight = -Round(_WinAPI_MulDiv(8.5, $g_iDPI, 72)) $g_hMenuFont = _WinAPI_CreateFont($iHeight, 0, 0, 0, $FW_NORMAL, False, False, False, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, $sFontName) EndFunc ;==>_CreateMenuFont Func _GDIPlus_DrawRoundRect($hGfx, $iX, $iY, $iW, $iH, $iDiameter, $iBrushARGB, $iPenARGB, $fPenWidth = 1.0) Local Const $hPath = _GDIPlus_PathCreate() ; Top-left arc _GDIPlus_PathAddArc($hPath, $iX, $iY, $iDiameter, $iDiameter, 180, 90) ; Top-right arc _GDIPlus_PathAddArc($hPath, $iX + $iW - $iDiameter, $iY, $iDiameter, $iDiameter, 270, 90) ; Bottom-right arc _GDIPlus_PathAddArc($hPath, $iX + $iW - $iDiameter, $iY + $iH - $iDiameter, $iDiameter, $iDiameter, 0, 90) ; Bottom-left arc _GDIPlus_PathAddArc($hPath, $iX, $iY + $iH - $iDiameter, $iDiameter, $iDiameter, 90, 90) _GDIPlus_PathCloseFigure($hPath) If $iBrushARGB <> 0 Then Local Const $hBrush = _GDIPlus_BrushCreateSolid($iBrushARGB) _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush) _GDIPlus_BrushDispose($hBrush) EndIf If $iPenARGB <> 0 Then Local Const $hPen = _GDIPlus_PenCreate($iPenARGB, $fPenWidth) _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen) _GDIPlus_PenDispose($hPen) EndIf _GDIPlus_PathDispose($hPath) EndFunc ;==>_GDIPlus_DrawRoundRect Func _SetDarkTreeViewCheckboxesGDIp($hTreeView, $iW = 16, $iH = 16) Local $hImageList = _GUIImageList_Create($iW, $iH, 5, 3) Local $hBmp = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hBmp) _GDIPlus_GraphicsSetSmoothingMode($hGfx, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ; --- Index 0: Unchecked --- _GDIPlus_GraphicsClear($hGfx, 0xFF000000 + $COLOR_EDIT_BG) _GDIPlus_DrawRoundRect($hGfx, 2 / 16 * $iW, 2 / 16 * $iH, 12 / 16 * $iW, 12 / 16 * $iH, 3, 0, 0xFF000000 + $COLOR_BORDER2, 1.5) Local $hBmp_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp, 0) _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) ; --- Index 1: Checked --- _GDIPlus_GraphicsClear($hGfx, 0xFF000000 + $COLOR_EDIT_BG) _GDIPlus_DrawRoundRect($hGfx, 2 / 16 * $iW, 2 / 16 * $iH, 12 / 16 * $iW, 12 / 16 * $iH, 3, 0xFF60CDFF, 0xFF60CDFF, 1.0) Local $hCheckPen = _GDIPlus_PenCreate(0xFF0F2028, 1.5) _GDIPlus_GraphicsDrawLine($hGfx, 5 / 16 * $iW, 8 / 16 * $iH, 7 / 16 * $iW, 10 / 16 * $iH, $hCheckPen) _GDIPlus_GraphicsDrawLine($hGfx, 7 / 16 * $iW, 10 / 16 * $iH, 11 / 16 * $iW, 6 / 16 * $iH, $hCheckPen) $hBmp_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp, 0) _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) ; --- Cleanup --- _GDIPlus_PenDispose($hCheckPen) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_ImageDispose($hBmp) _GUICtrlTreeView_SetStateImageList($hTreeView, $hImageList) Return True EndFunc ;==>_SetDarkTreeViewCheckboxesGDIp Func _SetDarkTreeViewCheckboxes($hTreeView, $iW = 16, $iH = 16) Local $hImageList = _GUIImageList_Create($iW, $iH, 5, 3) Local $hBmp_GDI = _WinAPI_ExtractThemeBackground($g_hGUI, 2) ;thanks to WildByDesign for the idea! _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) $hBmp_GDI = _WinAPI_ExtractThemeBackground($g_hGUI, 5) _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) _GUICtrlTreeView_SetStateImageList($hTreeView, $hImageList) Return True EndFunc ;==>_SetDarkTreeViewCheckboxes Func _WinAPI_ExtractThemeBackground($hGUI, $iState, $iPart = 3, $iWidth = 16, $iHeight = 16) Local $hTheme = _WinAPI_OpenThemeData($hGUI, "DarkMode_DarkTheme::Button") If @error Then Return SetError(1, 0, 0) Local $hDC = _WinAPI_GetDC($hGUI) Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight) Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC) Local $hObjOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) Local $tRECT = _WinAPI_CreateRectEx(0, 0, $iWidth, $iHeight) _WinAPI_DrawThemeBackground($hTheme, $iPart, $iState, $hMemDC, $tRECT) If @error Then _WinAPI_CloseThemeData($hTheme) Return SetError(2, 0, 0) EndIf _WinAPI_SelectObject($hMemDC, $hObjOld) _WinAPI_ReleaseDC($hGUI, $hDC) _WinAPI_DeleteDC($hMemDC) _WinAPI_CloseThemeData($hTheme) Return $hHBitmap EndFunc ;==>_WinAPI_ExtractThemeBackground Func _EnableMenuHotTrack($hMenu) If Not $hMenu Then Return False Local $tagMENUINFO = "dword cbSize;dword fMask;dword dwStyle;uint cyMax;handle hbrBack;dword dwContextHelpID;ulong_ptr dwMenuData" Local Const $MIM_STYLE = 0x00000010 Local Const $MNS_HOTTRACK = 0x08000000 Local $tMI = DllStructCreate($tagMENUINFO) With $tMI .cbSize = DllStructGetSize($tMI) .fMask = $MIM_STYLE .dwStyle = $MNS_HOTTRACK EndWith _GUICtrlMenu_SetMenuInfo($hMenu, $tMI) ; redraw menus _GUICtrlMenu_DrawMenuBar($g_hGUI) Return True EndFunc ;==>_EnableMenuHotTrack Func _OverpaintWhiteLine() ; The bright artifact line sits exactly 1px above the client area top edge. ; Instead of computing caption+border+menu heights manually (DPI-fragile), ; we locate the client rect in window coordinates and paint 1px above it. ; Get client rect and convert from client to screen coordinates Local $rcClient = _WinAPI_GetClientRect($g_hGUI) DllCall("user32.dll", "int", "MapWindowPoints", _ "hwnd", $g_hGUI, _ ; source: client coords "hwnd", 0, _ ; target: screen coords "ptr", DllStructGetPtr($rcClient), _ "uint", 2) ; 2 points = RECT If @error Then Return SetError(1, 0, 0) ; Make client rect window-relative (subtract window origin) Local $rcWindow = _WinAPI_GetWindowRect($g_hGUI) _WinAPI_OffsetRect($rcClient, -$rcWindow.left, -$rcWindow.top) ; Build a 1px-high rect just above the client area top — that's the artifact line Local $rcAnnoyingLine = DllStructCreate($tagRECT) With $rcAnnoyingLine .left = $rcClient.left .right = $rcClient.right .bottom = $rcClient.top ; bottom = client top .top = $rcClient.top - 1 ; top = 1px above client EndWith ; GetDCEx with DCX_WINDOW grants access to the non-client area ; DCX_INTERSECTRGN limits drawing to the provided region (full window here) Local $hRgn = _WinAPI_CreateRectRgn(-20000, -20000, 20000, 20000) Local $hDC = DllCall("user32.dll", "handle", "GetDCEx", _ "hwnd", $g_hGUI, "handle", $hRgn, _ "dword", BitOR($DCX_WINDOW, $DCX_INTERSECTRGN))[0] Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) _WinAPI_FillRect($hDC, $rcAnnoyingLine, $hBrush) _WinAPI_ReleaseDC($g_hGUI, $hDC) _WinAPI_DeleteObject($hBrush) Return 1 EndFunc ;==>_OverpaintWhiteLine 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 ; Registers a control for DPI-aware repositioning. ; Base coordinates (x, y, w, h) are at 100% DPI - _ApplyDPIScaling multiplies them by $g_fScale. ; fontsize > 0 triggers WM_SETFONT with the shared $g_hCtrlFont on each DPI change. Func _AddControlForDPI($iCtrlID, $x, $y, $w, $h, $fontsize = 8.5, $fontname = "Arial") If $iCtrlID Then $g_aCtrlDPI[$g_iCtrlCountDPI][0] = $iCtrlID $g_aCtrlDPI[$g_iCtrlCountDPI][1] = $x $g_aCtrlDPI[$g_iCtrlCountDPI][2] = $y $g_aCtrlDPI[$g_iCtrlCountDPI][3] = $w $g_aCtrlDPI[$g_iCtrlCountDPI][4] = $h $g_aCtrlDPI[$g_iCtrlCountDPI][5] = $fontsize $g_aCtrlDPI[$g_iCtrlCountDPI][6] = $fontname $g_iCtrlCountDPI += 1 EndIf EndFunc ;==>_AddControlForDPI ; Registers a control (by AutoIt ControlID) for dark mode subclassing and theming. 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 ; reserved for old WndProc (not used with SetWindowSubclass) $g_iControlCount += 1 EndIf EndFunc ;==>_AddControlForSubclass ; Registers a control (by HWND, e.g. native controls not created via GUICtrlCreate) for subclassing. Func _AddControlHandleForSubclass($hCtrl) If $hCtrl Then $g_aControls[$g_iControlCount][0] = 0 $g_aControls[$g_iControlCount][1] = $hCtrl $g_aControls[$g_iControlCount][2] = 0 $g_iControlCount += 1 EndIf EndFunc ;==>_AddControlHandleForSubclass 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") ; Subclass all controls Local $hCtrl, $sClass, $hEdit, $hComboLBox, $hHeader, $hUpDown For $i = 0 To $g_iControlCount - 1 $hCtrl = $g_aControls[$i][1] If $hCtrl Then $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 $hEdit = _WinAPI_FindWindowEx($hCtrl, "Edit") If $hEdit Then _WinAPI_SetWindowTheme($hEdit, "DarkMode_CFD", 0) _WinAPI_AllowDarkModeForWindow($hEdit, True) EndIf ; ComboBox dropdown list $hComboLBox = _WinAPI_FindWindowEx($hCtrl, "ComboLBox") If $hComboLBox Then _WinAPI_SetWindowTheme($hComboLBox, "DarkMode_Explorer", 0) _WinAPI_AllowDarkModeForWindow($hComboLBox, True) EndIf Case "syslistview32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) ; Enable double-buffering to prevent flicker during owner-draw _SendMessage($hCtrl, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_DOUBLEBUFFER) ; LVM_SETEXTENDEDLISTVIEWSTYLE ; Apply dark theme to the ListView header control $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, $TCM_SETBKCOLOR, 0, $COLOR_BG_DARK) ; Try to make the UpDown (spinner for too many tabs) dark as well $hUpDown = _WinAPI_FindWindowEx($hCtrl, "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_CopyEngine", 0) Case "scrollbar" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "sysdatetimepick32" ;~ ConsoleWrite(_WinAPI_SetWindowTheme($hCtrl, "Explorer", 0) & @CRLF) ;~ _WinAPI_AllowDarkModeForWindow($hCtrl, True) Case "msctls_statusbar32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_DarkTheme", 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 Local $hCtrl For $i = 0 To $g_iControlCount - 1 $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 If $iCode = $NM_CUSTOMDRAW Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAW, $lParam) Local $dwStage = $tNMCD.dwDrawStage Local $hDC = $tNMCD.hdc Switch StringLower(_WinAPI_GetClassName($hFrom)) Case "sysheader32" Switch $dwStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT _WinAPI_SetTextColor($hDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) _WinAPI_SetBkColor($hDC, _ColorToCOLORREF($COLOR_BG_DARK)) Return BitOR($CDRF_NEWFONT, $CDRF_NOTIFYPOSTPAINT) EndSwitch EndSwitch EndIf Case $WM_PAINT Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Case $WM_NCPAINT ; WS_EX_CLIENTEDGE border is drawn in WM_NCPAINT (non-client area), not WM_CTLCOLOR. ; We let Windows draw the default frame first, then overdraw it with our dark border. Local $sClass = StringLower(_WinAPI_GetClassName($hWnd)) If $sClass = "edit" Or $sClass = "listbox" Then Local $iRet = _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) Local $hDC = _WinAPI_GetWindowDC($hWnd) Local $tRECT = _WinAPI_GetWindowRect($hWnd) Local $iW = $tRECT.Right - $tRECT.Left Local $iH = $tRECT.Bottom - $tRECT.Top Local $hPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) Local $hOldPen = _WinAPI_SelectObject($hDC, $hPen) Local $hNull = _WinAPI_GetStockObject(5) Local $hOldBr = _WinAPI_SelectObject($hDC, $hNull) DllCall("gdi32.dll", "bool", "Rectangle", "handle", $hDC, "int", 0, "int", 0, "int", $iW, "int", $iH) _WinAPI_SelectObject($hDC, $hOldPen) _WinAPI_SelectObject($hDC, $hOldBr) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC($hWnd, $hDC) Return $iRet EndIf EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc Func _DateProc($hWnd, $iMsg, $wParam, $lParam) Switch $iMsg Case $WM_PAINT Local $tPaint = DllStructCreate($tagPAINTSTRUCT) Local $hDC = _WinAPI_BeginPaint($hWnd, $tPaint) Local $tClient = _WinAPI_GetClientRect($hWnd) Local $iW = $tClient.Right Local $iH = $tClient.Bottom ; --- Memory DC for flicker-free rendering --- Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local $hOldBmp = _WinAPI_SelectObject($hMemDC, $hBitmap) ; 1. Let Windows draw the light-mode control into memory DC _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $WM_PRINTCLIENT, $hMemDC, $PRF_CLIENT) ; 2. Invert all pixels (background becomes black, text white, selection orange) Local $tRECT = DllStructCreate($tagRECT) $tRECT.right = $iW $tRECT.bottom = $iH _WinAPI_InvertRect($hMemDC, $tRECT) ; --- 3. PIXEL HACK: destroy orange highlight & set background color --- ; Strategy: render the light-mode control via WM_PRINTCLIENT, invert all pixels, ; then scan the bitmap and replace near-black (inverted white background) with the ; exact GUI background color, and convert all remaining pixels to grayscale. ; This eliminates the orange selection highlight and unifies the background. Local $iSize = $iW * $iH Local $tPixels = DllStructCreate("dword c[" & $iSize & "]") ; Load pixel array directly from bitmap memory Local $iBytes = DllCall("gdi32.dll", "long", "GetBitmapBits", "handle", $hBitmap, "long", $iSize * 4, "ptr", DllStructGetPtr($tPixels))[0] If $iBytes = $iSize * 4 Then Local $iPixel, $r, $g, $b, $iGray For $i = 1 To $iSize $iPixel = $tPixels.c(($i)) ; Split into color channels $b = BitAND($iPixel, 0xFF) $g = BitAND(BitShift($iPixel, 8), 0xFF) $r = BitAND(BitShift($iPixel, 16), 0xFF) ; Convert to grayscale (orange becomes mid-gray) $iGray = Int(($r + $g + $b) / 3) ; Very dark pixel = inverted white background If $iGray < 15 Then $iPixel = $COLOR_BG_DARK ; Replace with exact GUI background color Else ; Grayscale value for text (white) and selection (gray) ; (negative BitShift shifts left in AutoIt) $iPixel = BitOR(BitShift($iGray, -16), BitShift($iGray, -8), $iGray) EndIf $tPixels.c(($i)) = $iPixel Next ; Write cleaned pixels back into the bitmap DllCall("gdi32.dll", "long", "SetBitmapBits", "handle", $hBitmap, "long", $iSize * 4, "ptr", DllStructGetPtr($tPixels)) EndIf ; --- END PIXEL HACK --- ; --- Border color (hover effect) --- Local $iBorderColor = $COLOR_BORDER If _WinAPI_GetFocus() = $hWnd Then $iBorderColor = $COLOR_BORDER Local $tCursorPos = DllStructCreate($tagPOINT) DllCall("user32.dll", "bool", "GetCursorPos", "struct*", $tCursorPos) DllCall("user32.dll", "bool", "ScreenToClient", "hwnd", $hWnd, "struct*", $tCursorPos) If $tCursorPos.X >= 0 And $tCursorPos.X <= $iW And $tCursorPos.Y >= 0 And $tCursorPos.Y <= $iH Then $iBorderColor = $COLOR_BORDER_LIGHT EndIf ; --- Draw border --- Local $hPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($iBorderColor)) Local $hNullBr = _WinAPI_GetStockObject(5) Local $hOldPen = _WinAPI_SelectObject($hMemDC, $hPen) Local $hOldBr = _WinAPI_SelectObject($hMemDC, $hNullBr) DllCall("gdi32.dll", "bool", "Rectangle", "handle", $hMemDC, "int", 0, "int", 0, "int", $iW, "int", $iH) _WinAPI_SelectObject($hMemDC, $hOldPen) _WinAPI_SelectObject($hMemDC, $hOldBr) _WinAPI_DeleteObject($hPen) ; --- Copy finished result to screen in one step (no flicker) --- _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hMemDC, 0, 0, $SRCCOPY) ; --- Cleanup --- _WinAPI_SelectObject($hMemDC, $hOldBmp) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) _WinAPI_EndPaint($hWnd, $tPaint) Return 0 Case $WM_ERASEBKGND Return 1 Case $WM_SETFOCUS, $WM_KILLFOCUS Local $iRet = _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) _WinAPI_InvalidateRect($hWnd, 0, False) Return $iRet Case $WM_MOUSEMOVE Local $iRet = _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) If Not $g_bHover Then $g_bHover = True _WinAPI_InvalidateRect($hWnd, 0, False) EndIf Return $iRet Case $WM_MOUSELEAVE $g_bHover = False _WinAPI_InvalidateRect($hWnd, 0, False) EndSwitch Return _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_DateProc Func _MakeMenuOwnerDraw($hWnd) ; Converts all top-level menu items to MFT_OWNERDRAW so WM_MEASUREITEM / WM_DRAWITEM ; can render them with the dark color scheme. Must be called again after every DPI change ; to force Windows to re-send WM_MEASUREITEM with updated dimensions. $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] Local $tText, $iLen For $i = 0 To $iCount - 1 ; GetMenuStringW is more reliable than _GUICtrlMenu_GetItemText for Unicode menu strings $tText = DllStructCreate("wchar s[256]") $iLen = DllCall("user32.dll", "int", "GetMenuStringW", "handle", $g_hMenu, "uint", $i, "struct*", $tText, "int", 255, "uint", $MF_BYPOSITION) If IsArray($iLen) And $iLen[0] > 0 Then $g_aMenuText[$i] = $tText.s Else $g_aMenuText[$i] = "" EndIf ; Flag item as owner-drawn - triggers WM_MEASUREITEM immediately _GUICtrlMenu_SetItemType($g_hMenu, $i, $MFT_OWNERDRAW, True) Next ; Force immediate repaint of the menu bar _GUICtrlMenu_DrawMenuBar($hWnd) _WinAPI_RedrawWindow($hWnd, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) Return True EndFunc ;==>_MakeMenuOwnerDraw Func _WM_DPICHANGED($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg _WinAPI_LockWindowUpdate($hWnd) ; suppress painting during DPI transition ; LoWord(wParam) = new DPI value sent by Windows $g_fScale = _WinAPI_LoWord($wParam) / 96 ; lParam = suggested window RECT already adjusted for new DPI - use it directly Local $tRECT = DllStructCreate($tagRECT, $lParam) Local $iX = $tRECT.left, $iY = $tRECT.top, $iW = $tRECT.right - $iX, $iH = $tRECT.bottom - $iY _WinAPI_SetWindowPos($hWnd, 0, $iX, $iY, $iW, $iH, BitOR($SWP_NOZORDER, $SWP_NOACTIVATE)) ; Reposition/resize all registered controls and apply new font _ApplyDPIScaling($g_fScale) ; Recreate menu font for new DPI. ; Old font is kept alive until AFTER _MakeMenuOwnerDraw so WM_MEASUREITEM can still use it. Local $hOldMenuFont = $g_hMenuFont Local $iHeight = -Round(_WinAPI_MulDiv(8.5, _WinAPI_LoWord($wParam), 72)) $g_hMenuFont = _WinAPI_CreateFont($iHeight, 0, 0, 0, $FW_NORMAL, False, False, False, _ $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, "Arial") ; Re-register owner-draw -> forces WM_MEASUREITEM with the new font already active _MakeMenuOwnerDraw($g_hGUI) If $hOldMenuFont Then _WinAPI_DeleteObject($hOldMenuFont) ; safe to delete now _EnableMenuHotTrack($g_hMenu) ; Rescale statusbar part widths using the base (unscaled) values in $g_aStatusbarParts If $g_hStatusbar Then Local $aScaledParts[4] For $i = 0 To 3 $aScaledParts[$i] = $g_aStatusbarParts[$i] * $g_fScale Next _GUICtrlStatusBar_SetParts($g_hStatusbar, $aScaledParts) _SendMessage($g_hStatusbar, $WM_SIZE, 0, 0) EndIf _WinAPI_LockWindowUpdate(0) Return 1 EndFunc ;==>_WM_DPICHANGED Func _WM_MEASUREITEM($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 ; only handle menu items Local $itemID = $t.itemID ; itemID is the menu item command ID, not its position. ; AutoIt assigns IDs starting at 3 for the first top-level menu item. Local $iPos = -1 For $i = 0 To UBound($g_aMenuText) - 1 If $itemID = ($i + 3) Then ; offset 3 = AutoIt internal menu ID base $iPos = $i ExitLoop EndIf Next ; Fallback if ID mapping failed If $iPos < 0 Then $iPos = $itemID If $iPos < 0 Or $iPos >= UBound($g_aMenuText) Then $iPos = 0 Local $sText = $g_aMenuText[$iPos] ; Measure text using DEFAULT_GUI_FONT - Windows keeps this stock object DPI-aware automatically. ; Using a window DC here is intentional: DEFAULT_GUI_FONT is a stock object not affected by DC caching. ; Multiply by $g_fScale because GetTextExtentPoint32 returns logical pixels at 96 DPI baseline. Local $hDC = _WinAPI_GetDC($hWnd) Local $hFont = _WinAPI_GetStockObject($DEFAULT_GUI_FONT) Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) Local $tSize = _WinAPI_GetTextExtentPoint32($hDC, $sText) Local $iTextWidth = $tSize.X * $g_fScale Local $iTextHeight = $tSize.Y * $g_fScale _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_ReleaseDC($hWnd, $hDC) ; Pass measured size back to Windows (no padding needed - DrawText uses exact rect) $t.itemWidth = $iTextWidth $t.itemHeight = $iTextHeight Return 1 EndFunc ;==>_WM_MEASUREITEM Func _WM_DRAWITEM($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($COLOR_MENU_SELECT) Local $clrText = _ColorToCOLORREF($COLOR_TEXT_LIGHT) Static $iDrawCount = 0 Static $bFullBarDrawn = False ; Track how many items have been drawn in this WM_DRAWITEM cycle. ; When the first item (iPos=0) is drawn, fill the entire menu bar background first ; to avoid leftover pixels between items during redraws. $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 = $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 = $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_GetSystemMetricsForDpi($SM_CYMENU, Round($g_fScale * 96)) .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 $bHot = BitAND($state, $ODS_HOTLIGHT) Local $hBrush If $bSelected Then $hBrush = _WinAPI_CreateSolidBrush($clrSel) ElseIf $bHot Then $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_HOTTRACK_MENU)) Else $hBrush = _WinAPI_CreateSolidBrush($clrBG) EndIf 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 = ($g_hMenuFont ? $g_hMenuFont : _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 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 ; --- Slider (msctls_trackbar32) custom drawing --- If $iCode = $NM_CUSTOMDRAW And StringLower(_WinAPI_GetClassName($hWndFrom)) = "msctls_trackbar32" Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAW, $lParam) Local $dwStage = $tNMCD.dwDrawStage Local $hDC = $tNMCD.hdc Local $dwItemSpec = $tNMCD.dwItemSpec Switch $dwStage Case $CDDS_PREPAINT ; Remove focus rectangle from slider DllStructSetData($tNMCD, "ItemState", BitXOR(DllStructGetData($tNMCD, "ItemState"), $CDIS_FOCUS)) Return $CDRF_NOTIFYITEMDRAW ; request per-item notifications Case $CDDS_ITEMPREPAINT Local Const $TBCD_TICS = 0x0001 ; tick marks Local Const $TBCD_THUMB = 0x0002 ; draggable thumb Local Const $TBCD_CHANNEL = 0x0003 ; slider channel/track Local $tRECT = DllStructCreate($tagRECT) $tRECT.left = $tNMCD.left $tRECT.top = $tNMCD.top $tRECT.right = $tNMCD.right $tRECT.bottom = $tNMCD.bottom Switch $dwItemSpec Case $TBCD_TICS ; Let Windows draw tick marks normally Return $CDRF_DODEFAULT Case $TBCD_THUMB ; Draw thumb as a pentagon (rectangle + downward arrow) Local $iL = $tNMCD.left Local $iT = $tNMCD.top Local $iR = $tNMCD.right - 1 ; -1 to stay within bounds and avoid paint artifacts Local $iB = $tNMCD.bottom Local $iMid = ($iL + $iR) / 2 ; horizontal center (tip of arrow) Local $iSplit = $iB - ($iR - $iL) / 2 ; y-position where rectangle ends and arrow begins ; Pentagon points: top-left, top-right, right-middle, bottom-tip, left-middle Local $tPoints = DllStructCreate("int p[10]") $tPoints.p((1)) = $iL $tPoints.p((2)) = $iT $tPoints.p((3)) = $iR $tPoints.p((4)) = $iT $tPoints.p((5)) = $iR $tPoints.p((6)) = $iSplit $tPoints.p((7)) = $iMid $tPoints.p((8)) = $iB $tPoints.p((9)) = $iL $tPoints.p((10)) = $iSplit ; Fill and outline thumb with blue accent color Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF(0x0078D4)) Local $hPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_CONTROL_BG)) Local $hOldBrush = _WinAPI_SelectObject($hDC, $hBrush) Local $hOldPen = _WinAPI_SelectObject($hDC, $hPen) DllCall("gdi32.dll", "bool", "Polygon", "handle", $hDC, "struct*", $tPoints, "int", 5) _WinAPI_SelectObject($hDC, $hOldBrush) _WinAPI_SelectObject($hDC, $hOldPen) _WinAPI_DeleteObject($hBrush) _WinAPI_DeleteObject($hPen) Return $CDRF_SKIPDEFAULT ; skip default drawing Case $TBCD_CHANNEL ; Fill channel with border color Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BORDER)) _WinAPI_FillRect($hDC, $tRECT, $hBrush) _WinAPI_DeleteObject($hBrush) Return $CDRF_SKIPDEFAULT ; skip default drawing EndSwitch EndSwitch EndIf ; --- Per-control notification handling --- Local Static $iTheme Switch $hWndFrom Case $g_hDate ; thanks to argumentum for the code :-) Switch $iCode Case $NM_SETFOCUS ; Disable visual theme when DateTime control receives focus _WinAPI_SetThemeAppProperties(0) Case $NM_KILLFOCUS _WinAPI_SetThemeAppProperties($iTheme) ; cudos to argumentum Case $DTN_DROPDOWN ; Apply dark colors when the calendar dropdown opens Local $iCtrl = _GUICtrlDTP_GetMonthCal($hWndFrom) ; get the MonthCal child handle _WinAPI_SetWindowTheme($iCtrl, "", "") ; remove theme for manual color control _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 dropdown closed - no action needed EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_NOTIFY Func _WM_ACTIVATE($hWnd, $iMsg, $wParam, $lParam) If $hWnd <> $g_hGUI Then Return $GUI_RUNDEFMSG _OverpaintWhiteLine() Return $GUI_RUNDEFMSG EndFunc ;==>_WM_ACTIVATE Func _WM_WINDOWPOSCHANGED($hWnd, $iMsg, $wParam, $lParam) If $hWnd <> $g_hGUI Then Return $GUI_RUNDEFMSG _OverpaintWhiteLine() Return $GUI_RUNDEFMSG EndFunc ;==>_WM_WINDOWPOSCHANGED Func _WM_MENUCOMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local $iPos = $wParam ;Menu Item Position (0-based index) Local $hMenu = $lParam ;Menu Handle Switch $hMenu Case $g_hMenu1 ConsoleWrite("From Menu One" & @CRLF) Switch $iPos Case 0 ; SubMenu One A ConsoleWrite("SubMenu One A clicked" & @CRLF) Case 1 ; SubMenu One B ConsoleWrite("SubMenu One B clicked" & @CRLF) Case 2 ; About ConsoleWrite("About clicked!" & @CRLF) GUICtrlSendToDummy($g_AboutDummy) Return 0 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_MENUCOMMAND Func _WM_SYSCOMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $lParam Switch BitAND($wParam, 0x0000FFFF) Case $idAbout GUICtrlSendToDummy($g_AboutDummy) EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_SYSCOMMAND Func _CleanupBrushes() ; Release all GDI objects created at startup. Called on GUI close. 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) If $g_hMenuFont Then _WinAPI_DeleteObject($g_hMenuFont) If $g_hCtrlFont Then _WinAPI_DeleteObject($g_hCtrlFont) ; control font created by _ApplyDPIScaling Local $j For $j = 0 To UBound($g_aCustomFonts) - 1 If $g_aCustomFonts[$j] Then _WinAPI_DeleteObject($g_aCustomFonts[$j]) Next EndFunc ;==>_CleanupBrushes Func _EnableDarkScrollBars() ; Apply DarkMode_Explorer theme to all controls that have scrollbars. ; Also handles TreeView with $TVS_CHECKBOXES which creates explicit ScrollBar child windows. Local $tScrollInfo, $sClass, $hCtrl, $hChild For $i = 0 To $g_iControlCount - 1 $hCtrl = $g_aControls[$i][1] If Not $hCtrl Then ContinueLoop ; 1ï¸ Normal attempt (works for most controls) $tScrollInfo = _GUIScrollBars_GetScrollInfoEx($hCtrl, 1) If IsDllStruct($tScrollInfo) Then _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) ; 2ï¸ Extension: If the control has its own scrollbar child windows (e.g., TreeView with $TVS_CHECKBOXES) $hChild = _WinAPI_GetWindow($hCtrl, $GW_CHILD) While $hChild $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 but exclude overlapping GUI controls from painting Local $hParent = _WinAPI_GetParent($hWnd) Local $hChild = _WinAPI_GetWindow($hParent, $GW_CHILD) Local $tCR, $tPR = _WinAPI_GetWindowRect($hWnd) Local $left, $top, $right, $bottom While $hChild If $hChild <> $hWnd And _WinAPI_IsWindowVisible($hChild) Then $tCR = _WinAPI_GetWindowRect($hChild) ; Only exclude controls that lie fully within the tab control area If $tCR.left >= $tPR.left And $tCR.right <= $tPR.right And $tCR.top >= $tPR.top And $tCR.bottom <= $tPR.bottom Then $left = $tCR.left - $tPR.left $top = $tCR.top - $tPR.top $right = $tCR.right - $tPR.left $bottom = $tCR.bottom - $tPR.top ; Exclude from offscreen bitmap (prevents black fill) DllCall("gdi32.dll", "int", "ExcludeClipRect", "handle", $hMemDC, "int", $left, "int", $top, "int", $right, "int", $bottom) ; Exclude from screen DC (prevents BitBlt overwrite) DllCall("gdi32.dll", "int", "ExcludeClipRect", "handle", $hDC, "int", $left, "int", $top, "int", $right, "int", $bottom) EndIf EndIf $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT) WEnd ; 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, $TCM_GETITEMCOUNT, 0, 0) Local $iCurSel = _SendMessage($hWnd, $TCM_GETCURSEL, 0, 0) ; 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, $iLeft, $iTop, $iRight, $iBottom, $tItem, $tText, $bSelected, $iTabColor, $hTabBrush, $tTabRect, _ $sText, $hPen, $hOldPen, $hPenSep, $hOldPenSep, $tTextRect, $hBorderPen, $hOldBorderPen, $hNullBrush, $hOldBorderBrush For $i = 0 To $iTabCount - 1 ; Get tab rectangle using TCM_GETITEMRECT $tRECT = DllStructCreate($tagRECT) $aResult = DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hWnd, "uint", $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 $tItem = DllStructCreate("uint Mask;dword dwState;dword dwStateMask;ptr pszText;int cchTextMax;int iImage;lparam lParam") $tText = DllStructCreate("wchar Text[256]") With $tItem .Mask = $TCIF_TEXT .pszText = DllStructGetPtr($tText) .cchTextMax = 256 EndWith DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hWnd, "uint", $TCM_GETITEMW, "wparam", $i, "struct*", $tItem) $sText = DllStructGetData($tText, "Text") ; Draw tab background $bSelected = ($i = $iCurSel) $iTabColor = $bSelected ? $COLOR_BUTTON_BG : $COLOR_BG_DARK $hTabBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($iTabColor)) $tTabRect = DllStructCreate($tagRECT) With $tTabRect .Left = $iLeft .Top = $iTop .Right = $iRight .Bottom = $iBottom EndWith _WinAPI_FillRect($hMemDC, $tTabRect, $hTabBrush) _WinAPI_DeleteObject($hTabBrush) ; Draw selection indicator (top border for selected tab) If $bSelected Then $hPen = _WinAPI_CreatePen(0, 2, _ColorToCOLORREF(0x0078D4)) ; Blue accent $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 $hPenSep = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) $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 $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 $hBorderPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) $hOldBorderPen = _WinAPI_SelectObject($hMemDC, $hBorderPen) $hNullBrush = _WinAPI_GetStockObject(5) ; NULL_BRUSH $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 Case $WM_PARENTNOTIFY ; Fired when a child window is created inside the tab control. ; The tab spinner (msctls_updown32) is created lazily by Windows when tabs overflow - ; it doesn't exist at init time, so we theme it here the moment it appears. If _WinAPI_LoWord($wParam) = $WM_CREATE Then Local $hNewChild = HWnd($lParam) ; lParam carries the new child's HWND as integer - must cast! If StringLower(_WinAPI_GetClassName($hNewChild)) = "msctls_updown32" Then _WinAPI_AllowDarkModeForWindow($hNewChild, True) _WinAPI_SetWindowTheme($hNewChild, "DarkMode_Explorer", 0) _SendMessage($hNewChild, $WM_THEMECHANGED, 0, 0) EndIf EndIf Return _WinAPI_CallWindowProc($g_hProc, $hWnd, $iMsg, $wParam, $lParam) EndSwitch Return _WinAPI_CallWindowProc($g_hProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_WinProc Func _WinAPI_FindWindowEx($hParent, $sClass, $sTitle = "", $hAfter = 0) 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 #Region WinAPI DPI ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-adjustwindowrectexfordpi Func _WinAPI_AdjustWindowRectExForDpi($dpi, $dwStyle, $dwExStyle, $bMenu = False) Local $tRECT = DllStructCreate($tagRECT) Local $aResult = DllCall("user32.dll", "bool", "AdjustWindowRectExForDpi", "struct*", $tRECT, "dword", $dwStyle, "bool", $bMenu, "dword", $dwExStyle, "int", $dpi) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $tRECT EndFunc ;==>_WinAPI_AdjustWindowRectExForDpi ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfofordpi Func _WinAPI_SystemParametersInfoForDpi($uiAction, $uiParam, $pvParam, $fWinIni, $dpi) Local $aResult = DllCall("user32.dll", "bool", "SystemParametersInfoForDpi", "uint", $uiAction, "uint", $uiParam, "struct*", $pvParam, "uint", $fWinIni, "uint", $dpi) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_SystemParametersInfoForDpi ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-inheritwindowmonitor Func _WinAPI_InheritWindowMonitor($hWnd, $hWndInherit) Local $aResult = DllCall("user32.dll", "bool", "InheritWindowMonitor", "hwnd", $hWnd, "hwnd", $hWndInherit) ;requires Win10 v1803+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_InheritWindowMonitor ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isvaliddpiawarenesscontext Func _WinAPI_IsValidDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "bool", "IsValidDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_IsValidDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-logicaltophysicalpointforpermonitordpi Func _WinAPI_LogicalToPhysicalPointForPerMonitorDPI($hWnd, $iX, $iY) Local $tPOINT = DllStructCreate($tagPOINT) $tPOINT.x = $iX $tPOINT.y = $iY Local $aResult = DllCall("user32.dll", "bool", "LogicalToPhysicalPointForPerMonitorDPI", "hwnd", $hWnd, "struct*", $tPOINT) ;requires Win 8.1+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $tPOINT EndFunc ;==>_WinAPI_LogicalToPhysicalPointForPerMonitorDPI ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-physicaltologicalpointforpermonitordpi Func _WinAPI_PhysicalToLogicalPointForPerMonitorDPI($hWnd, $iX, $iY) Local $tPOINT = DllStructCreate($tagPOINT) $tPOINT.X = $iX $tPOINT.Y = $iY Local $aResult = DllCall("user32.dll", "bool", "PhysicalToLogicalPointForPerMonitorDPI", "hwnd", $hWnd, "struct*", $tPOINT) ;requires Win 8.1+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $tPOINT EndFunc ;==>_WinAPI_PhysicalToLogicalPointForPerMonitorDPI Func _GDIPlus_GetDPI($hGUI = 0) Local $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI) If @error Then Return SetError(1, @extended, 0) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0) If @error Then Return SetError(2, @extended, 0) _GDIPlus_GraphicsDispose($hGfx) Return $aResult[2] EndFunc ;==>_GDIPlus_GetDPI Func _WinAPI_GetDPI($hWnd = 0) $hWnd = (Not $hWnd ? _WinAPI_GetDesktopWindow() : $hWnd) Local Const $hDC = _WinAPI_GetDC($hWnd) If @error Then Return SetError(1, 0, 0) Local Const $iDPI = _WinAPI_GetDeviceCaps($hDC, $LOGPIXELSX) If @error Or Not $iDPI Then _WinAPI_ReleaseDC($hWnd, $hDC) Return SetError(2, 0, 0) EndIf _WinAPI_ReleaseDC($hWnd, $hDC) Return $iDPI EndFunc ;==>_WinAPI_GetDPI ;https://learn.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-getdpiformonitor Func _WinAPI_GetDpiForMonitor($hMonitor = 0, $dpiType = $MDT_DEFAULT) If $hMonitor = 0 Then Local $aMonitors = _WinAPI_EnumDisplayMonitors() If @error Or Not IsArray($aMonitors) Then Return SetError(1, 0, 0) Local $i For $i = 1 To $aMonitors[0][0] If _WinAPI_GetMonitorInfo($aMonitors[$i][0])[2] = 1 Then $hMonitor = $aMonitors[$i][0] ExitLoop EndIf Next EndIf Local $tx = DllStructCreate("uint dpiX"), $tY = DllStructCreate("uint dpiY") Local $aResult = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "handle", $hMonitor, "long", $dpiType, "struct*", $tx, "struct*", $tY) If @error Or Not IsArray($aResult) Then Return SetError(2, 0, 0) If $aResult[0] <> 0 Then Return SetError(3, $aResult[0], 0) Return $tx.dpiX EndFunc ;==>_WinAPI_GetDpiForMonitor ;https://learn.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-getdpiformonitor Func _WinAPI_GetDpiForMonitor2($hMonitor, $dpiType = $MDT_EFFECTIVE_DPI) Local $tDpiX = DllStructCreate("uint dpiX") Local $tDpiY = DllStructCreate("uint dpiY") Local $aResult = DllCall("Shcore.dll", "long", "GetDpiForMonitor", _ ;Win8.1+ "handle", $hMonitor, _ "int", $dpiType, _ "struct*", $tDpiX, _ "struct*", $tDpiY) If @error Or Not IsArray($aResult) Then Return SetError(1, @error, 0) If $aResult[0] <> 0 Then Return SetError(2, $aResult[0], 0) ; HRESULT check Local $aReturn[2] = [DllStructGetData($tDpiX, "dpiX"), DllStructGetData($tDpiY, "dpiY")] Return $aReturn ; Returns both X and Y DPI EndFunc ;==>_WinAPI_GetDpiForMonitor2 ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforwindow Func _WinAPI_GetDpiForWindow($hWnd) Local $aResult = DllCall("user32.dll", "uint", "GetDpiForWindow", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiForWindow ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforsystem Func _WinAPI_GetDpiForSystem() Local $aResult = DllCall("user32.dll", "uint", "GetDpiForSystem") ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiForSystem ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getthreaddpiawarenesscontext Func _WinAPI_GetThreadDpiAwarenessContext() Local $aResult = DllCall("user32.dll", (@AutoItX64 ? "int64" : "int"), "GetThreadDpiAwarenessContext") ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetThreadDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpifromdpiawarenesscontext Func _WinAPI_GetDpiFromDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "uint", "GetDpiFromDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1803+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiFromDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getawarenessfromdpiawarenesscontext Func _WinAPI_GetAwarenessFromDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "uint", "GetAwarenessFromDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetAwarenessFromDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiawarenesscontextforprocess Func _WinAPI_GetDpiAwarenessContextForProcess($hProcess) Local $aResult = DllCall("user32.dll", (@AutoItX64 ? "int64" : "int"), "GetDpiAwarenessContextForProcess", "handle", $hProcess) ;requires Win10 v1803+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDpiAwarenessContextForProcess ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemdpiforprocess Func _WinAPI_GetSystemDpiForProcess($hProcess) Local $aResult = DllCall("user32.dll", "uint", "GetSystemDpiForProcess", "handle", $hProcess) ;requires Win10 v1803+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetSystemDpiForProcess ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowdpiawarenesscontext Func _WinAPI_GetWindowDpiAwarenessContext($hWnd) Local $aResult = DllCall("user32.dll", (@AutoItX64 ? "int64" : "int"), "GetWindowDpiAwarenessContext", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetWindowDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiawarenesscontext Func _WinAPI_SetProcessDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1703+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setthreaddpiawarenesscontext Func _WinAPI_SetThreadDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) Local $aResult = DllCall("user32.dll", (@AutoItX64 ? "int64" : "int"), "SetThreadDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1703+ / Windows Server 2016+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_SetThreadDpiAwarenessContext ;https://learn.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness Func _WinAPI_SetProcessDpiAwareness($PROCESS_DPI_AWARENESS = $DPI_AWARENESS_PER_MONITOR_AWARE) Local $aResult = DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $PROCESS_DPI_AWARENESS) ;requires Win 8.1+ / Server 2012 R2+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If $aResult[0] Then Return SetError(2, $aResult[0], 0) Return 1 EndFunc ;==>_WinAPI_SetProcessDpiAwareness Func _WinAPI_SetDPIAwareness($iAwarenessLevel = $DPI_AWARENESS_PER_MONITOR_AWARE, $iMode = 1) If @OSBuild < 6000 Then Return SetError(100, 0, 0) ; $iAwarenessLevel unified for all Windows versions: ; 0 = UNAWARE ; 1 = SYSTEM_AWARE ; 2 = PER_MONITOR_AWARE (default) ; 3 = PER_MONITOR_AWARE_V2 (Win10 1703+ only) ; 4 = UNAWARE_GDISCALED (Win10 1803+ only) $iAwarenessLevel = ($iAwarenessLevel < 0) ? (-$iAwarenessLevel - 1) : ($iAwarenessLevel > 4) ? 4 : $iAwarenessLevel Switch @OSBuild Case 6000 To 9199 ; Vista - Windows 8 Local $aResult = DllCall("user32.dll", "bool", "SetProcessDPIAware") If Not IsArray($aResult) Or Not $aResult[0] Then Return SetError(1, 0, 0) Case 9200 To 13999 ; Windows 8.1 - Windows 10 Build 14393 ; Limit to 0-2 for this version Local $iLegacyLevel = ($iAwarenessLevel > 2) ? 2 : $iAwarenessLevel If _WinAPI_SetProcessDpiAwareness($iLegacyLevel) = 0 Then Return SetError(2, @error, 0) Case Else ; Windows 10 Build 14393+ ; Convert to DPI_AWARENESS_CONTEXT values Local $aContextMap[5] = [$DPI_AWARENESS_CONTEXT_UNAWARE, _ ; -1 $DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, _ ; -2 $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE, _ ; -3 $DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, _ ; -4 $DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED _ ; -5 ] ; Limit V2 and GDISCALED to compatible Windows versions If $iAwarenessLevel = 3 And @OSBuild < 15063 Then $iAwarenessLevel = 2 ; V2 requires 1703+ If $iAwarenessLevel = 4 And @OSBuild < 17134 Then $iAwarenessLevel = 2 ; GDISCALED requires 1803+ Local $iDpiContext = $aContextMap[$iAwarenessLevel] $iMode = ($iMode < 1) ? 1 : ($iMode > 2) ? 2 : $iMode Local $iResult Switch $iMode Case 1 ; Process-wide setting $iResult = _WinAPI_SetProcessDpiAwarenessContext($iDpiContext) If Not $iResult Or @error Then Return SetError(3, @error, 0) Case 2 ; Thread-specific setting $iResult = _WinAPI_SetThreadDpiAwarenessContext($iDpiContext) If Not $iResult Or @error Then Return SetError(4, @error, 0) EndSwitch EndSwitch ; Retrieve DPI value Local $iDPI If @OSBuild < 9200 Then $iDPI = _WinAPI_GetDPI() If @error Or Not $iDPI Then Return SetError(5, 0, 0) Else $iDPI = _WinAPI_GetDpiForMonitor() If @error Or Not $iDPI Then Return SetError(6, 0, 0) EndIf Return $iDPI EndFunc ;==>_WinAPI_SetDPIAwareness ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-aredpiawarenesscontextsequal Func _WinAPI_AreDpiAwarenessContextsEqual($dpiContextA, $dpiContextB) Local $aResult = DllCall("user32.dll", "bool", "AreDpiAwarenessContextsEqual", _ ;Win10 1607+ @AutoItX64 ? "int64" : "int", $dpiContextA, _ @AutoItX64 ? "int64" : "int", $dpiContextB) If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, False) Return $aResult[0] EndFunc ;==>_WinAPI_AreDpiAwarenessContextsEqual ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enablenonclientdpiscaling Func _WinAPI_EnableNonClientDpiScaling($hWnd) Local $aResult = DllCall("user32.dll", "bool", "EnableNonClientDpiScaling", "hwnd", $hWnd) ;Win10 1607+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_EnableNonClientDpiScaling ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetricsfordpi Func _WinAPI_GetSystemMetricsForDpi($nIndex, $dpi) Local $aResult = DllCall("user32.dll", "int", "GetSystemMetricsForDpi", "int", $nIndex, "uint", $dpi) ;Win10 1607+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetSystemMetricsForDpi ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdialogdpichangebehavior Func _WinAPI_GetDialogDpiChangeBehavior($hWnd) Local $aResult = DllCall("user32.dll", "int", "GetDialogDpiChangeBehavior", "hwnd", $hWnd) ;Win10 1703+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDialogDpiChangeBehavior Func _WinAPI_SetDialogDpiChangeBehavior($hWnd, $mask, $values) Local $aResult = DllCall("user32.dll", "bool", "SetDialogDpiChangeBehavior", "hwnd", $hWnd, "int", $mask, "int", $values) ;Win10 1703+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_SetDialogDpiChangeBehavior ;https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdialogcontroldpichangebehavior Func _WinAPI_GetDialogControlDpiChangeBehavior($hWnd) Local $aResult = DllCall("user32.dll", "int", "GetDialogControlDpiChangeBehavior", "hwnd", $hWnd) ;Win10 1703+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDialogControlDpiChangeBehavior Func _WinAPI_SetDialogControlDpiChangeBehavior($hWnd, $mask, $values) Local $aResult = DllCall("user32.dll", "bool", "SetDialogControlDpiChangeBehavior", "hwnd", $hWnd, "int", $mask, "int", $values) ;Win10 1703+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_SetDialogControlDpiChangeBehavior ;https://learn.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-openthemedatafordpi Func _WinAPI_OpenThemeDataForDpi($hWnd, $pszClassList, $dpi) Local $aResult = DllCall("uxtheme.dll", "handle", "OpenThemeDataForDpi", "hwnd", $hWnd, "wstr", $pszClassList, "uint", $dpi) ;Win10 1703+ If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_OpenThemeDataForDpi #EndRegion WinAPI DPI
-
UEZ reacted to a post in a topic:
SampleControls.au3 in Dark Mode
-
UEZ reacted to a post in a topic:
How can we obtain the font size for a GUI?
-
SOLVE-SMART reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
WildByDesign reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
DarkMode UDF for AutoIt's Win32GUIs
UEZ replied to NoNameCode's topic in AutoIt Technical Discussion
This works in my example: Func _SetDarkTreeViewCheckboxes($hTreeView) Local $hImageList = _GUIImageList_Create(16, 16, 5, 3) Local $hBmp_GDI = _WinAPI_ExtractThemeBackground($g_hGUI, 2) ;thanks to WildByDesign for the idea! _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) $hBmp_GDI = _WinAPI_ExtractThemeBackground($g_hGUI, 5) _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) _GUICtrlTreeView_SetStateImageList($hTreeView, $hImageList) Return True EndFunc ;==>_SetDarkTreeViewCheckboxes Func _WinAPI_ExtractThemeBackground($hGUI, $iState, $iPart = 3, $iWidth = 16, $iHeight = 16) Local $hTheme = _WinAPI_OpenThemeData($hGUI, "DarkMode_DarkTheme::Button") If @error Then Return SetError(1, 0, 0) Local $hDC = _WinAPI_GetDC($hGUI) Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight) Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC) Local $hObjOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) Local $tRECT = _WinAPI_CreateRectEx(0, 0, $iWidth, $iHeight) _WinAPI_DrawThemeBackground($hTheme, $iPart, $iState, $hMemDC, $tRECT) If @error Then _WinAPI_CloseThemeData($hTheme) Return SetError(2, 0, 0) EndIf _WinAPI_SelectObject($hMemDC, $hObjOld) _WinAPI_ReleaseDC($hGUI, $hDC) _WinAPI_DeleteDC($hMemDC) _WinAPI_CloseThemeData($hTheme) Return $hHBitmap EndFunc ;==>_WinAPI_ExtractThemeBackground Important is to use: "DarkMode_DarkTheme::Button" -
WildByDesign reacted to a post in a topic:
SampleControls.au3 in Dark Mode
-
WildByDesign reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
UEZ reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
DarkMode UDF for AutoIt's Win32GUIs
UEZ replied to NoNameCode's topic in AutoIt Technical Discussion
I changed in my example the drawing from GDI to GDI+ completely. Func _GDIPlus_DrawRoundRect($hGfx, $iX, $iY, $iW, $iH, $iDiameter, $iBrushARGB, $iPenARGB, $fPenWidth = 1.0) Local Const $hPath = _GDIPlus_PathCreate() ; Top-left arc _GDIPlus_PathAddArc($hPath, $iX, $iY, $iDiameter, $iDiameter, 180, 90) ; Top-right arc _GDIPlus_PathAddArc($hPath, $iX + $iW - $iDiameter, $iY, $iDiameter, $iDiameter, 270, 90) ; Bottom-right arc _GDIPlus_PathAddArc($hPath, $iX + $iW - $iDiameter, $iY + $iH - $iDiameter, $iDiameter, $iDiameter, 0, 90) ; Bottom-left arc _GDIPlus_PathAddArc($hPath, $iX, $iY + $iH - $iDiameter, $iDiameter, $iDiameter, 90, 90) _GDIPlus_PathCloseFigure($hPath) If $iBrushARGB <> 0 Then Local Const $hBrush = _GDIPlus_BrushCreateSolid($iBrushARGB) _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush) _GDIPlus_BrushDispose($hBrush) EndIf If $iPenARGB <> 0 Then Local Const $hPen = _GDIPlus_PenCreate($iPenARGB, $fPenWidth) _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen) _GDIPlus_PenDispose($hPen) EndIf _GDIPlus_PathDispose($hPath) EndFunc ;==>_GDIPlus_DrawRoundRect Func _SetDarkTreeViewCheckboxes($hTreeView, $iW = 16, $iH = 16) Local $hImageList = _GUIImageList_Create($iW, $iH, 5, 3) Local $hBmp = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hBmp) _GDIPlus_GraphicsSetSmoothingMode($hGfx, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ; --- Index 0: Unchecked --- _GDIPlus_GraphicsClear($hGfx, 0xFF000000 + $COLOR_EDIT_BG) _GDIPlus_DrawRoundRect($hGfx, 2 / 16 * $iW, 2 / 16 * $iH, 12 / 16 * $iW, 12 / 16 * $iH, 3, 0, 0xFF000000 + $COLOR_BORDER2, 1.5) Local $hBmp_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp, 0) _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) ; --- Index 1: Checked --- _GDIPlus_GraphicsClear($hGfx, 0xFF000000 + $COLOR_EDIT_BG) _GDIPlus_DrawRoundRect($hGfx, 2 / 16 * $iW, 2 / 16 * $iH, 12 / 16 * $iW, 12 / 16 * $iH, 3, 0xFF60CDFF, 0xFF60CDFF, 1.0) Local $hCheckPen = _GDIPlus_PenCreate(0xFF0F2028, 1.5) _GDIPlus_GraphicsDrawLine($hGfx, 5 / 16 * $iW, 8 / 16 * $iH, 7 / 16 * $iW, 10 / 16 * $iH, $hCheckPen) _GDIPlus_GraphicsDrawLine($hGfx, 7 / 16 * $iW, 10 / 16 * $iH, 11 / 16 * $iW, 6 / 16 * $iH, $hCheckPen) $hBmp_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp, 0) _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) ; --- Cleanup --- _GDIPlus_PenDispose($hCheckPen) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_ImageDispose($hBmp) _GUICtrlTreeView_SetStateImageList($hTreeView, $hImageList) Return True EndFunc ;==>_SetDarkTreeViewCheckboxes It gives much more smoother drawings with aa. To your new idea - I like it. You can draw to a GDI bitmap and add it to ImageList. Let me check it and add it to the example... -
_WM_INITMENUPOPUP() is useless and can be removed.
-
WildByDesign reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
ioa747 reacted to a post in a topic:
SampleControls.au3 in Dark Mode
-
argumentum reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
DarkMode UDF for AutoIt's Win32GUIs
UEZ replied to NoNameCode's topic in AutoIt Technical Discussion
I updated also my example by drawing the checkbox using GDI+ with aa. It uses GDI and GDIPlus to create it -> see _SetDarkTreeViewCheckboxes() function. Next step is to add DPI using _WinAPI_DPI.au3 from here: Let's see how complicated it will be to draw all the controls on DPI changes... -
WildByDesign reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
argumentum reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
DarkMode UDF for AutoIt's Win32GUIs
UEZ replied to NoNameCode's topic in AutoIt Technical Discussion
GUIDarkTheme.au3 incl. base64 icons: #include-once #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GDIPlus.au3> ; #INDEX# ======================================================================================================================= ; Title .........: GUIDarkTheme UDF Library for AutoIt3 ; AutoIt Version : 3.3.18.0 ; Language ......: English ; Description ...: UDF library for applying dark theme to win32 controls ; Author(s) .....: WildByDesign (including previous code from NoNameCode, argumentum, UEZ) ; Version .......: 0.9 ; =============================================================================================================================== ; Windows messages used by GUIDarkTheme: (only when relevant controls are detected) ; $WM_CTLCOLORLISTBOX ; $WM_CTLCOLOREDIT ; $WM_NOTIFY ; Windows messages used by GUIDarkMenu: (activated only if GUI has a menubar) ; $WM_DRAWITEM ; $WM_MEASUREITEM ; $WM_NCPAINT ; $WM_ACTIVATE #Region Functions list ; #CURRENT# ===================================================================================================================== ; _GUISetDarkTheme ; _GUICtrlSetDarkTheme ; _GUICtrlAllSetDarkTheme ; _ApplyDarkTheme ; _ApplyLightTheme ; =============================================================================================================================== #EndRegion Functions list #Region API Functions list ; #CURRENT# ===================================================================================================================== ; _WinAPI_ShouldAppsUseDarkMode ; _WinAPI_AllowDarkModeForWindow ; _WinAPI_AllowDarkModeForApp ; _WinAPI_FlushMenuThemes ; _WinAPI_RefreshImmersiveColorPolicyState ; _WinAPI_IsDarkModeAllowedForWindow ; _WinAPI_GetIsImmersiveColorUsingHighContrast ; _WinAPI_OpenNcThemeData ; =============================================================================================================================== #EndRegion API Functions list #include <GuiMonthCal.au3> #include <GuiDateTimePicker.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> #include <TabConstants.au3> #include <GuiImageList.au3> #include <GuiTreeView.au3> #include <GuiMenu.au3> #include "GUIDarkInternal.au3" #include "GUIDarkMenu.au3" #Region Global Variables and Constants ; #VARIABLES# =================================================================================================================== ; Windows build information Global $iOSBuild = @OSBuild Global $iRevision = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "UBR") Global $b24H2Plus = False If $iOSBuild >= 26100 And $iRevision >= 6899 Then $b24H2Plus = True ; Fake lower build number to test DarkMode_Explorer ;$b24H2Plus = False ; Declare edit brush Global $g_hBrushEdit = 0 ; Global variable for tab subclassing Global $g_hTab_CB, $g_pTab_CB, $g_hProc, $g_hTab ; Set global variable placeholders in the case SysListView32 control is detected ; TODO: need better method if there are multiple ListView controls Global $hWndListViewHeader, $hWndListView Global $g__ListView_wProcNew = 0, $g__ListView_wProcOld = 0 ; DateTimePicker Global $g_hDateProc_CB, $g_pDateProc_CB, $g_hDateOldProc, $g_hDate Global Const $PRF_CLIENT = 0x0004, $DTP_BORDER = 0x404040, $DTP_BG_DARK = $COLOR_CONTROL_BG, $DTP_TEXT_LIGHT = $COLOR_TEXT_LIGHT, $DTP_BORDER_LIGHT = 0xD8D8D8 Global $g_bHover = False ; 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) #Region ; GUIStyles.inc.au3 ;~ #include "GUIStyles.inc.au3" Global Const $_g__Style_Gui[32][2] = _ [[0x80000000, 'WS_POPUP'], _ [0x40000000, 'WS_CHILD'], _ [0x20000000, 'WS_MINIMIZE'], _ [0x10000000, 'WS_VISIBLE'], _ [0x08000000, 'WS_DISABLED'], _ [0x04000000, 'WS_CLIPSIBLINGS'], _ [0x02000000, 'WS_CLIPCHILDREN'], _ [0x01000000, 'WS_MAXIMIZE'], _ [0x00CF0000, 'WS_OVERLAPPEDWINDOW'], _ ; (WS_CAPTION | WS_SYSMENU | WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) aka 'WS_TILEDWINDOW' [0x00C00000, 'WS_CAPTION'], _ ; (WS_BORDER | WS_DLGFRAME) [0x00800000, 'WS_BORDER'], _ [0x00400000, 'WS_DLGFRAME'], _ [0x00200000, 'WS_VSCROLL'], _ [0x00100000, 'WS_HSCROLL'], _ [0x00080000, 'WS_SYSMENU'], _ [0x00040000, 'WS_SIZEBOX'], _ [0x00020000, '! WS_MINIMIZEBOX ! WS_GROUP'], _ ; ! GUI ! Control [0x00010000, '! WS_MAXIMIZEBOX ! WS_TABSTOP'], _ ; ! GUI ! Control [0x00002000, 'DS_CONTEXTHELP'], _ [0x00001000, 'DS_CENTERMOUSE'], _ [0x00000800, 'DS_CENTER'], _ [0x00000400, 'DS_CONTROL'], _ [0x00000200, 'DS_SETFOREGROUND'], _ [0x00000100, 'DS_NOIDLEMSG'], _ [0x00000080, 'DS_MODALFRAME'], _ [0x00000040, 'DS_SETFONT'], _ [0x00000020, 'DS_LOCALEDIT'], _ [0x00000010, 'DS_NOFAILCREATE'], _ [0x00000008, 'DS_FIXEDSYS'], _ [0x00000004, 'DS_3DLOOK'], _ [0x00000002, 'DS_SYSMODAL'], _ [0x00000001, 'DS_ABSALIGN']] ; ; [0x80880000, 'WS_POPUPWINDOW'] ; [0x20000000, 'WS_ICONIC'] ; [0x00040000, 'WS_THICKFRAME'] ; ; [0x00000000, 'WS_OVERLAPPED'] ; also named 'WS_TILED' Global Const $_g__Style_GuiExtended[21][2] = _ [[0x08000000, 'WS_EX_NOACTIVATE'], _ [0x02000000, 'WS_EX_COMPOSITED'], _ [0x00400000, 'WS_EX_LAYOUTRTL'], _ [0x00100000, '! WS_EX_NOINHERITLAYOUT ! GUI_WS_EX_PARENTDRAG'], _ ; ! GUI ! Control (label or pic, AutoIt "draggable" feature on 2 controls) [0x00080000, 'WS_EX_LAYERED'], _ [0x00040000, 'WS_EX_APPWINDOW'], _ [0x00020000, 'WS_EX_STATICEDGE'], _ [0x00010000, 'WS_EX_CONTROLPARENT'], _ ; AutoIt adds a "draggable" feature to this GUI extended style behavior [0x00004000, 'WS_EX_LEFTSCROLLBAR'], _ [0x00002000, 'WS_EX_RTLREADING'], _ [0x00001000, 'WS_EX_RIGHT'], _ [0x00000400, 'WS_EX_CONTEXTHELP'], _ [0x00000200, 'WS_EX_CLIENTEDGE'], _ [0x00000100, 'WS_EX_WINDOWEDGE'], _ [0x00000080, 'WS_EX_TOOLWINDOW'], _ [0x00000040, 'WS_EX_MDICHILD'], _ [0x00000020, 'WS_EX_TRANSPARENT'], _ [0x00000010, 'WS_EX_ACCEPTFILES'], _ [0x00000008, 'WS_EX_TOPMOST'], _ [0x00000004, 'WS_EX_NOPARENTNOTIFY'], _ [0x00000001, 'WS_EX_DLGMODALFRAME']] ; ; [0x00000300, 'WS_EX_OVERLAPPEDWINDOW'] ; [0x00000188, 'WS_EX_PALETTEWINDOW'] ; ; [0x00000000, 'WS_EX_LEFT'] ; [0x00000000, 'WS_EX_LTRREADING'] ; [0x00000000, 'WS_EX_RIGHTSCROLLBAR'] Global Const $_g__Style_Avi[5][2] = _ [[0x0010, 'ACS_NONTRANSPARENT'], _ [0x0008, 'ACS_TIMER'], _ [0x0004, 'ACS_AUTOPLAY'], _ [0x0002, 'ACS_TRANSPARENT'], _ [0x0001, 'ACS_CENTER']] Global Const $_g__Style_Button[20][2] = _ [[0x8000, 'BS_FLAT'], _ [0x4000, 'BS_NOTIFY'], _ [0x2000, 'BS_MULTILINE'], _ [0x1000, 'BS_PUSHLIKE'], _ [0x0C00, 'BS_VCENTER'], _ [0x0800, 'BS_BOTTOM'], _ [0x0400, 'BS_TOP'], _ [0x0300, 'BS_CENTER'], _ [0x0200, 'BS_RIGHT'], _ [0x0100, 'BS_LEFT'], _ [0x0080, 'BS_BITMAP'], _ [0x0040, 'BS_ICON'], _ [0x0020, 'BS_RIGHTBUTTON'], _ [0x0009, 'BS_AUTORADIOBUTTON'] , _ [0x0007, 'BS_GROUPBOX'], _ [0x0006, 'BS_AUTO3STATE'], _ [0x0005, 'BS_3STATE'], _ [0x0003, 'BS_AUTOCHECKBOX'], _ [0x0002, 'BS_CHECKBOX'], _ [0x0001, 'BS_DEFPUSHBUTTON']] Global Const $_g__Style_Combo[13][2] = _ [[0x4000, 'CBS_LOWERCASE'], _ [0x2000, 'CBS_UPPERCASE'], _ [0x0800, 'CBS_DISABLENOSCROLL'], _ [0x0400, 'CBS_NOINTEGRALHEIGHT'], _ [0x0200, 'CBS_HASSTRINGS'], _ [0x0100, 'CBS_SORT'], _ [0x0080, 'CBS_OEMCONVERT'], _ [0x0040, 'CBS_AUTOHSCROLL'], _ [0x0020, 'CBS_OWNERDRAWVARIABLE'], _ [0x0010, 'CBS_OWNERDRAWFIXED'], _ [0x0003, 'CBS_DROPDOWNLIST'], _ [0x0002, 'CBS_DROPDOWN'], _ [0x0001, 'CBS_SIMPLE']] Global Const $_g__Style_Common[12][2] = _ ; "for rebar controls, toolbar controls, and status windows (msdn)" [[0x0083, 'CCS_RIGHT'], _ [0x0082, 'CCS_NOMOVEX'], _ [0x0081, 'CCS_LEFT'], _ [0x0080, 'CCS_VERT'], _ [0x0040, 'CCS_NODIVIDER'], _ [0x0020, 'CCS_ADJUSTABLE'], _ [0x0010, 'CCS_NOHILITE'], _ [0x0008, 'CCS_NOPARENTALIGN'], _ [0x0004, 'CCS_NORESIZE'], _ [0x0003, 'CCS_BOTTOM'], _ [0x0002, 'CCS_NOMOVEY'], _ [0x0001, 'CCS_TOP']] Global Const $_g__Style_DateTime[7][2] = _ [[0x0020, 'DTS_RIGHTALIGN'], _ [0x0010, 'DTS_APPCANPARSE'], _ [0x000C, 'DTS_SHORTDATECENTURYFORMAT'], _ [0x0009, 'DTS_TIMEFORMAT'], _ [0x0004, 'DTS_LONGDATEFORMAT'], _ [0x0002, 'DTS_SHOWNONE'], _ [0x0001, 'DTS_UPDOWN']] ; ; [0x0000, 'DTS_SHORTDATEFORMAT'] Global Const $_g__Style_Edit[13][2] = _ [[0x2000, 'ES_NUMBER'], _ [0x1000, 'ES_WANTRETURN'], _ [0x0800, 'ES_READONLY'], _ [0x0400, 'ES_OEMCONVERT'], _ [0x0100, 'ES_NOHIDESEL'], _ [0x0080, 'ES_AUTOHSCROLL'], _ [0x0040, 'ES_AUTOVSCROLL'], _ [0x0020, 'ES_PASSWORD'], _ [0x0010, 'ES_LOWERCASE'], _ [0x0008, 'ES_UPPERCASE'], _ [0x0004, 'ES_MULTILINE'], _ [0x0002, 'ES_RIGHT'], _ [0x0001, 'ES_CENTER']] Global Const $_g__Style_Header[10][2] = _ [[0x1000, 'HDS_OVERFLOW'], _ [0x0800, 'HDS_NOSIZING'], _ [0x0400, 'HDS_CHECKBOXES'], _ [0x0200, 'HDS_FLAT'], _ [0x0100, 'HDS_FILTERBAR'], _ [0x0080, 'HDS_FULLDRAG'], _ [0x0040, 'HDS_DRAGDROP'], _ [0x0008, 'HDS_HIDDEN'], _ [0x0004, 'HDS_HOTTRACK'], _ [0x0002, 'HDS_BUTTONS']] ; ; [0x0000, '$HDS_HORZ'] Global Const $_g__Style_ListBox[16][2] = _ [[0x8000, 'LBS_COMBOBOX'], _ [0x4000, 'LBS_NOSEL'], _ [0x2000, 'LBS_NODATA'], _ [0x1000, 'LBS_DISABLENOSCROLL'], _ [0x0800, 'LBS_EXTENDEDSEL'], _ [0x0400, 'LBS_WANTKEYBOARDINPUT'], _ [0x0200, 'LBS_MULTICOLUMN'], _ [0x0100, 'LBS_NOINTEGRALHEIGHT'], _ [0x0080, 'LBS_USETABSTOPS'], _ [0x0040, 'LBS_HASSTRINGS'], _ [0x0020, 'LBS_OWNERDRAWVARIABLE'], _ [0x0010, 'LBS_OWNERDRAWFIXED'], _ [0x0008, 'LBS_MULTIPLESEL'], _ [0x0004, 'LBS_NOREDRAW'], _ [0x0002, 'LBS_SORT'], _ [0x0001, 'LBS_NOTIFY']] ; ; [0xA00003, 'LBS_STANDARD'] ; i.e. (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER) help file correct, ListBoxConstants.au3 incorrect Global Const $_g__Style_ListView[17][2] = _ [[0x8000, 'LVS_NOSORTHEADER'], _ [0x4000, 'LVS_NOCOLUMNHEADER'], _ [0x2000, 'LVS_NOSCROLL'], _ [0x1000, 'LVS_OWNERDATA'], _ [0x0800, 'LVS_ALIGNLEFT'], _ [0x0400, 'LVS_OWNERDRAWFIXED'], _ [0x0200, 'LVS_EDITLABELS'], _ [0x0100, 'LVS_AUTOARRANGE'], _ [0x0080, 'LVS_NOLABELWRAP'], _ [0x0040, 'LVS_SHAREIMAGELISTS'], _ [0x0020, 'LVS_SORTDESCENDING'], _ [0x0010, 'LVS_SORTASCENDING'], _ [0x0008, 'LVS_SHOWSELALWAYS'], _ [0x0004, 'LVS_SINGLESEL'], _ [0x0003, 'LVS_LIST'], _ [0x0002, 'LVS_SMALLICON'], _ [0x0001, 'LVS_REPORT']] ; ; [0x0000, 'LVS_ICON'] ; [0x0000, 'LVS_ALIGNTOP'] Global Const $_g__Style_ListViewExtended[20][2] = _ [[0x00100000, 'LVS_EX_SIMPLESELECT'], _ [0x00080000, 'LVS_EX_SNAPTOGRID'], _ [0x00020000, 'LVS_EX_HIDELABELS'], _ [0x00010000, 'LVS_EX_DOUBLEBUFFER'], _ [0x00008000, 'LVS_EX_BORDERSELECT'], _ [0x00004000, 'LVS_EX_LABELTIP'], _ [0x00002000, 'LVS_EX_MULTIWORKAREAS'], _ [0x00001000, 'LVS_EX_UNDERLINECOLD'], _ [0x00000800, 'LVS_EX_UNDERLINEHOT'], _ [0x00000400, 'LVS_EX_INFOTIP'], _ [0x00000200, 'LVS_EX_REGIONAL'], _ [0x00000100, 'LVS_EX_FLATSB'], _ [0x00000080, 'LVS_EX_TWOCLICKACTIVATE'], _ [0x00000040, 'LVS_EX_ONECLICKACTIVATE'], _ [0x00000020, 'LVS_EX_FULLROWSELECT'], _ [0x00000010, 'LVS_EX_HEADERDRAGDROP'], _ [0x00000008, 'LVS_EX_TRACKSELECT'], _ [0x00000004, 'LVS_EX_CHECKBOXES'], _ [0x00000002, 'LVS_EX_SUBITEMIMAGES'], _ [0x00000001, 'LVS_EX_GRIDLINES']] Global Const $_g__Style_MonthCal[8][2] = _ [[0x0100, 'MCS_NOSELCHANGEONNAV'], _ [0x0080, 'MCS_SHORTDAYSOFWEEK'], _ [0x0040, 'MCS_NOTRAILINGDATES'], _ [0x0010, 'MCS_NOTODAY'], _ [0x0008, 'MCS_NOTODAYCIRCLE'], _ [0x0004, 'MCS_WEEKNUMBERS'], _ [0x0002, 'MCS_MULTISELECT'], _ [0x0001, 'MCS_DAYSTATE']] Global Const $_g__Style_Pager[3][2] = _ [[0x0004, 'PGS_DRAGNDROP'], _ [0x0002, 'PGS_AUTOSCROLL'], _ [0x0001, 'PGS_HORZ']] ; ; [0x0000, 'PGS_VERT'] Global Const $_g__Style_Progress[4][2] = _ [[0x0010, 'PBS_SMOOTHREVERSE'], _ [0x0008, 'PBS_MARQUEE'], _ [0x0004, 'PBS_VERTICAL'], _ [0x0001, 'PBS_SMOOTH']] Global Const $_g__Style_Rebar[8][2] = _ [[0x8000, 'RBS_DBLCLKTOGGLE'], _ [0x4000, 'RBS_VERTICALGRIPPER'], _ [0x2000, 'RBS_AUTOSIZE'], _ [0x1000, 'RBS_REGISTERDROP'], _ [0x0800, 'RBS_FIXEDORDER'], _ [0x0400, 'RBS_BANDBORDERS'], _ [0x0200, 'RBS_VARHEIGHT'], _ [0x0100, 'RBS_TOOLTIPS']] Global Const $_g__Style_RichEdit[8][2] = _ ; will also use plenty (not all) of Edit styles [[0x01000000, 'ES_SELECTIONBAR'], _ [0x00400000, 'ES_VERTICAL'], _ ; Asian-language support only (msdn) [0x00080000, 'ES_NOIME'], _ ; ditto [0x00040000, 'ES_SELFIME'], _ ; ditto [0x00008000, 'ES_SAVESEL'], _ [0x00004000, 'ES_SUNKEN'], _ [0x00002000, 'ES_DISABLENOSCROLL'], _ ; same value as 'ES_NUMBER' => issue ? [0x00000008, 'ES_NOOLEDRAGDROP']] ; same value as 'ES_UPPERCASE' but RichRdit controls do not support 'ES_UPPERCASE' style (msdn) Global Const $_g__Style_Scrollbar[5][2] = _ [[0x0010, 'SBS_SIZEGRIP'], _ [0x0008, 'SBS_SIZEBOX'], _ [0x0004, 'SBS_RIGHTALIGN or SBS_BOTTOMALIGN'], _ ; i.e. use SBS_RIGHTALIGN with SBS_VERT, use SBS_BOTTOMALIGN with SBS_HORZ (msdn) [0x0002, 'SBS_LEFTALIGN or SBS_TOPALIGN'], _ ; i.e. use SBS_LEFTALIGN with SBS_VERT, use SBS_TOPALIGN with SBS_HORZ (msdn) [0x0001, 'SBS_VERT']] ; ; [0x0000, 'SBS_HORZ'] Global Const $_g__Style_Slider[13][2] = _ ; i.e. trackbar [[0x1000, 'TBS_TRANSPARENTBKGND'], _ [0x0800, 'TBS_NOTIFYBEFOREMOVE'], _ [0x0400, 'TBS_DOWNISLEFT'], _ [0x0200, 'TBS_REVERSED'], _ [0x0100, 'TBS_TOOLTIPS'], _ [0x0080, 'TBS_NOTHUMB'], _ [0x0040, 'TBS_FIXEDLENGTH'], _ [0x0020, 'TBS_ENABLESELRANGE'], _ [0x0010, 'TBS_NOTICKS'], _ [0x0008, 'TBS_BOTH'], _ [0x0004, 'TBS_LEFT or TBS_TOP'], _ ; i.e. TBS_LEFT tick marks when vertical slider, or TBS_TOP tick marks when horizontal slider [0x0002, 'TBS_VERT'], _ [0x0001, 'TBS_AUTOTICKS']] ; ; [0x0000, 'TBS_RIGHT'] ; [0x0000, 'TBS_BOTTOM'] ; [0x0000, 'TBS_HORZ'] Global Const $_g__Style_Static[18][2] = _ [[0x1000, 'SS_SUNKEN'], _ [0x0400, 'SS_RIGHTJUST'], _ [0x0200, 'SS_CENTERIMAGE'], _ [0x0100, 'SS_NOTIFY'], _ [0x0080, 'SS_NOPREFIX'], _ [0x0012, 'SS_ETCHEDFRAME'], _ [0x0011, 'SS_ETCHEDVERT'], _ [0x0010, 'SS_ETCHEDHORZ'], _ [0x000C, 'SS_LEFTNOWORDWRAP'], _ [0x000B, 'SS_SIMPLE'], _ [0x0009, 'SS_WHITEFRAME'], _ [0x0008, 'SS_GRAYFRAME'], _ [0x0007, 'SS_BLACKFRAME'], _ [0x0006, 'SS_WHITERECT'], _ [0x0005, 'SS_GRAYRECT'], _ [0x0004, 'SS_BLACKRECT'], _ [0x0002, 'SS_RIGHT'], _ [0x0001, 'SS_CENTER']] ; ; [0x0000, 'SS_LEFT'] Global Const $_g__Style_StatusBar[2][2] = _ [[0x0800, 'SBARS_TOOLTIPS'], _ [0x0100, 'SBARS_SIZEGRIP']] ; ; [0x0800, 'SBT_TOOLTIPS'] Global Const $_g__Style_Tab[17][2] = _ [[0x8000, 'TCS_FOCUSNEVER'], _ [0x4000, 'TCS_TOOLTIPS'], _ [0x2000, 'TCS_OWNERDRAWFIXED'], _ [0x1000, 'TCS_FOCUSONBUTTONDOWN'], _ [0x0800, 'TCS_RAGGEDRIGHT'], _ [0x0400, 'TCS_FIXEDWIDTH'], _ [0x0200, 'TCS_MULTILINE'], _ [0x0100, 'TCS_BUTTONS'], _ [0x0080, 'TCS_VERTICAL'], _ [0x0040, 'TCS_HOTTRACK'], _ [0x0020, 'TCS_FORCELABELLEFT'], _ [0x0010, 'TCS_FORCEICONLEFT'], _ [0x0008, 'TCS_FLATBUTTONS'], _ [0x0004, 'TCS_MULTISELECT'], _ [0x0002, 'TCS_RIGHT'], _ [0x0002, 'TCS_BOTTOM'], _ [0x0001, 'TCS_SCROLLOPPOSITE']] ; ; [0x0000, 'TCS_TABS'] ; [0x0000, 'TCS_SINGLELINE'] ; [0x0000, 'TCS_RIGHTJUSTIFY'] Global Const $_g__Style_Toolbar[8][2] = _ [[0x8000, 'TBSTYLE_TRANSPARENT'], _ [0x4000, 'TBSTYLE_REGISTERDROP'], _ [0x2000, 'TBSTYLE_CUSTOMERASE'], _ [0x1000, 'TBSTYLE_LIST'], _ [0x0800, 'TBSTYLE_FLAT'], _ [0x0400, 'TBSTYLE_ALTDRAG'], _ [0x0200, 'TBSTYLE_WRAPABLE'], _ [0x0100, 'TBSTYLE_TOOLTIPS']] Global Const $_g__Style_TreeView[16][2] = _ [[0x8000, 'TVS_NOHSCROLL'], _ [0x4000, 'TVS_NONEVENHEIGHT'], _ [0x2000, 'TVS_NOSCROLL'], _ [0x1000, 'TVS_FULLROWSELECT'], _ [0x0800, 'TVS_INFOTIP'], _ [0x0400, 'TVS_SINGLEEXPAND'], _ [0x0200, 'TVS_TRACKSELECT'], _ [0x0100, 'TVS_CHECKBOXES'], _ [0x0080, 'TVS_NOTOOLTIPS'], _ [0x0040, 'TVS_RTLREADING'], _ [0x0020, 'TVS_SHOWSELALWAYS'], _ [0x0010, 'TVS_DISABLEDRAGDROP'], _ [0x0008, 'TVS_EDITLABELS'], _ [0x0004, 'TVS_LINESATROOT'], _ [0x0002, 'TVS_HASLINES'], _ [0x0001, 'TVS_HASBUTTONS']] Global Const $_g__Style_UpDown[9][2] = _ [[0x0100, 'UDS_HOTTRACK'], _ [0x0080, 'UDS_NOTHOUSANDS'], _ [0x0040, 'UDS_HORZ'], _ [0x0020, 'UDS_ARROWKEYS'], _ [0x0010, 'UDS_AUTOBUDDY'], _ [0x0008, 'UDS_ALIGNLEFT'], _ [0x0004, 'UDS_ALIGNRIGHT'], _ [0x0002, 'UDS_SETBUDDYINT'], _ [0x0001, 'UDS_WRAP']] #EndRegion ; GUIStyles.inc.au3 ; =============================================================================================================================== ; #CONSTANTS# =================================================================================================================== ;Global Const $DWMWA_USE_IMMERSIVE_DARK_MODE = (@OSBuild <= 18985) ? 19 : 20 ; before this build set to 19, otherwise set to 20, no thanks Windaube to document anything ?? ; _WinAPI_GetIsImmersiveColorUsingHighContrast($IMMERSIVE_HC_CACHE_MODE) Global Const $IHCM_USE_CACHED_VALUE = 0 Global Const $IIHCM_REFRESH = 1 ; _WinAPI_SetPreferredAppMode($PREFERREDAPPMODE) Global Const $APPMODE_DEFAULT = 0 Global Const $APPMODE_ALLOWDARK = 1 Global Const $APPMODE_FORCEDARK = 2 Global Const $APPMODE_FORCELIGHT = 3 Global Const $APPMODE_MAX = 4 OnAutoItExitRegister(_CleanExit) Func _CleanExit() If $g_hDateOldProc Then __WinAPI_SetWindowLong($g_hDate, $GWL_WNDPROC, $g_hDateOldProc) If $g_hDateProc_CB Then DllCallbackFree($g_hDateProc_CB) If $g_hBrushEdit Then __WinAPI_DeleteObject($g_hBrushEdit) If $g__ListView_wProcOld Then __WinAPI_SetWindowLong($hWndListView, $GWL_WNDPROC, $g__ListView_wProcOld) If $g__ListView_wProcNew Then DllCallbackFree($g__ListView_wProcNew) ; Restore the original window procedure for the tab control If $g_hProc Then __WinAPI_SetWindowLong($g_hTab, $GWL_WNDPROC, $g_hProc) If $g_hTab_CB Then DllCallbackFree($g_hTab_CB) EndFunc ; =============================================================================================================================== #EndRegion Global Variables and Constants #Region API Functions ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_ShouldAppsUseDarkMode ; Description ...: Checks if apps should use the dark mode. ; Syntax ........: _WinAPI_ShouldAppsUseDarkMode() ; Parameters ....: None ; Return values .: Success: Returns True if apps should use dark mode. ; Failure: Returns False and sets @error: ; -1: Operating system version is earlier than Windows 10 (version 1809, build 17763). ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: Requires Windows 10 (version 1809, build 17763) or later. ; Related .......: ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_ShouldAppsUseDarkMode() If @OSBuild < 17763 Then Return SetError(-1, 0, False) Local $fnShouldAppsUseDarkMode = 132 Local $aResult = DllCall($hUxthemeDll, 'bool', $fnShouldAppsUseDarkMode) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc ;==>_WinAPI_ShouldAppsUseDarkMode ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_AllowDarkModeForWindow ; Description ...: Allows or disallows dark mode for a specific window handle. ; Syntax ........: _WinAPI_AllowDarkModeForWindow($hWnd, $bAllow = True) ; Parameters ....: $hWnd - Handle to the window. ; $bAllow - [optional] If True, allows dark mode; if False, disallows dark mode. Default is True. ; Return values .: Success: Returns True if the operation succeeded. ; Failure: Returns False and sets @error: ; -1: Operating system version is earlier than Windows 10 (version 1809, build 17763). ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: Requires Windows 10 (version 1809, build 17763) or later. ; Related .......: ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_AllowDarkModeForWindow($hWnd, $bAllow = True) If @OSBuild < 17763 Then Return SetError(-1, 0, False) Local $fnAllowDarkModeForWindow = 133 Local $aResult = DllCall($hUxthemeDll, 'bool', $fnAllowDarkModeForWindow, 'hwnd', $hWnd, 'bool', $bAllow) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc ;==>_WinAPI_AllowDarkModeForWindow ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_AllowDarkModeForApp ; Description ...: Allows or disallows dark mode for the entire application. ; Syntax ........: _WinAPI_AllowDarkModeForApp($bAllow = True) ; Parameters ....: $bAllow - [optional] If True, allows dark mode for the application; if False, disallows dark mode. Default is True. ; Return values .: Success: Returns True if the operation succeeded. ; Failure: Returns False and sets @error: ; -1: Operating system version is earlier than Windows 10 (version 1809, build 17763). ; -2: Operating system version is later than or equal to Windows 10 (version 1903, build 18362). (Use _WinAPI_SetPreferredAppMode instat!) ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: Requires Windows 10 (version 1809, build 17763) and earlier than Windows 10 (version 1903, build 18362). ; Related .......: _WinAPI_SetPreferredAppMode ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_AllowDarkModeForApp($bAllow = True) If @OSBuild < 17763 Then Return SetError(-1, 0, False) If @OSBuild >= 18362 Then Return SetError(-2, 0, False) Local $fnAllowDarkModeForApp = 135 Local $aResult = DllCall($hUxthemeDll, 'bool', $fnAllowDarkModeForApp, 'bool', $bAllow) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc ;==>_WinAPI_AllowDarkModeForApp ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_FlushMenuThemes ; Description ...: Refreshes the system's immersive color policy state, allowing changes to take effect. ; Syntax ........: _WinAPI_FlushMenuThemes() ; Parameters ....: None ; Return values .: Success: True ; Failure: False and sets the @error flag: ; -1: Operating system version is earlier than Windows 10 (version 17763) ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: This function is applicable for Windows 10 (version 17763) and later. ; Related .......: ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_FlushMenuThemes() If @OSBuild < 17763 Then Return SetError(-1, 0, False) Local $fnFlushMenuThemes = 136 DllCall($hUxthemeDll, 'none', $fnFlushMenuThemes) If @error Then Return SetError(@error, @extended, False) Return True EndFunc ;==>_WinAPI_FlushMenuThemes ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_RefreshImmersiveColorPolicyState ; Description ...: Refreshes the system's immersive color policy state, allowing changes to take effect. ; Syntax ........: _WinAPI_RefreshImmersiveColorPolicyState() ; Parameters ....: None ; Return values .: Success: True ; Failure: False and sets the @error flag: ; -1: Operating system version is earlier than Windows 10 (version 17763) ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: This function is applicable for Windows 10 (version 17763) and later. ; Related .......: ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_RefreshImmersiveColorPolicyState() If @OSBuild < 17763 Then Return SetError(-1, 0, False) Local $fnRefreshImmersiveColorPolicyState = 104 DllCall($hUxthemeDll, 'none', $fnRefreshImmersiveColorPolicyState) If @error Then Return SetError(@error, @extended, False) Return True EndFunc ;==>_WinAPI_RefreshImmersiveColorPolicyState ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_IsDarkModeAllowedForWindow ; Description ...: Checks if the dark mode is allowed for the specified window. ; Syntax ........: _WinAPI_IsDarkModeAllowedForWindow() ; Parameters ....: None ; Return values .: Success: True if dark mode is allowed for the window, False otherwise. ; Failure: False and sets the @error flag: ; -1: Operating system version is earlier than Windows 10 (version 17763) ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: This function is applicable for Windows 10 (version 17763) and later. ; Related .......: ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_IsDarkModeAllowedForWindow() If @OSBuild < 17763 Then Return SetError(-1, 0, False) Local $fnIsDarkModeAllowedForWindow = 137 Local $aResult = DllCall($hUxthemeDll, 'bool', $fnIsDarkModeAllowedForWindow) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc ;==>_WinAPI_IsDarkModeAllowedForWindow ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_GetIsImmersiveColorUsingHighContrast ; Description ...: Retrieves whether immersive color is using high contrast. ; Syntax ........: _WinAPI_GetIsImmersiveColorUsingHighContrast($IMMERSIVE_HC_CACHE_MODE) ; Parameters ....: $IMMERSIVE_HC_CACHE_MODE - The cache mode. Use one of the following values: ; $IHCM_USE_CACHED_VALUE (0) - Use the cached value. (Default) ; $IHCM_REFRESH (1) - Refresh the value. ; Return values .: Success: True if immersive color is using high contrast. ; Failure: False and sets the @error flag: ; -1: Operating system version is earlier than Windows 10 (version 17763) ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: This function is applicable for Windows 10 (version 17763) and later. ; Related .......: ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_GetIsImmersiveColorUsingHighContrast($IMMERSIVE_HC_CACHE_MODE = $IHCM_USE_CACHED_VALUE) If @OSBuild < 17763 Then Return SetError(-1, 0, False) Local $fnGetIsImmersiveColorUsingHighContrast = 106 Local $aResult = DllCall($hUxthemeDll, 'bool', $fnGetIsImmersiveColorUsingHighContrast, 'int', $IMMERSIVE_HC_CACHE_MODE) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc ;==>_WinAPI_GetIsImmersiveColorUsingHighContrast ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_OpenNcThemeData ; Description ...: Opens the theme data for a window. ; Syntax ........: _WinAPI_OpenNcThemeData($hWnd, $pClassList) ; Parameters ....: $hWnd - Handle to the window. ; $sClassList - String that contains a semicolon-separated list of classes. ; Return values .: Success: A handle to the theme data. ; Failure: 0 and sets the @error flag: ; -1: Operating system version is earlier than Windows 10 (version 17763) ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://github.com/ysc3839/win32-darkmode/blob/master/win32-darkmode/DarkMode.h#L69 ; Example .......: No ; =============================================================================================================================== Func _WinAPI_OpenNcThemeData($hWnd, $sClassList) If @OSBuild < 17763 Then Return SetError(-1, 0, False) Local $fnOpenNcThemeData = 49 Local $aResult = DllCall($hUxthemeDll, 'hwnd', $fnOpenNcThemeData, 'hwnd', $hWnd, 'wstr', $sClassList) If @error Then Return SetError(@error, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_OpenNcThemeData ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_ShouldSystemUseDarkMode ; Description ...: Checks if system should use the dark mode. ; Syntax ........: _WinAPI_ShouldSystemUseDarkMode() ; Parameters ....: None ; Return values .: Success: Returns True if system should use dark mode. ; Failure: Returns False and sets @error: ; -1: Operating system version is earlier than Windows 10 (version 1903, build 18362). ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: Requires Windows 10 (version 1903, build 18362) or later. ; Related .......: ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_ShouldSystemUseDarkMode() If @OSBuild < 18362 Then Return SetError(-1, 0, False) Local $fnShouldSystemUseDarkMode = 138 Local $aResult = DllCall($hUxthemeDll, 'bool', $fnShouldSystemUseDarkMode) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc ;==>_WinAPI_ShouldSystemUseDarkMode ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_SetPreferredAppMode ; Description ...: Sets the preferred application mode for Windows 10 (version 1903, build 18362) and later. ; Syntax ........: _WinAPI_SetPreferredAppMode($PREFERREDAPPMODE) ; Parameters ....: $PREFERREDAPPMODE - The preferred application mode. See enum PreferredAppMode for possible values. ; $APPMODE_DEFAULT (0) ; $APPMODE_ALLOWDARK (1) ; $APPMODE_FORCEDARK (2) ; $APPMODE_FORCELIGHT (3) ; $APPMODE_MAX (4) ; Return values .: Success: The PreferredAppMode retuned by the DllCall ; Failure: '' and sets the @error flag: ; -1: Operating system version is earlier than Windows 10 (version 18362) ; Other values: DllCall error, check @error @extended for more information. ; Author ........: NoNameCode ; Modified ......: ; Remarks .......: This function is applicable for Windows 10 (version 18362) and later. ; Related .......: _WinAPI_AllowDarkModeForApp ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: No ; =============================================================================================================================== Func _WinAPI_SetPreferredAppMode($PREFERREDAPPMODE) If @OSBuild < 18362 Then Return SetError(-1, 0, False) Local $fnSetPreferredAppMode = 135 Local $aResult = DllCall($hUxthemeDll, 'int', $fnSetPreferredAppMode, 'int', $PREFERREDAPPMODE) If @error Then Return SetError(@error, @extended, '') Return $aResult[0] EndFunc ;==>_WinAPI_SetPreferredAppMode Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") Local $ret = DllCall($hUser32Dll, "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 #EndRegion API Functions #Region Internal Functions ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_DwmSetWindowAttribute_unr ; Description ...: Dose the same as _WinAPI_DwmSetWindowAttribute; But has no Restrictions ; Syntax ........: _WinAPI_DwmSetWindowAttribute_unr($hWnd, $iAttribute, $iData) ; Parameters ....: $hWnd - a handle value. ; $iAttribute - an integer value. ; $iData - an integer value. ; Return values .: Success: 1 Failure: @error, @extended & False ; Author ........: argumentum ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://www.autoitscript.com/forum/topic/211475-winapithemeex-darkmode-for-autoits-win32guis/?do=findComment&comment=1530103 ; Example .......: No ; =============================================================================================================================== Func _WinAPI_DwmSetWindowAttribute_unr($hWnd, $iAttribute, $iData) ; #include <WinAPIGdi.au3> ; unthoughtful unrestricting mod. Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $iAttribute, _ 'dword*', $iData, 'dword', 4) If @error Then Return SetError(@error, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttribute_unr #EndRegion Internal Functions #cs 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 #ce Func _WM_CTLCOLOR($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local $hDC = $wParam Local $hCtrl = $lParam Switch __WinAPI_GetClassName($hCtrl) Case 'Static' ; 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 EndSwitch ; --- Default behavior for all other statics / controls --- __WinAPI_SetTextColor($hDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) Local $hBrush = $g_hBrushEdit _WinAPI_SetBkColor($hDC, _ColorToCOLORREF($COLOR_CONTROL_BG)) __WinAPI_SetBkMode($hDC, $TRANSPARENT) Return $hBrush EndFunc ;==>_WM_CTLCOLOR 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($hUser32Dll, "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 but exclude overlapping GUI controls from painting Local $hParent = __WinAPI_GetParent($hWnd) Local $hChild = __WinAPI_GetWindow($hParent, $GW_CHILD) Local $tCR, $tPR = __WinAPI_GetWindowRect($hWnd) Local $left, $top, $right, $bottom While $hChild If $hChild <> $hWnd And __WinAPI_IsWindowVisible($hChild) Then $tCR = __WinAPI_GetWindowRect($hChild) ; Only exclude controls that lie fully within the tab control area If $tCR.left >= $tPR.left And $tCR.right <= $tPR.right And $tCR.top >= $tPR.top And $tCR.bottom <= $tPR.bottom Then $left = $tCR.left - $tPR.left $top = $tCR.top - $tPR.top $right = $tCR.right - $tPR.left $bottom = $tCR.bottom - $tPR.top ; Exclude from offscreen bitmap (prevents black fill) DllCall($hGdi32Dll, "int", "ExcludeClipRect", "handle", $hMemDC, "int", $left, "int", $top, "int", $right, "int", $bottom) ; Exclude from screen DC (prevents BitBlt overwrite) DllCall($hGdi32Dll, "int", "ExcludeClipRect", "handle", $hDC, "int", $left, "int", $top, "int", $right, "int", $bottom) EndIf EndIf $hChild = __WinAPI_GetWindow($hChild, $GW_HWNDNEXT) WEnd ; Fill background Local $hBrush = __WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_CONTROL_BG)) __WinAPI_FillRect($hMemDC, $tClient, $hBrush) __WinAPI_DeleteObject($hBrush) ; Get tab info Local $iTabCount = __SendMessage($hWnd, $TCM_GETITEMCOUNT, 0, 0) Local $iCurSel = __SendMessage($hWnd, $TCM_GETCURSEL, 0, 0) ; 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, $iLeft, $iTop, $iRight, $iBottom, $tItem, $tText, $bSelected, $iTabColor, $hTabBrush, $tTabRect, _ $sText, $hPen, $hOldPen, $hPenSep,$hOldPenSep, $tTextRect, $hBorderPen, $hOldBorderPen, $hNullBrush, $hOldBorderBrush For $i = 0 To $iTabCount - 1 ; Get tab rectangle using TCM_GETITEMRECT $tRect = DllStructCreate($tagRECT) Local $aResult = DllCall($hUser32Dll, "lresult", "SendMessageW", _ "hwnd", $hWnd, _ "uint", $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 $tItem = DllStructCreate("uint Mask;dword dwState;dword dwStateMask;ptr pszText;int cchTextMax;int iImage;lparam lParam") $tText = DllStructCreate("wchar Text[256]") With $tItem .Mask = 0x0001 ; TCIF_TEXT .pszText = DllStructGetPtr($tText) .cchTextMax = 256 EndWith DllCall($hUser32Dll, "lresult", "SendMessageW", _ "hwnd", $hWnd, _ "uint", $TCM_GETITEMW, _ "wparam", $i, _ "struct*", $tItem) $sText = DllStructGetData($tText, "Text") ; Draw tab background $bSelected = ($i = $iCurSel) $iTabColor = $bSelected ? __WinAPI_ColorAdjustLuma($COLOR_CONTROL_BG, 20) : __WinAPI_ColorAdjustLuma($COLOR_CONTROL_BG, 10) $hTabBrush = __WinAPI_CreateSolidBrush($iTabColor) $tTabRect = DllStructCreate($tagRECT) With $tTabRect .Left = $iLeft .Top = $iTop .Right = $iRight .Bottom = $iBottom EndWith __WinAPI_FillRect($hMemDC, $tTabRect, $hTabBrush) __WinAPI_DeleteObject($hTabBrush) ; Draw selection indicator (top border for selected tab) If $bSelected Then $hPen = __WinAPI_CreatePen(0, 2, _ColorToCOLORREF(0x0078D4)) ; Blue accent $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 $hPenSep = __WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) $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 $tTextRect = DllStructCreate($tagRECT) With $tTextRect .Left = $iLeft + 6 .Top = $iTop + 3 .Right = $iRight - 6 .Bottom = $iBottom - 3 EndWith DllCall($hUser32Dll, "int", "DrawTextW", _ "handle", $hMemDC, _ "wstr", $sText, _ "int", -1, _ "struct*", $tTextRect, _ "uint", BitOR($DT_CENTER, $DT_VCENTER, $DT_SINGLELINE)) Next ; Draw border around entire control $hBorderPen = __WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) $hOldBorderPen = __WinAPI_SelectObject($hMemDC, $hBorderPen) $hNullBrush = __WinAPI_GetStockObject(5) ; NULL_BRUSH $hOldBorderBrush = __WinAPI_SelectObject($hMemDC, $hNullBrush) DllCall($hGdi32Dll, "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 _LVWndProc($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam If $iMsg = $WM_NOTIFY Then Local $tNMHDR, $hWndFrom, $iCode, $hDC $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListViewHeader Switch $iCode Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Switch DllStructGetData($tCustDraw, "dwDrawStage") Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT $hDC = DllStructGetData($tCustDraw, "hDC") DllCall($hGdi32Dll, "int", "SetTextColor", "handle", $hDC, "dword", __WinAPI_SwitchColor($COLOR_TEXT_LIGHT)) Return $CDRF_NEWFONT Return $CDRF_SKIPDEFAULT EndSwitch EndSwitch EndSwitch EndIf ;pass the unhandled messages to default WindowProc Local $aResult = DllCall($hUser32Dll, "lresult", "CallWindowProcW", "ptr", $g__ListView_wProcOld, _ "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam) If @error Then Return -1 Return $aResult[0] EndFunc ;==>_LVWndProc #Region WM_NOTIFY Func _DateProc($hWnd, $iMsg, $wParam, $lParam) Local $iRet Switch $iMsg Case $WM_PAINT Local $tPaint = DllStructCreate($tagPAINTSTRUCT) Local $hDC = __WinAPI_BeginPaint($hWnd, $tPaint) Local $tClient = __WinAPI_GetClientRect($hWnd) Local $iW = $tClient.Right Local $iH = $tClient.Bottom ; --- Memory DC for flicker-free rendering --- Local $hMemDC = __WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = __WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local $hOldBmp = __WinAPI_SelectObject($hMemDC, $hBitmap) ; 1. Let Windows draw the light-mode control into memory DC __WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $WM_PRINTCLIENT, $hMemDC, $PRF_CLIENT) ; 2. Invert all pixels (background becomes black, text white, selection orange) Local $tRect = DllStructCreate($tagRECT) $tRect.right = $iW $tRect.bottom = $iH __WinAPI_InvertRect($hMemDC, $tRect) ; --- 3. PIXEL HACK: destroy orange highlight & set background color --- Local $iSize = $iW * $iH Local $tPixels = DllStructCreate("dword c[" & $iSize & "]") ; Load pixel array directly from bitmap memory Local $iBytes = DllCall($hGdi32Dll, "long", "GetBitmapBits", "handle", $hBitmap, "long", $iSize * 4, "ptr", DllStructGetPtr($tPixels))[0] If $iBytes = $iSize * 4 Then Local $iPixel, $r, $g, $b, $iGray For $i = 1 To $iSize $iPixel = $tPixels.c(($i)) ; Split into color channels $b = BitAND($iPixel, 0xFF) $g = BitAND(BitShift($iPixel, 8), 0xFF) $r = BitAND(BitShift($iPixel, 16), 0xFF) ; Convert to grayscale (orange becomes mid-gray) $iGray = Int(($r + $g + $b) / 3) ; Very dark pixel = inverted white background If $iGray < 15 Then $iPixel = $DTP_BG_DARK ; Replace with exact GUI background color Else ; Grayscale value for text (white) and selection (gray) ; (negative BitShift shifts left in AutoIt) $iPixel = BitOR(BitShift($iGray, -16), BitShift($iGray, -8), $iGray) EndIf $tPixels.c(($i)) = $iPixel Next ; Write cleaned pixels back into the bitmap DllCall($hGdi32Dll, "long", "SetBitmapBits", "handle", $hBitmap, "long", $iSize * 4, "ptr", DllStructGetPtr($tPixels)) EndIf ; --- END PIXEL HACK --- ; --- Border color (hover effect) --- Local $iBorderColor = $DTP_BORDER If __WinAPI_GetFocus() = $hWnd Then $iBorderColor = $DTP_BORDER Local $tCursorPos = DllStructCreate($tagPOINT) DllCall($hUser32Dll, "bool", "GetCursorPos", "struct*", $tCursorPos) DllCall($hUser32Dll, "bool", "ScreenToClient", "hwnd", $hWnd, "struct*", $tCursorPos) If $tCursorPos.X >= 0 And $tCursorPos.X <= $iW And $tCursorPos.Y >= 0 And $tCursorPos.Y <= $iH Then $iBorderColor = $DTP_BORDER_LIGHT EndIf ; --- Draw border --- Local $hPen = __WinAPI_CreatePen(0, 1, _ColorToCOLORREF($iBorderColor)) Local $hNullBr = __WinAPI_GetStockObject(5) Local $hOldPen = __WinAPI_SelectObject($hMemDC, $hPen) Local $hOldBr = __WinAPI_SelectObject($hMemDC, $hNullBr) DllCall($hGdi32Dll, "bool", "Rectangle", "handle", $hMemDC, "int", 0, "int", 0, "int", $iW, "int", $iH) __WinAPI_SelectObject($hMemDC, $hOldPen) __WinAPI_SelectObject($hMemDC, $hOldBr) __WinAPI_DeleteObject($hPen) ; --- Copy finished result to screen in one step (no flicker) --- __WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hMemDC, 0, 0, $SRCCOPY) ; --- Cleanup --- __WinAPI_SelectObject($hMemDC, $hOldBmp) __WinAPI_DeleteObject($hBitmap) __WinAPI_DeleteDC($hMemDC) __WinAPI_EndPaint($hWnd, $tPaint) Return 0 Case $WM_ERASEBKGND Return 1 Case $WM_SETFOCUS, $WM_KILLFOCUS, $WM_LBUTTONDOWN, $WM_LBUTTONUP $iRet = __WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) __WinAPI_InvalidateRect($hWnd, 0, False) Return $iRet Case $WM_MOUSEMOVE $iRet = __WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) If Not $g_bHover Then $g_bHover = True __WinAPI_InvalidateRect($hWnd, 0, False) EndIf Return $iRet Case $WM_MOUSELEAVE $g_bHover = False __WinAPI_InvalidateRect($hWnd, 0, False) EndSwitch Return __WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_DateProc Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local Static $iTheme ; argumentum Local $hWndFrom, $iCode, $tNMHDR, $iCtrl $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd($tNMHDR.hWndFrom) $iCode = $tNMHDR.Code ; --- Slider (msctls_trackbar32) custom drawing --- If $iCode = $NM_CUSTOMDRAW And StringLower(__WinAPI_GetClassName($hWndFrom)) = "msctls_trackbar32" Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAW, $lParam) Local $dwStage = $tNMCD.dwDrawStage Local $hDC = $tNMCD.hdc Local $dwItemSpec = $tNMCD.dwItemSpec Switch $dwStage Case $CDDS_PREPAINT ; Remove focus rectangle from slider DllStructSetData($tNMCD, 'ItemState', BitXOR(DllStructGetData($tNMCD, 'ItemState'), $CDIS_FOCUS)) Return $CDRF_NOTIFYITEMDRAW ; request per-item notifications Case $CDDS_ITEMPREPAINT Local Const $TBCD_TICS = 0x0001 ; tick marks Local Const $TBCD_THUMB = 0x0002 ; draggable thumb Local Const $TBCD_CHANNEL = 0x0003 ; slider channel/track Local $tRect = DllStructCreate($tagRECT) $tRect.left = $tNMCD.left $tRect.top = $tNMCD.top $tRect.right = $tNMCD.right $tRect.bottom = $tNMCD.bottom Switch $dwItemSpec Case $TBCD_TICS ; Let Windows draw tick marks normally Return $CDRF_DODEFAULT Case $TBCD_THUMB ; Draw thumb as a pentagon (rectangle + downward arrow) Local $iL = $tNMCD.left Local $iT = $tNMCD.top Local $iR = $tNMCD.right - 1 ; -1 to stay within bounds and avoid paint artifacts Local $iB = $tNMCD.bottom Local $iMid = ($iL + $iR) / 2 ; horizontal center (tip of arrow) Local $iSplit = $iB - ($iR - $iL) / 2 ; y-position where rectangle ends and arrow begins ; Pentagon points: top-left, top-right, right-middle, bottom-tip, left-middle Local $tPoints = DllStructCreate("int p[10]") $tPoints.p((1)) = $iL $tPoints.p((2)) = $iT $tPoints.p((3)) = $iR $tPoints.p((4)) = $iT $tPoints.p((5)) = $iR $tPoints.p((6)) = $iSplit $tPoints.p((7)) = $iMid $tPoints.p((8)) = $iB $tPoints.p((9)) = $iL $tPoints.p((10)) = $iSplit ; Fill and outline thumb with blue accent color Local $hBrush = __WinAPI_CreateSolidBrush(_ColorToCOLORREF(0x0078D4)) Local $hPen = __WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_CONTROL_BG)) Local $hOldBrush = __WinAPI_SelectObject($hDC, $hBrush) Local $hOldPen = __WinAPI_SelectObject($hDC, $hPen) DllCall($hGdi32Dll, "bool", "Polygon", "handle", $hDC, "struct*", $tPoints, "int", 5) __WinAPI_SelectObject($hDC, $hOldBrush) __WinAPI_SelectObject($hDC, $hOldPen) __WinAPI_DeleteObject($hBrush) __WinAPI_DeleteObject($hPen) Return $CDRF_SKIPDEFAULT ; skip default drawing Case $TBCD_CHANNEL ; Fill channel with border color Local $hBrushChan = __WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BORDER)) __WinAPI_FillRect($hDC, $tRect, $hBrushChan) __WinAPI_DeleteObject($hBrushChan) Return $CDRF_SKIPDEFAULT ; skip default drawing EndSwitch EndSwitch EndIf ; --- Per-control notification handling --- Switch $hWndFrom Case $g_hDate ;thanks to argumentum for the code :-) Switch $iCode Case $NM_SETFOCUS $iTheme = __WinAPI_GetThemeAppProperties() ; argumentum ; Disable the visual theme when the DateTime control receives focus __WinAPI_SetThemeAppProperties(0) Case $DTN_DROPDOWN;, $EVENT_OBJECT_CREATE ; Apply dark colors when the calendar dropdown appears $iCtrl = _GUICtrlDTP_GetMonthCal($hWndFrom) __WinAPI_SetWindowTheme($iCtrl, "", "") _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TEXT, $COLOR_TEXT_LIGHT) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TITLEBK, $COLOR_CONTROL_BG) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TITLETEXT, $COLOR_TEXT_LIGHT) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_BACKGROUND, $COLOR_CONTROL_BG) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_MONTHBK, $COLOR_CONTROL_BG) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TRAILINGTEXT, $COLOR_TEXT_LIGHT) Case $DTN_CLOSEUP ; Reset visual theme __WinAPI_SetThemeAppProperties($iTheme) ; argumentum ; Calendar will closed EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_NOTIFY #EndRegion WM_NOTIFY Func hWnd2Styles($hWnd) Return _GetCtrlStyleString(__WinAPI_GetWindowLong($hWnd, $GWL_STYLE), __WinAPI_GetWindowLong($hWnd, $GWL_EXSTYLE), __WinAPI_GetClassName($hWnd)) EndFunc Func _GetStyleString($iStyle, $fExStyle) ConsoleWrite('+ Func _GetStyleString(' & $iStyle & ', ' & $fExStyle & ')' & @CRLF) Local $Text = '', $Data = $fExStyle ? $_g__Style_GuiExtended : $_g__Style_Gui For $i = 0 To UBound($Data) - 1 If BitAND($iStyle, $Data[$i][0]) = $Data[$i][0] Then $iStyle = BitAND($iStyle, BitNOT($Data[$i][0])) If StringLeft($Data[$i][1], 1) <> "!" Then $Text &= $Data[$i][1] & ', ' Else ; ex. '! WS_MINIMIZEBOX ! WS_GROUP' => 'WS_MINIMIZEBOX, ' $Text &= StringMid($Data[$i][1], 3, StringInStr($Data[$i][1], "!", 2, 2) - 4) & ', ' EndIf EndIf Next If $iStyle Then $Text = '0x' & Hex($iStyle, 8) & ', ' & $Text Return StringRegExpReplace($Text, ',\s\z', '') EndFunc ;==>_GetStyleString Func _GetCtrlStyleString($iStyle, $fExStyle, $sClass, $iLVExStyle = 0) If $sClass = "AutoIt v3 GUI" Or $sClass = "#32770" Or $sClass = "MDIClient" Then ; control = child GUI, dialog box (msgbox) etc... Return _GetStyleString($iStyle, 0) EndIf If StringLeft($sClass, 8) = "RichEdit" Then $sClass = "RichEdit" ; RichEdit, RichEdit20A, RichEdit20W, RichEdit50A, RichEdit50W Local $Text = '' _GetCtrlStyleString2($iStyle, $Text, $sClass, $iLVExStyle) ; 4th param. in case $sClass = "Ex_SysListView32" (special treatment) If $sClass = "ReBarWindow32" Or $sClass = "ToolbarWindow32" Or $sClass = "msctls_statusbar32" Then $sClass = "Common" ; "for rebar controls, toolbar controls, and status windows" (msdn) _GetCtrlStyleString2($iStyle, $Text, $sClass) ElseIf $sClass = "RichEdit" Then $sClass = "Edit" ; "Richedit controls also support many edit control styles (not all)" (msdn) _GetCtrlStyleString2($iStyle, $Text, $sClass) EndIf Local $Data = $fExStyle ? $_g__Style_GuiExtended : $_g__Style_Gui For $i = 0 To UBound($Data) - 1 If BitAND($iStyle, $Data[$i][0]) = $Data[$i][0] Then If (Not BitAND($Data[$i][0], 0xFFFF)) Or ($fExStyle) Then $iStyle = BitAND($iStyle, BitNOT($Data[$i][0])) If StringLeft($Data[$i][1], 1) <> "!" Then $Text &= $Data[$i][1] & ', ' Else ; ex. '! WS_MINIMIZEBOX ! WS_GROUP' => 'WS_GROUP, ' $Text &= StringMid($Data[$i][1], StringInStr($Data[$i][1], "!", 2, 2) + 2) & ', ' EndIf EndIf EndIf Next If $iStyle Then $Text = '0x' & Hex($iStyle, 8) & ', ' & $Text Return StringRegExpReplace($Text, ',\s\z', '') EndFunc ;==>_GetCtrlStyleString ;===================================================================== Func _GetCtrlStyleString2(ByRef $iStyle, ByRef $Text, $sClass, $iLVExStyle = 0) Local $Data Switch $sClass ; $Input[16] Case "Button" $Data = $_g__Style_Button Case "ComboBox", "ComboBoxEx32" $Data = $_g__Style_Combo Case "Common" $Data = $_g__Style_Common ; "for rebar controls, toolbar controls, and status windows (msdn)" Case "Edit" $Data = $_g__Style_Edit Case "ListBox" $Data = $_g__Style_ListBox Case "msctls_progress32" $Data = $_g__Style_Progress Case "msctls_statusbar32" $Data = $_g__Style_StatusBar Case "msctls_trackbar32" $Data = $_g__Style_Slider Case "msctls_updown32" $Data = $_g__Style_UpDown Case "ReBarWindow32" $Data = $_g__Style_Rebar Case "RichEdit" $Data = $_g__Style_RichEdit Case "Scrollbar" $Data = $_g__Style_Scrollbar Case "Static" $Data = $_g__Style_Static Case "SysAnimate32" $Data = $_g__Style_Avi Case "SysDateTimePick32" $Data = $_g__Style_DateTime Case "SysHeader32" $Data = $_g__Style_Header Case "SysListView32" $Data = $_g__Style_ListView Case "Ex_SysListView32" ; special treatment below $Data = $_g__Style_ListViewExtended Case "SysMonthCal32" $Data = $_g__Style_MonthCal Case "SysPager" $Data = $_g__Style_Pager Case "SysTabControl32", "SciTeTabCtrl" $Data = $_g__Style_Tab Case "SysTreeView32" $Data = $_g__Style_TreeView Case "ToolbarWindow32" $Data = $_g__Style_Toolbar Case Else Return EndSwitch If $sClass <> "Ex_SysListView32" Then For $i = 0 To UBound($Data) - 1 If BitAND($iStyle, $Data[$i][0]) = $Data[$i][0] Then $iStyle = BitAND($iStyle, BitNOT($Data[$i][0])) $Text = $Data[$i][1] & ', ' & $Text EndIf Next Else For $i = 0 To UBound($Data) - 1 If BitAND($iLVExStyle, $Data[$i][0]) = $Data[$i][0] Then $iLVExStyle = BitAND($iLVExStyle, BitNOT($Data[$i][0])) $Text = $Data[$i][1] & ', ' & $Text If BitAND($iStyle, $Data[$i][0]) = $Data[$i][0] Then $iStyle = BitAND($iStyle, BitNOT($Data[$i][0])) EndIf EndIf Next If $iLVExStyle Then $Text = 'LVex: 0x' & Hex($iLVExStyle, 8) & ', ' & $Text ; next test bc LVS_EX_FULLROWSELECT (default AutoIt LV ext style) and WS_EX_TRANSPARENT got both same value 0x20 (hard to solve in some cases) If BitAND($iStyle, $WS_EX_TRANSPARENT) = $WS_EX_TRANSPARENT Then ; note that $WS_EX_TRANSPARENT has nothing to do with listview $iStyle = BitAND($iStyle, BitNOT($WS_EX_TRANSPARENT)) EndIf EndIf EndFunc ;==>_GetCtrlStyleString2 #Region Public Functions ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUISetDarkTheme ; Description ...: Sets the theme for a specified window to either dark or light mode on Windows 10. ; Syntax ........: _GUISetDarkTheme($hwnd, $dark_theme = True) ; Parameters ....: $hwnd - The handle to the window. ; $dark_theme - If True, sets the dark theme; if False, sets the light theme. ; (Default is True for dark theme.) ; Return values .: None ; Author ........: DK12000, NoNameCode ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://www.autoitscript.com/forum/topic/211196-gui-title-bar-dark-theme-an-elegant-solution-using-dwmapi/ ; Example .......: No ; =============================================================================================================================== Func _GUISetDarkTheme($hWnd, $bEnableDarkTheme = True) Local $iPreferredAppMode = ($bEnableDarkTheme == True) ? $APPMODE_FORCEDARK : $APPMODE_FORCELIGHT Local $iGUI_BkColor = ($bEnableDarkTheme == True) ? $COLOR_BG_DARK : _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_3DFACE)) _WinAPI_SetPreferredAppMode($iPreferredAppMode) _WinAPI_RefreshImmersiveColorPolicyState() _WinAPI_FlushMenuThemes() GUISetBkColor($iGUI_BkColor, $hWnd) _GUICtrlSetDarkTheme($hWnd, $bEnableDarkTheme) ;To Color the GUI's own Scrollbar _WinAPI_DwmSetWindowAttribute_unr($hWnd, $DWMWA_USE_IMMERSIVE_DARK_MODE, $bEnableDarkTheme) EndFunc ;==>_GUISetDarkTheme ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlAllSetDarkTheme ; Description ...: Sets the dark theme to all existing sub Controls from a GUI ; Syntax ........: _GUICtrlAllSetDarkTheme($hGUI[, $bEnableDarkTheme = True, $bPreferNewTheme = False]) ; Parameters ....: $hGUI - GUI handle ; $bEnableDarkTheme - [optional] a boolean value. Default is True. ; $bPreferNewTheme - Prefer the newer DarkMode_DarkTheme theme over DarkMode_Explorer when possible. ; (Default is False. DarkMode_DarkTheme is only available on Win11 26100.6899 and higher) ; Return values .: None ; Author ........: NoName ; Modified ......: WildByDesign ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _GUICtrlAllSetDarkTheme($hGUI, $bEnableDarkTheme = True, $bPreferNewTheme = False) Local $aCtrls = __WinAPI_EnumChildWindows($hGUI, False) For $i = 1 To $aCtrls[0][0] _GUICtrlSetDarkTheme($aCtrls[$i][0], $bEnableDarkTheme, $bPreferNewTheme) Next Local $aCtrlsEx = __WinAPI_EnumProcessWindows(0, False) ; allows getting handles for tooltips_class32, ComboLBox, etc. For $i = 1 To $aCtrlsEx[0][0] _GUICtrlSetDarkTheme($aCtrlsEx[$i][0], $bEnableDarkTheme, $bPreferNewTheme) Next Return $aCtrls EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlSetDarkTheme ; Description ...: Sets the dark theme for a specified control. ; Syntax ........: _GUICtrlSetDarkTheme($vCtrl, $bEnableDarkTheme = True, $bPreferNewTheme = False) ; Parameters ....: $vCtrl - The control handle or identifier. ; $bEnableDarkTheme - If True, enables the dark theme; if False, disables it. ; (Default is True for enabling dark theme.) ; $bPreferNewTheme - Prefer the newer DarkMode_DarkTheme theme over DarkMode_Explorer when possible. ; (Default is False. DarkMode_DarkTheme is only available on Win11 26100.6899 and higher) ; Return values .: Success: True ; Failure: False and sets the @error flag: ; 1: Invalid control handle or identifier. ; 2: Error while allowing dark mode for the window. ; 3: Error while setting the window theme. ; 4: Error while sending the WM_THEMECHANGED message. ; Author ........: NoNameCode ; Modified ......: WildByDesign ; Remarks .......: This function requires the _WinAPI_SetWindowTheme and _WinAPI_AllowDarkModeForWindow functions. ; Related .......: ; Link ..........: http://www.opengate.at/blog/2021/08/dark-mode-win32/ ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlSetDarkTheme($vCtrl, $bEnableDarkTheme = True, $bPreferNewTheme = False) Local $sThemeName = Null, $sThemeList = Null Local $iGUI_Ctrl_Color = ($bEnableDarkTheme == True) ? $COLOR_TEXT_LIGHT : _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_WINDOWTEXT)) Local $iGUI_Ctrl_BkColor = ($bEnableDarkTheme == True) ? $COLOR_CONTROL_BG : _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_BTNFACE)) Local $bSpecialBtn = False, $bSpecialLV = False, $bSpecialTV = False Local $sStyles If Not IsHWnd($vCtrl) Then $vCtrl = GUICtrlGetHandle($vCtrl) If Not IsHWnd($vCtrl) Then Return SetError(1, 0, False) _WinAPI_AllowDarkModeForWindow($vCtrl, $bEnableDarkTheme) If @error <> 0 Then Return SetError(2, @error, False) ;========= ;ConsoleWrite(@CRLF & __WinAPI_GetClassName($vCtrl)) Switch __WinAPI_GetClassName($vCtrl) Case 'Button' $sStyles = hWnd2Styles($vCtrl) Switch $bEnableDarkTheme Case True If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' Else If StringInStr($sStyles, "BS_GROUPBOX") Or StringInStr($sStyles, "BS_AUTORADIOBUTTON") Then $bSpecialBtn = True Else $sThemeName = 'DarkMode_Explorer' EndIf EndIf Case False $sThemeName = 'Explorer' EndSwitch Case 'msctls_trackbar32' GUICtrlSetColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_Color) GUICtrlSetBkColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_BkColor) If $bEnableDarkTheme Then GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") Case 'msctls_updown32' If $bEnableDarkTheme Then $sThemeName = 'DarkMode_Explorer' GUICtrlSetColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_Color) GUICtrlSetBkColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_BkColor) EndIf Case 'ListBox' Switch $bEnableDarkTheme Case True If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' Else $sThemeName = 'DarkMode_Explorer' EndIf ; create brush and register GUI message If Not $g_hBrushEdit Then $g_hBrushEdit = __WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_CONTROL_BG)) GUIRegisterMsg($WM_CTLCOLORLISTBOX, "_WM_CTLCOLOR") Case False $sThemeName = 'Explorer' EndSwitch Case 'SysTreeView32' $sStyles = hWnd2Styles($vCtrl) Switch $bEnableDarkTheme Case True If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' Else $sThemeName = 'DarkMode_Explorer' EndIf ; dark mode checkboxes If StringInStr($sStyles, "TVS_CHECKBOXES") Then $bSpecialTV = True EndIf Case False $sThemeName = 'Explorer' EndSwitch GUICtrlSetColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_Color) GUICtrlSetBkColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_BkColor) Case 'SysListView32' Switch $bEnableDarkTheme Case True If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' Else $sThemeName = 'DarkMode_Explorer' EndIf ; register callback to subclass ListView header text color $hWndListViewHeader = _GUICtrlListView_GetHeader($vCtrl) $hWndListView = $vCtrl $g__ListView_wProcNew = DllCallbackRegister("_LVWndProc", "ptr", "hwnd;uint;wparam;lparam") $g__ListView_wProcOld = __WinAPI_SetWindowLong($vCtrl, $GWL_WNDPROC, DllCallbackGetPtr($g__ListView_wProcNew)) ; checkbox dark mode If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($vCtrl), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $bSpecialLV = True EndIf Case False $sThemeName = 'Explorer' EndSwitch GUICtrlSetColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_Color) GUICtrlSetBkColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_BkColor) Case 'Edit' Switch $bEnableDarkTheme Case True If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' Else $sThemeName = 'DarkMode_Explorer' EndIf ; create brush and register GUI message If Not $g_hBrushEdit Then $g_hBrushEdit = __WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_CONTROL_BG)) GUIRegisterMsg($WM_CTLCOLOREDIT, "_WM_CTLCOLOR") Case False $sThemeName = 'Explorer' EndSwitch Case 'SysHeader32' Switch $bEnableDarkTheme Case True If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' Else $sThemeName = 'DarkMode_ItemsView' EndIf Case False $sThemeName = 'ItemsView' EndSwitch $sThemeList = 'Header' Case 'Static' If $bEnableDarkTheme Then GUICtrlSetColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_Color) EndIf Case 'SysDateTimePick32' ; if SysDateTimePick32 exists, obtain handle for SysDateTimePick32 and register WM_NOTIFY If $bEnableDarkTheme Then $g_hDate = $vCtrl $g_hDateProc_CB = DllCallbackRegister('_DateProc', 'ptr', 'hwnd;uint;wparam;lparam') $g_pDateProc_CB = DllCallbackGetPtr($g_hDateProc_CB) $g_hDateOldProc = __WinAPI_SetWindowLong($g_hDate, $GWL_WNDPROC, $g_pDateProc_CB) GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") EndIf Case 'msctls_progress32' If $bEnableDarkTheme Then If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_CopyEngine' Else $sThemeName = 'DarkMode' EndIf $sThemeList = 'Progress' EndIf Case 'Scrollbar' If $bEnableDarkTheme Then $sThemeName = 'DarkMode_Explorer' Case 'AutoIt v3 GUI' If $bEnableDarkTheme Then $sThemeName = 'DarkMode_Explorer' Case 'msctls_statusbar32' If $bEnableDarkTheme Then If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' $sThemeList = 'Status' Else $sThemeName = 'DarkMode' $sThemeList = 'ExplorerStatusBar' EndIf Else ; EndIf Case 'tooltips_class32' If $bEnableDarkTheme Then If $bPreferNewTheme And $b24H2Plus Then ;$sThemeName = 'DarkMode_DarkTheme' ; works but is faded (MS still developing DarkMode_DarkTheme parts) $sThemeName = 'DarkMode_Explorer' ; use for now $sThemeList = 'ToolTip' Else $sThemeName = 'DarkMode_Explorer' $sThemeList = 'ToolTip' EndIf Else ; EndIf Case 'ComboLBox', 'ComboBox' If $bEnableDarkTheme Then If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' $sThemeList = 'Combobox' Else $sThemeName = 'DarkMode_CFD' $sThemeList = 'Combobox' EndIf ; create brush and register GUI message If Not $g_hBrushEdit Then $g_hBrushEdit = __WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_CONTROL_BG)) GUIRegisterMsg($WM_CTLCOLORLISTBOX, "_WM_CTLCOLOR") Else ; EndIf GUICtrlSetColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_Color) GUICtrlSetBkColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_BkColor) #cs Local $hEdit = _WinAPI_FindWindowEx($vCtrl, 0, "Edit", "") If $hEdit Then __WinAPI_SetWindowTheme($hEdit, "DarkMode_CFD", 0) _WinAPI_AllowDarkModeForWindow($hEdit, True) EndIf ; ComboBox dropdown list Local $hComboLBox = _WinAPI_FindWindowEx($vCtrl, 0, "ComboLBox", "") If $hComboLBox Then __WinAPI_SetWindowTheme($hComboLBox, "DarkMode_Explorer", 0) _WinAPI_AllowDarkModeForWindow($hComboLBox, True) EndIf #ce Case 'SysTabControl32' If $bEnableDarkTheme Then If $bPreferNewTheme And $b24H2Plus Then $sThemeName = 'DarkMode_DarkTheme' $sThemeList = 'Tab' Else $sThemeName = 'DarkMode_Explorer' ; Register a custom window procedure for the tab control for owner-drawing EndIf ; 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($vCtrl, $GWL_WNDPROC, $g_pTab_CB) $g_hTab = $vCtrl Else $sThemeName = 'Explorer' EndIf Case Else $sThemeName = 'Explorer' EndSwitch ;ConsoleWrite(@CRLF & 'Class:' & __WinAPI_GetClassName($vCtrl) & ' Theme:' & $sThemeName & '::' & $sThemeList) ;========= __WinAPI_SetWindowTheme($vCtrl, $sThemeName, $sThemeList) If @error <> 0 Then Return SetError(3, @error, False) __SendMessage($vCtrl, $WM_THEMECHANGED, 0, 0) If @error <> 0 Then Return SetError(4, @error, False) If $bSpecialBtn Then ; this is used to remove theme from group box and radio buttons which are not themed properly with older DarkMode_Explorer __WinAPI_SetWindowTheme($vCtrl, "", "") GUICtrlSetColor(_WinAPI_GetDlgCtrlID($vCtrl), $iGUI_Ctrl_Color) EndIf _GDIPlus_Startup() Local Static $hIcon_c, $hIcon_uc Local $hBmp If $hIcon_c = 0 Then $hBmp = _GDIPlus_BitmapCreateFromMemory(_checkedico()) $hIcon_c = _GDIPlus_HICONCreateFromBitmap($hBmp) _GDIPlus_ImageDispose($hBmp) EndIf If $hIcon_uc = 0 Then $hBmp = _GDIPlus_BitmapCreateFromMemory(_uncheckedico()) $hIcon_uc = _GDIPlus_HICONCreateFromBitmap($hBmp) _GDIPlus_ImageDispose($hBmp) EndIf If $bSpecialLV Then Local $hImageListLV = _GUICtrlListView_GetImageList($vCtrl, 2) _GUIImageList_Remove($hImageListLV) _GUIImageList_ReplaceIcon($hImageListLV, -1, $hIcon_uc) _GUIImageList_ReplaceIcon($hImageListLV, -1, $hIcon_c) EndIf If $bSpecialTV Then Local $hImageListTV = _GUICtrlTreeView_GetStateImageList($vCtrl) _GUIImageList_Remove($hImageListTV) _GUIImageList_ReplaceIcon($hImageListTV, -1, $hIcon_c) _GUIImageList_ReplaceIcon($hImageListTV, -1, $hIcon_c) _GUIImageList_ReplaceIcon($hImageListTV, -1, $hIcon_uc) EndIf _GDIPlus_Shutdown() Return True EndFunc ;==>_GUICtrlSetDarkTheme #EndRegion Public Functions #Region Enable GUI DARKMODE ; TODO: these functions probably need common #FUNCTION# to be more descriptive Func _ApplyDarkTheme($hGUI, $bPreferNewTheme = False) _GUISetDarkTheme($hGUI, True) _GUICtrlAllSetDarkTheme($hGUI, True, $bPreferNewTheme) ; GUIDarkMenu _GUITopMenuTheme($hGUI) ; redraw menus _GUICtrlMenu_DrawMenuBar($hGUI) EndFunc #EndRegion Enable GUI DARKMODE #Region Enable GUI LIGHTMODE Func _ApplyLightTheme($hGUI) _GUISetDarkTheme($hGUI, False) _GUICtrlAllSetDarkTheme($hGUI, False) EndFunc #EndRegion Enable GUI LIGHTMODE ;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2020-06-05 Func _uncheckedico($bSaveBinary = False, $sSavePath = @ScriptDir) Local $uncheckedico $uncheckedico &= 'JLgAAAABAAcADQ2iAAAACADhAFB2ABgEEBADeA0BAABXKQAMFBQDPBYALGQCUAAAGhoDPBkAPHqgAwAAICADHiIAHkCTBAAAKCgDHgyBAFa1BQAANDQDHgIlAB7BBwAAiVBATkcNChoKACgNMElIRFIBBwEDCAYhAAVy6+R8AAYJcIBIWXMAAA7DAQMgAcdvqGQAFBl0AEVYdFNvZnR3AGFyZQB3d3cuAGlua3NjYXBlgC5vcmeb7jwBmABuSURBVCiR7QDOsQ2DQBQDUAD7xBZJdXOQAQBQekZgJpIBMgBKtjjfSTCHPwADpOA6mlhy5wAnmaWUJ4AXyQAbzrOnlJaB5ABqe845f8+EpADR9geSIiLQWwBJkTou/eSPLgBBu6SxZ1xrfQAA2Nham2y/AQDcO9xGcjkAKYDDR/wtaZg+AXEASUVORK5CYIILEHABqRACcB/z/2EFOnCaAXA4je2TuwANwkAQBed8yADWBdRA7h4QOQBtIDpwN+BSkACQi9jotEWQ+ACTPBJMRGATewCkDd9sNMHdDwBACxyBkmVMQAAn6bIDWkmPYQAYznVdT0vWZgBWppSaEMI9uAD72Pf9ful4JgDnXMUYX7i7JADxz7m7ijVffwCxCTbBLJjMbABpRF9yzhUwFgBAl1Jq1kjMrACMMTZAFz453wCAE+tyfkq6vgAB5PhpkG9/YxbrHEPBkxQCQ42JHQuBfjdDowRD1bENwgAwEAXQfyeMbgAFkNO5o0ZMwwAqFGGLlGQZFgBwZ19FMkOa6ABoLCoqmwrlSwDXPv3qPsUY9wAicieiK4AD6gAym9m4LMttJwAiPRGdnHNn7wD9VKOllDwzDwAi0pOqTuu6XgBCCK/KdgCAnABzx8xPqKqZGQB+capq3NLqWwA2cAM38H/AOQCl5FuhnHMHYABmMxuZeWhBywAvHIjoQWUC+gAyAcdK8zMBbwBd7XfzBEcR9gtcRYEzGkJFqUpMzgV6RaZBRUiJ' $uncheckedico &= '7dYxAA7CMAyFYduiAMhXAKVbN2bEAGl6FYZwi4z0ADJcoFviieYMAFkqswQmxmTzAJM8f/L247quAEdmfiDiDAAnAGi7rKpLKeV+AGBmj4iXYRiuAM65raUSY3REABSY2aOIbPu+AN+maXq3RL5LACmNRPQCEVFVAIWeJyJKPb74QDeDDDLIIIAAqAAXlGOMrheQUgAaASCTqi5EFAB6YLWAAiI+sQAGpK8BeW5s/QAC8gMezIntdFgI9eUcI8GLIAIjc1h6evQfIxgjrwEjWACF7dexDQIxDAAFUNvikFcA5QC6dNSIaViF4gDY4kpuGRZIlwS44sBFk2kCFbUAafwl1/+5/JgAUtoz8x0RrwAAcACbVFVdWmsAtx0zT4h4GoYA4RxCWC3ac84AgYhmZp5QRNYAbdsuMcaXRfkAJ6WUkYieICIAqqrwjxMRJcsAr3/FAQ5wgANAHOAABzjAQgEIAABqzjlYF5dSAEYAqKSqCxHNAJaIvgtnRHxgAJ/nU5/nRyPDAHeevwHMfpvnsLW1yZQ8JAGuKCIkMIz+uG0/JDckAZkBJCTYsUocQRzHAPHv7t6yhdEgACkzXrVwEAPaAJ29RVLkCXIPAGB1wnEvYZMiAK11fANT6AuoAN0FEuG45Q72AG7bBKIyyDD8AFPcRIygCAO7ACnmW/2n+xS7AM0vEhEAiqLIAFqt1p6IfATeAAIr1NsN8B04ALLWHuZ5fgsQAIkIi8XitTHmACuwVTPqsUZpAJp+UEpV0WQyAMmSJLlgiZuLAMjAGHPa6XSuAOoUjcfj1SzLAHZF5ADoACNrAO1ONJvN9kXkADMwT9N0Wyn1ALNO2MPKsly3ANZ+AzaAfiwiAD0AERk0jQNoALfbv4Che/ZiAOANgDHmtDHVAIOstSfu3IyBABcAdX9zT5XnAPlvd67GjUqeAFEA+haAvgWgEG8B6FtWAQPXsADc5xq23DWdTgBfuvMqBi4BsgAs222O9G9RFAC9' $uncheckedico &= 'c+ePGPgCIAAiB2VZrjfHWgBWVdUr4JN7HgD9nYDPgW1gDgAMrbUn9yawWgAqimItSZL3DgCngJHWunt/RAA/dsj/obsRPQIGwB5a6y7QB84AcT9OzV0DZ0AAX2vdVUpVAH8AAOQTmFcI9KgW1HxBge00YkHFeBsvIbF/Qb8gsyCysSBogQDt2rFqFFEUgADhf2Z2mEKjBABLr1sNLETBdABrn0ILn8A8gADVCiEvkcbC1gDavIEWyQsYuwAVVFh22IXZnQDWQBK5yOVyLAB2DKkCbpA5gQDzVed25y9mqgCTiAgAVVUVvQBe77WIvAKeAAB30O0X8A04jAAxvi/L8jdAIgAiLJfLhyGETwDA005XXN84zwDzl865JplOpwBFlmVfWMUsRABkL4RwPBgMzgC73vI6k8lkowAoih0ROQAGwAA4xvgsmc/nbwBE5B2wyPN82wA597PjXf9JXQDXmzHGr8AjYACUisgugIjs3QC2GIB+v38K7AC3z90U2AIIIQAcd7bVDcUYjwDa8XEK3AXQ/gDNXKcsy7N23ABIO93kP7Ag7QAsSDsL0s6CtA6zrwCvAKEALgUuYAB1O9PxLmubzQBm99vxPAV+AAAURbHT3Uo3kwAkyfN2/J4CHwAAROSgruvN7gDWWk/TNA+AtwDt8/DvedkJsAANLID9GOPRlQBzE5WqqrqXZQDZC1YxDhh77wCHVw8AP7KKugCNLg8AUwDnXADjvR8CI+CE9gBHodwF8BkYeQDvh865BuAPs4CEmG/rOy7qSSI=' $uncheckedico = _WinAPI_Base64Decode($uncheckedico) If @error Then Return SetError(1, 0, 0) Local $tSource = DllStructCreate('byte[' & BinaryLen($uncheckedico) & ']') DllStructSetData($tSource, 1, $uncheckedico) Local $tDecompress _WinAPI_LZNTDecompress($tSource, $tDecompress, 2534) If @error Then Return SetError(3, 0, 0) $tSource = 0 Local Const $bString = Binary(DllStructGetData($tDecompress, 1)) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\unchecked.ico", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_uncheckedico Func _checkedico($bSaveBinary = False, $sSavePath = @ScriptDir) Local $checkedico $checkedico &= 'FrwAAAABAAcADQ0CAAAACABoAQAAUnYASBAQA3icAHjeKQAMFBQDPLMALHoDUAAAGhoDPOoAPC0gBQAAICADHgUCAAAAFwcAACgoBQMeLAAeHAkAADQKNAMe7wAeSAsAAACJUE5HDQoaCsEAKA1JSERSAQcBA4QIBgAFcuvkfAAGAAFzUkdCAdnJBCx/AAwEZ0FNQYAAALGPC/xhAG9AACBjSFJNAIsmgAAAgIQAAPoAEgCA6AAAdTAAAEDqYAAAOpgAh3AQnLpRPAAYCXBIQFlzAAASdAEDARDeZh94ABQHdEkATUUH6QUDFScQC3AwyoBLAL5JAERBVCjPlZI9AArCUBCEv32IAJ2Q0lbIAQT1AAD2eoY8K8vgAAmMJzBHeAewABC8gIWluYGVABcwkC5F1sJGAGN+t5thPwZ2AFYAgkQjUQ0RAPGoG9UUwbmZANlJkBSxICFdAEc1EnsvXo0JABWJphcAIOKZAC57j4v70a3QAG1vQaQeel7PAH/AeLHEXwX1AFCepdyiTSMAADD4Fv7aAnBaAE+YbqNKAEBsAKJaNvMsZTiqAD+qQTUtm03AAKcniPv1hBMAAJsURxTb+nsQALu5ObwBAjdAINLNNQjVgbRJRcBORK5CYIKQs4HsQhCCsx/z/2HosyagLbsmfr6ABPLBWQA4y6WSoU4DQQAQhr/ZENSRNAC4Vi0JCfaa0AAHwNX0AVA9TADtlSegj3CVxQBwZ1AYwODaBwAoySoSEsQGQQAdIeEUooPClADL0Vs+OZP/mwCZZARguFyPRQBIQSxboY41WQDeM4UMl5qIcABFAKp6bkQ0JQAQgdSAxAQbxAAa/kkjwct9zgDX50eYwM0mPABdT9ndazUXuADZhNfFLf3LeQD9CeWb52ZwQAC58pXhzem/BABRxxKPLngYnQBQrvyfYYCdzQDC4SAB4O60SwDUtrVhAEkeVQCrGu/PjqhjawDDlRv8sH8UbwD7B+qDv0jVGQBV' $checkedico &= 'puECMlMcmwBMlTNUXYPJHgDVcd4zxTfIqsBYwb1oypbcZkHZ4hTCZo2JHQHE/2bkZqARlEkCOeANCWMzAGNkYGBQ0osvAFHTTqhqZeXiAFFjYmHlYSARAHx/+/LQ5UWdAO13V0+7xWhSANRjpRWRv4OJAJmFl4EC8P/fAN9PVxdN8GSMADn6bRsLB6cnAAMVwN/fP48yEFHLMAYAACYWVgAdJgYqAkZGJgB+qhrIwMDAMAA4DHx36wLDpgBIQ6xyLOQYtgCvKJDBqW895QAuRDZMSM2AeAADN0UaMry7dQCBZMNwGmjTOACfYV9xINxQYggNY2AAAEw4+/8AP07vFQcyGKQA1TNcmNlIlGEAeA0k1WVEGTgASBL2//8fqGsAICPDBeoZ938AA9N/JsZEqrgA8v//D/9/MRYAMi00ZHzwn5kA0ZCB4f8Gcg0AYvj//8D/34wAhgstGR8AAECAyXfEAJ1molw2hQGhGkI2qUpMzl82B182XzZCNiUtkAstCn3gDUBBNkjH7dYAvU7CUBwF8HMAbgwTJqwydfAABTo4kDjAxuIAAzhRF1b0CaAAT2AYZWpfwYkADQZHDT5CJ+cAm8BUI8cBjPUAq4G218TEM98A3F9Ocj/+xDYAvYU8rjWAEIAAbKBMpATEXCkQw7jFBGC3vXsFAISuSwNfQQvhADI6MTF7C3l8ANGiciSD6Zm+AOFaQ2cIAJANANY0MADacB0hADAAPecQ2TD4AKX8Q98mXVpMAPtt3I0uflxzAFAN0kG6sjgNACM3jbJIdzJDAP3Iqx7aB8mFAB5vRrg995EuAG1pJBc6PgveADfMYEWQXKjeAPTQncw+YEURAABg8CDlLVg9ACWY9juoHW7eAN0iyE6HIdusACiyU6NsMxCFAJC9Lmy96f2VALdOsu4/PiUGAETk/uPD3MhwAOy0lWSVMjSxAM9E4JUTbDtuAMUtJvw0QA43AMNKyTlCsiAiAKUcvw2Qr2rGwMEJ' $checkedico &= 'sCLwVzw9QdzCICI9c3p69D89Pz2DPz0jPQ9Fa2yZ4A0CWyE9WMPtl7FKAQGn/xnETghWVgCW1jHBTvBiZQBpa2XS2F7yBACeD3C4KZPmtABJq/gCuYBV5ABkq0AsfYAjTwBwkyLcEQOSuwBkvQXJXy67fAAfw8DOEJZy+wAhDrG4EDggqgDAZERmIISSUAD3+YzC9JgyeACUKAK5KCWingDq3MkEyoX/lACgRdkxhIVIggAGE4sLSyEWlwAhcGwJQOCw8QBuL1QCqjAsZwAn8H8FJgOFsQDfsSOgex7GfiAH8VSXL5AAdP8AAYcnVVz6L+UACizDr/pD7B8AVMoT2ASeS+AA7eZ0bTNtCs8AJXDcuMZkoPAA7rWMwwFgb90AherdfQYCgHMALzAGzyXwm4QACXhugVWJeKoAEX/preGFBFYAJUzAAYCakUgA0Uff4SuO6s4A1vCNBXa/oVkAAZGZvaFUZgwAQmhvKEXIklAA195QDMWLRVEAlIX6q6DGo2wAOW1GySNAbSsAy2ma1mdyIYIA9l+u50RQQY0AR+nxHEBxo7twn1z1Zk8gSiBxjSjhQiCM/rhtTyBPIE8gB08gTyBOICQvZx59CbB7AYJEINgxTgIAQRTG8f+bmsIAVqvlBmBiYScAnYUGboCVrUcAEG5AbWO2t8AAzg6tjWFv4FYA2lJQWexnAZgADUHDCosvcb8Ador55c28yeQAGUvpPuvEgtoAQAcsYidRAiQA+rB+fGxpfsUAvmBj7ZGpZ9gAFX8aDRSsHzcAbfIF7I61Z5kARmANXESJgrUA4qZNAgCZen4AcADWsEzXANYAHSuyjFccRhkArbCQeowFtQMA0PAKRHSCr7sAt1xCiwLOUwEAK2AF9AScvqUA3J3VuTuv+wMATt9SHi5bTN8AU38VzONqBxEApzcjP8BVuNoAfuQDuCmuVOAANnCFgIvuW+cAkm8LV7iC63QI4jZxAAGNfkJuABtXCJjfcBWy' $checkedico &= 'AAxc4SP+DlkWAA7ALl6kTTsUAFEK7tfPzHIlAMvCbfQO5kFlAOF+fcTVf7ACAP4zoFK3OikJAMDQ7+iDJCizAHu3BfywfoiPAOwRNHDIG8THAJYGAAXrzwfZAF5wycw07+K4AGkTBWv5qKQGAIv59OwaLmU2ABLWNaKB7Wh2ACilGEMzhreHAOEpv/QJnXUC4MfNU5eMvyK6IjGvwjSyIsV4G+u/Ir8iD78ivyK/Ir8iE0hxASCXAAACRbEiaN4A7dq/TttQFMcA8e+5SjOBFHUAqhiQh6pzKEUAiM3p1KUib2AAs6QrqA8A3asAMpcl8RukW6cA1h1bqBJWJqsAQ7shS2WC4NMAIYDSNKiQOP4AJ//Gq+vho3sA77m2dYRb4hwAqi1GNwEbxUIIpEaaQK8CwNeBAHjeuvQnTZN/ACA9tSTSNohNAKajXT2XHW9DAILRUfMX5khdALnUXvYxANKUAAfacw8jZ+IKADlH6orQJo+JANTtrBnvBuT0ANSSS+2lfk5mADhfeiEr3oYEAAZAIt3PLQZAAKQmVW0DiPNVAOtSoUcBohENACMVdShIxOimAAHsooBQbINiAFGcWCbXxWBCAHEwFCwlqASVAKASVIISzelJAJ9Pr5v88LtTAD1fyRrmY6vBAPnvkNOTY5btAGZ+V2gUA/D4AKWb3y03jqm/ANqj3trNJyhOAEzqoLgxqYLmAIFJDTQvzNSgAG9vt+msCv33AHuZwkwNur70APoHb+6FmjdmAGrQ83ddqou1AHuhksBMDXr4AKTOi4PPd0YlAIWZqSjcFZUkAGbmKvc/VNIYAABxv6vGXoZbALssN5qJY2IDIE1CVRdrgAC9WADHt18amNjfFADGUUljYt1yowA5+xlw9ivg0QCqnfhr1Vy+WAAXliwWlqzynwBCCSpBuQSphgCF0aiG5qrdpAAoCQzgF4Yj+ABGI/lQmB03EADPeGvig+Z/lQAi7Xrr0jcAagBkK9fFQTXU' $checkedico &= 'gQDs3JRtb0UCZQA4kE8Q29dtZgA395D3TDqq5ABrpVTD0U6sYQBdGMtVA+A+SAAz4xhfL2RrvAABUG6bP2xqUgAHxYaMtGhCgADgi9BtPzVfJgBN+wPXaGWGHAihNfHpLg==' $checkedico = _WinAPI_Base64Decode($checkedico) If @error Then Return SetError(1, 0, 0) Local $tSource = DllStructCreate('byte[' & BinaryLen($checkedico) & ']') DllStructSetData($tSource, 1, $checkedico) Local $tDecompress _WinAPI_LZNTDecompress($tSource, $tDecompress, 3639) If @error Then Return SetError(3, 0, 0) $tSource = 0 Local Const $bString = Binary(DllStructGetData($tDecompress, 1)) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\checked.ico", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_checkedico Func _WinAPI_Base64Decode($sB64String) Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "") Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]") $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "") Return DllStructGetData($bBuffer, 1) EndFunc ;==>_WinAPI_Base64Decode Func _WinAPI_LZNTDecompress(ByRef $tInput, ByRef $tOutput, $iBufferSize) $tOutput = DllStructCreate("byte[" & $iBufferSize & "]") If @error Then Return SetError(1, 0, 0) Local $aRet = DllCall("ntdll.dll", "uint", "RtlDecompressBuffer", "ushort", 0x0002, "struct*", $tOutput, "ulong", $iBufferSize, "struct*", $tInput, "ulong", DllStructGetSize($tInput), "ulong*", 0) If @error Then Return SetError(2, 0, 0) If $aRet[0] Then Return SetError(3, $aRet[0], 0) Return $aRet[6] EndFunc ;==>_WinAPI_LZNTDecompress For sure you can use GD+ to draw the check / uncheck icons (bitmaps) as @argumentum did above. -
UEZ reacted to a post in a topic:
DarkMode UDF for AutoIt's Win32GUIs
-
DarkMode UDF for AutoIt's Win32GUIs
UEZ replied to NoNameCode's topic in AutoIt Technical Discussion
I cannot reproduce the issue on my system. It displays as intended in the correct size and in dark mode. -
DarkMode UDF for AutoIt's Win32GUIs
UEZ replied to NoNameCode's topic in AutoIt Technical Discussion
I'm on Win11 24H2. WM_NOTIFY should only change the thumb - not the whole slider control but if you change the style of the control, it would not fit with current setting. For the demo it is ok not if you use different styles. -
DarkMode UDF for AutoIt's Win32GUIs
UEZ replied to NoNameCode's topic in AutoIt Technical Discussion
System Menu text colors (when you click on the Autoit icon in the left upper corner) and slider thumb are not working properly. Slider thumb is changing the color when dragged. -
Need help inverting colors with _WinAPI_InvertRgn
UEZ replied to WildByDesign's topic in AutoIt GUI Help and Support
;Coded by UEZ build 2026-02-28 beta #include <WindowsConstants.au3> #include <GuiConstants.au3> #include <GuiDateTimePicker.au3> #include <GuiMonthCal.au3> #include <WinAPI.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> Opt("MustDeclareVars", True) Global $g_hDateProc_CB, $g_pDateProc_CB, $g_hDateOldProc, $g_hDate Global Const $PRF_CLIENT = 0x0004, $COLOR_BORDER = 0x404040, $COLOR_BG_DARK = 0x202020, $COLOR_TEXT_LIGHT = 0xFFFFFF, $COLOR_BORDER_LIGHT = 0xD8D8D8 Global $g_bHover = False Example() Func Example() Local $hGUI = GUICreate("Sample GUI", 400, 240) GUISetBkColor($COLOR_BG_DARK) Local $idDate = GUICtrlCreateDate("", 15, 15, 200, 20) $g_hDate = GUICtrlGetHandle($idDate) $g_hDateProc_CB = DllCallbackRegister('_DateProc', 'ptr', 'hwnd;uint;wparam;lparam') $g_pDateProc_CB = DllCallbackGetPtr($g_hDateProc_CB) $g_hDateOldProc = _WinAPI_SetWindowLong($g_hDate, $GWL_WNDPROC, $g_pDateProc_CB) GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUISetState() While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _WinAPI_SetWindowLong($g_hDate, $GWL_WNDPROC, $g_hDateOldProc) DllCallbackFree($g_hDateProc_CB) GUIRegisterMsg($WM_NOTIFY, "") GUIDelete() ExitLoop EndSwitch WEnd EndFunc ;==>Example Func _DateProc($hWnd, $iMsg, $wParam, $lParam) Switch $iMsg Case $WM_PAINT Local $tPaint = DllStructCreate($tagPAINTSTRUCT) Local $hDC = _WinAPI_BeginPaint($hWnd, $tPaint) Local $tClient = _WinAPI_GetClientRect($hWnd) Local $iW = $tClient.Right Local $iH = $tClient.Bottom ; --- Memory DC for flicker-free rendering --- Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local $hOldBmp = _WinAPI_SelectObject($hMemDC, $hBitmap) ; 1. Let Windows draw the light-mode control into memory DC _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $WM_PRINTCLIENT, $hMemDC, $PRF_CLIENT) ; 2. Invert all pixels (background becomes black, text white, selection orange) Local $tRect = DllStructCreate($tagRECT) $tRect.right = $iW $tRect.bottom = $iH _WinAPI_InvertRect($hMemDC, $tRect) ; --- 3. PIXEL HACK: destroy orange highlight & set background color --- Local $iSize = $iW * $iH Local $tPixels = DllStructCreate("dword c[" & $iSize & "]") ; Load pixel array directly from bitmap memory Local $iBytes = DllCall("gdi32.dll", "long", "GetBitmapBits", "handle", $hBitmap, "long", $iSize * 4, "ptr", DllStructGetPtr($tPixels))[0] If $iBytes = $iSize * 4 Then Local $iPixel, $r, $g, $b, $iGray For $i = 1 To $iSize $iPixel = $tPixels.c(($i)) ; Split into color channels $b = BitAND($iPixel, 0xFF) $g = BitAND(BitShift($iPixel, 8), 0xFF) $r = BitAND(BitShift($iPixel, 16), 0xFF) ; Convert to grayscale (orange becomes mid-gray) $iGray = Int(($r + $g + $b) / 3) ; Very dark pixel = inverted white background If $iGray < 15 Then $iPixel = $COLOR_BG_DARK ; Replace with exact GUI background color Else ; Grayscale value for text (white) and selection (gray) ; (negative BitShift shifts left in AutoIt) $iPixel = BitOR(BitShift($iGray, -16), BitShift($iGray, -8), $iGray) EndIf $tPixels.c(($i)) = $iPixel Next ; Write cleaned pixels back into the bitmap DllCall("gdi32.dll", "long", "SetBitmapBits", "handle", $hBitmap, "long", $iSize * 4, "ptr", DllStructGetPtr($tPixels)) EndIf ; --- END PIXEL HACK --- ; --- Border color (hover effect) --- Local $iBorderColor = $COLOR_BORDER If _WinAPI_GetFocus() = $hWnd Then $iBorderColor = $COLOR_BORDER Local $tCursorPos = DllStructCreate($tagPOINT) DllCall("user32.dll", "bool", "GetCursorPos", "struct*", $tCursorPos) DllCall("user32.dll", "bool", "ScreenToClient", "hwnd", $hWnd, "struct*", $tCursorPos) If $tCursorPos.X >= 0 And $tCursorPos.X <= $iW And $tCursorPos.Y >= 0 And $tCursorPos.Y <= $iH Then $iBorderColor = $COLOR_BORDER_LIGHT EndIf ; --- Draw border --- Local $hPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($iBorderColor)) Local $hNullBr = _WinAPI_GetStockObject(5) Local $hOldPen = _WinAPI_SelectObject($hMemDC, $hPen) Local $hOldBr = _WinAPI_SelectObject($hMemDC, $hNullBr) DllCall("gdi32.dll", "bool", "Rectangle", "handle", $hMemDC, "int", 0, "int", 0, "int", $iW, "int", $iH) _WinAPI_SelectObject($hMemDC, $hOldPen) _WinAPI_SelectObject($hMemDC, $hOldBr) _WinAPI_DeleteObject($hPen) ; --- Copy finished result to screen in one step (no flicker) --- _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hMemDC, 0, 0, $SRCCOPY) ; --- Cleanup --- _WinAPI_SelectObject($hMemDC, $hOldBmp) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) _WinAPI_EndPaint($hWnd, $tPaint) Return 0 Case $WM_ERASEBKGND Return 1 Case $WM_SETFOCUS, $WM_KILLFOCUS, $WM_LBUTTONDOWN, $WM_LBUTTONUP Local $iRet = _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) _WinAPI_InvalidateRect($hWnd, 0, False) Return $iRet Case $WM_MOUSEMOVE Local $iRet = _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) If Not $g_bHover Then $g_bHover = True _WinAPI_InvalidateRect($hWnd, 0, False) EndIf Return $iRet Case $WM_MOUSELEAVE $g_bHover = False _WinAPI_InvalidateRect($hWnd, 0, False) EndSwitch Return _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_DateProc 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 _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 visual theme when DateTime control receives focus _WinAPI_SetThemeAppProperties(0) Case $DTN_DROPDOWN ; Apply dark colors when the calendar dropdown opens _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 dropdown closed - no action needed EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_NOTIFY -
UEZ reacted to a post in a topic:
SampleControls.au3 in Dark Mode
-
I created a fake DateTimePicker control. Does anyone know in which DLL or other file the original icon is hidden?