Jump to content

Recommended Posts

Posted (edited)

 

 

Spoiler

Important note about Windows DLLs

Files like fontext.dll in newer versions of Windows (Windows 10/11) are MUI (Multilingual User Interface) binaries.
This means that the actual language strings are often not contained within the .dll itself,
but in language subfolders (e.g. C:\Windows\System32\el-GR\fontext.dll.mui).

When you call LoadLibraryExW with the flag $LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE (0x00000040) or
when you let Windows load the corresponding .mui,
the system automatically routes the call to the language of the active user.

 

 

I have English MUI (Multilingual User Interface) windows.

#AutoIt3Wrapper_UseX64=y

#include <WinAPIRes.au3>

Local $aStrings[4] = [1101, 1103, 1136, 1137]

; Directly load the MUI file for Greek
Local $sMuiDll = @SystemDir & "\el-GR\comdlg32.dll.mui"
ConsoleWrite("-> $sMuiDll=" & $sMuiDll & @CRLF)

Local $hInstance = _WinAPI_LoadLibraryEx($sMuiDll, $LOAD_LIBRARY_AS_DATAFILE)

If $hInstance Then
    For $i = 0 To UBound($aStrings) - 1
        ConsoleWrite("String " & $aStrings[$i] & ": " & _WinAPI_LoadString($hInstance, $aStrings[$i]) & @CRLF)
    Next
    _WinAPI_FreeLibrary($hInstance)
Else
    ConsoleWrite("Error: Could not load MUI file." & @CRLF)
EndIf

output:

>"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "D:\i\Pro\.AutoIT\_Test\000_forum-topic\213613-guidarktheme-udf\neo-test.au3" /UserParams    
+>11:53:37 Starting AutoIt3Wrapper (pid=18340) 23.402.1150.10 from:SciTE.exe (4.4.6.0)  Keyboard:00000409  OS:WIN_11/2009  CPU:X64 OS:X64  Environment(Language:0409)  CodePage:65001  utf8.auto.check:4
+>         SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE   UserDir => C:\Users\ioaio\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\ioaio\AppData\Local\AutoIt v3\SciTE 
>Running AU3Check (3.3.18.0)  from:C:\Program Files (x86)\AutoIt3  input:D:\i\Pro\.AutoIT\_Test\000_forum-topic\213613-guidarktheme-udf\neo-test.au3
+>11:53:38 AU3Check ended. rc:0
>Running:(3.3.18.0):C:\Program Files (x86)\AutoIt3\autoit3_x64.exe "D:\i\Pro\.AutoIT\_Test\000_forum-topic\213613-guidarktheme-udf\neo-test.au3"    
+>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart. --> Press Ctrl+BREAK to Stop.
-> $sMuiDll=C:\WINDOWS\system32\el-GR\comdlg32.dll.mui
String 1101: Γραμματοσειρά TrueType. Η ίδια γραμματοσειρά θα χρησιμοποιηθεί και στον εκτυπωτή και στην οθόνη σας.
String 1103: Γραμματοσειρά οθόνης. Στον εκτυπωτή σας θα χρησιμοποιηθεί η πλησιέστερη γραμματοσειρά που ταιριάζει.
String 1136: Γραμματοσειρά OpenType. Η ίδια γραμματοσειρά θα χρησιμοποιηθεί στον εκτυπωτή και στην οθόνη σας.
String 1137: Γραμματοσειρά OpenType. Η ίδια γραμματοσειρά θα χρησιμοποιηθεί στον εκτυπωτή και στην οθόνη σας.

 

edit: 😁

#AutoIt3Wrapper_UseX64=y

#include <WinAPIRes.au3>
#include <File.au3>

Local $aStrings[4] = [1101, 1103, 1136, 1137]

Local $aArray = _FileListToArrayRec(@SystemDir, "comdlg32.dll.mui", $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_SORT)

For $j = 1 To $aArray[0]
    ; Directly load the MUI file
    Local $sMuiDll = @SystemDir & "\" & $aArray[$j]

    Local $sLabel = StringLeft($aArray[$j], StringInStr($aArray[$j], "\") -1)
    ConsoleWrite("--- " & $sLabel & " ---" & @CRLF)

    Local $hInstance = _WinAPI_LoadLibraryEx($sMuiDll, $LOAD_LIBRARY_AS_DATAFILE)

    If $hInstance Then
        For $i = 0 To UBound($aStrings) - 1
            ConsoleWrite("String " & $aStrings[$i] & ": " & _WinAPI_LoadString($hInstance, $aStrings[$i]) & @CRLF)
        Next
        _WinAPI_FreeLibrary($hInstance)
    Else
        ConsoleWrite("Error: Could not load MUI file." & @CRLF)
    EndIf
Next

 

Edited by ioa747

I know that I know nothing

Posted

GUIDarkTheme 2026.07.27

  • Load Font Type strings directly from OS with _WinAPI_LoadString
    • This also obtains strings for non-English OS
  • DPI improvements for vertical alignment of combo items in Font dialog
  • Fixed issue where Font dialog was crashing on non-English OS
    • Changed methods used to determine if dialog is Font, Color, etc.

Latest download available in the first post of the topic. :)

Posted
4 hours ago, ioa747 said:

I have English MUI (Multilingual User Interface) windows.

Your example scripts and output was very helpful, thank you. :)

I've never had multiple languages on my system and so never really understood how it all works. So your examples pulling strings from MUI files helped my understanding.

I have always wondered something though and perhaps you can help answer this question.

Does the @MUILang macro return the currently (in-use) language that is on your system in a multi-language system?

Also if you have a moment, I just updated GUIDarkTheme-2026.07.27 version with some fixes to prevent crashes particularly on non-English OS for the ChooseFont dialog. Could you please test this new version, run the GUI, and click on the ...Font() button to bring up the ChooseFont dialog to see if it works in your language?

Thank you. Although, it would need to be tested on Win10/11. I don't recall what your main system runs. :)

My goal is simply to make the default ChooseFont dialog become dark mode but keeping the design and layout the same. So I often test by running the AutoIt default light mode _ChooseFont() dialog and run my dark mode variant and check them side-by-side to compare. It was much more complex than I anticipated. But it turned out good so far.

Posted
ConsoleWrite("@muilang=" & @muilang & @CRLF)

it comes out @muilang=0409

basically it says what the scite console says
+>17:07:56 Starting AutoIt3Wrapper (pid=7804) 23.402.1150.10 from:SciTE.exe (4.4.6.0) Keyboard:00000409 OS:WIN_11/2009 CPU:X64 OS:X64 Environment(Language:0409) CodePage:65001 utf8.auto.check:4

In my system
as Windows display language
Windows features like Settings and File Explorer will appear in this language
English (United States)

And as  Country or region a
Windows and apps might use your country or region to give you local content
Greece

Edition    Windows 11 Pro
Version    25H2
Installed on    ‎27/‎11/‎2025
OS build    26200.8894
Experience    Windows Feature Experience Pack 1000.26100.334.0

 

I know that I know nothing

Posted

GUIDarkTheme 2026.08.03

  • Added dark theme support for RichEdit controls
  • Added CUSTOMDRAW for improved Rebar control dark theme
    • Allows custom painting of Rebar band gripper and more
  • Fixed some visual glitches with multi-line Edit (ES_MULTILINE) controls in WM_CTLCOLOREDIT
  • Improvements to vertical alignment of text in single line Edit controls
  • Improved vertical alignment of text in HotKey controls
  • Added _SelfWatchDog UDF by argumentum for debugging if needed
    • Added related "Enable Debugger" option in the Options menu
  • Fixed an issue where the top 3 pixels of a SysIPAddress32 control were not responding to clicks

Latest download available in the first post of the topic. :)

  • 1 month later...
Posted
#include "GUIDarkTheme.au3"

#include <MsgBoxConstants.au3>

Example()

Func Example()
    ; Create a constant variable in Local scope of the message to display in FileSelectFolder.
    Local Const $sMessage = "Select a folder"

    ; Display an open dialog to select a file.
    Local $sFileSelectFolder = FileSelectFolder($sMessage, "")
    If @error Then
        ; Display the error message.
        MsgBox($MB_SYSTEMMODAL, "", "No folder was selected.")
    Else
        ; Display the selected folder.
        MsgBox($MB_SYSTEMMODAL, "", "You chose the following folder:" & @CRLF & $sFileSelectFolder)
    EndIf
EndFunc   ;==>Example

@WildByDesign That always returns an empty string.

Posted
5 minutes ago, bladem2003 said:

That always returns an empty string.

Thanks for letting me know. I actually ran into a similar bug with FileOpenDialog earlier today.

The problem was my code for intercepting Choose Color and Choose Font dialogs is not intended to handle other dialog types. So I fixed it by only allowing Color and Font dialogs to be intercepted and allow the other dialog types to continue as normal.

I tested my fix with your example code and the fix worked well for FileSelectFolder. I will try to get an update out tomorrow.

Posted

GUIDarkTheme 2026.09.18

  • Fixed issue with certain dialog windows failing to work correctly or crashing

 

@bladem2003 This release has the fix that prevents other dialog types from crashing or failing. I have a bigger release coming (hopefully soon) that I have been working on for a month now to bring full Per-Monitor V2 DPI scaling to GUIDarkTheme UDF. It has been more difficult than I expected but it is almost done.

Posted

Heads up:

I apologize, but my "fix" in the GUIDarkTheme 2026.09.18 release ended up breaking dark mode for MsgBox, Font dialog, and Color dialog. I've got an idea for a more elaborate fix for this issue but I can't fix it until later tonight. Sorry about that.

Posted (edited)

GUIDarkTheme 2026.09.27

  • Added support for Per-Monitor V2 DPI scaling via PMv2 UDF
  • Close/recreate theme handles on WM_DPICHANGED and WM_DPICHANGED_AFTERPARENT
  • Improvements to splitbutton drop down arrow
  • Fixed issue with _ArrayDisplay header getting messed up from WM_PARENTNOTIFY
  • __GUIDarkTheme_NotifyProc is now __GUIDarkTheme_WndProc
    • Now handles WM_DPICHANGED and WM_PARENTNOTIFY in addition to WM_NOTIFY
  • Fixed an issue with __GUIDarkTheme_UpDownProc that sometimes showed theme-drawn UpDown
  • Switch from using _WinAPI_LockWindowUpdate to enabling/disabling WM_SETREDRAW

Latest download available in the first post of the topic. :)

 

Demo.au3 GUI scales with DPI changes now and GUIDarkTheme UDF itself also handles DPI changes now to ensure that the sharpest theme resources are always used. 🤩

Edited by WildByDesign
Posted

GUIDarkTheme 2026.09.30

  • Fixed a subclassing crash caused by TrayAutoPause - thanks to argumentum
    • Disabled TrayAutoPause in the UDF to prevent crash
    • Added #NoTrayIcon to Demo.au3 since tray icon is not needed
  • Fixed a dialog window crash caused by dialog subclass
    • This only seemed to affect the Choose Font dialog
  • Fixed keyboard prefix underline not showing on menu bar when pressing Alt
  • Updated PMv2 UDF with smoother DPI scaling

Latest download available in the first post of the topic. :)

Posted

GUIDarkTheme 2026.10.03

  • The Demo now automatically detects the OS color mode and resecpts it
    • Demo also automatically changes color mode when OS color mode changes
  • Fixed auto-switch theme with OS color mode change to synchronize with manual changes (Toggle Theme)
  • Added custom window message $__DM_WM_COLORMODECHANGED
    • This helps with timing of swapping ImageLists
  • Fixed dark checkboxes in TreeView/ListView being reverted to light during DPI changes
    • Added internal function __DM_ScaleCheckBoxes for this purpose
  • Reorganized the structure of the GUIDarkTheme zip archive

Latest download available in the first post of the topic. :)

Posted

GUIDarkTheme 2026.10.26

  • Added dark theme for ListView group headers with custom draw
  • Added numerous improvements for Slider/Trackbar controls
    • Drawing theme parts with uxtheme for better performance
    • Added double buffering to prevent flicker
    • Handling WM_ERASEBKGND to prevent flicker
  • Performance improvements for tab control custom drawing
    • This was done by making child control enumeration approx. 10x faster

Latest download available in the first post of the topic. :)

Posted

And here is a small example for anyone curious about how the ListView group header custom drawing looks.

#include <WindowsConstants.au3>
#include <ColorConstants.au3>
#include <GUIConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include <WinAPITheme.au3>
#include "..\Includes\GUIDarkTheme.au3"

_PM_Init()

Example()

Func Example()
    Local $hGUI = GUICreate("ListView Group Header CustomDraw", 370, 240)
    GUISetBkColor(0x202020)

    Local $iStyle = BitOR($GUI_SS_DEFAULT_LISTVIEW, $LVS_NOCOLUMNHEADER)
    Local $iExStyle = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER, $LVS_EX_CHECKBOXES)
    Local $idListview = GUICtrlCreateListView("", 10, 10, 350, 220, $iStyle, $iExStyle)
    GUICtrlSetBkColor(-1, 0x383838)
    GUICtrlSetColor(-1, 0xFFFFFF)

    _GUICtrlListView_AddColumn($idListview, "Column 1", 300)

    _GUICtrlListView_AddItem($idListview, "custom-userProfileMinimal", 0)
    _GUICtrlListView_AddItem($idListview, "custom-volumeRootMinimal", 1)
    _GUICtrlListView_AddItem($idListview, "lpacAppExperience", 2)
    _GUICtrlListView_AddItem($idListview, "lpacWebPlatform", 3)
    _GUICtrlListView_AddItem($idListview, "registryRead", 4)
    _GUICtrlListView_AddItem($idListview, "runFullTrust", 5)

    _GUICtrlListView_EnableGroupView($idListview, True)
    _GUICtrlListView_InsertGroup($idListview, -1, 1, "Group 1")
    _GUICtrlListView_InsertGroup($idListview, -1, 2, "Group 2")
    _GUICtrlListView_InsertGroup($idListview, -1, 3, "Group 3")
    _GUICtrlListView_SetItemGroupID($idListview, 0, 1)
    _GUICtrlListView_SetItemGroupID($idListview, 1, 1)
    _GUICtrlListView_SetItemGroupID($idListview, 2, 2)
    _GUICtrlListView_SetItemGroupID($idListview, 3, 2)
    _GUICtrlListView_SetItemGroupID($idListview, 4, 3)
    _GUICtrlListView_SetItemGroupID($idListview, 5, 3)

    _GUICtrlListView_SetColumnWidth($idListview, 0, $LVSCW_AUTOSIZE_USEHEADER)

    _GUICtrlListView_SetGroupInfo($idListview, 1, "Custom Capabilities", 0, BitOR($LVGS_COLLAPSED, $LVGS_COLLAPSIBLE))
    _GUICtrlListView_SetGroupInfo($idListview, 2, "LPAC Capabilities", 1, BitOR($LVGS_COLLAPSED, $LVGS_COLLAPSIBLE))
    _GUICtrlListView_SetGroupInfo($idListview, 3, "Common Capabilities", 2, BitOR($LVGS_COLLAPSED, $LVGS_COLLAPSIBLE))

    _WinAPI_SetWindowTheme(GUICtrlGetHandle($idListview), "DarkMode_Explorer")
    _SendMessage(GUICtrlGetHandle($idListview), $WM_CHANGEUISTATE, 65537, 0)
    _WinAPI_DwmSetWindowAttribute($hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True)

    _GUIDarkTheme_ApplyAuto($hGUI)
    _PM_Scale($hGUI)

    GUISetState(@SW_SHOW)

    While True
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
EndFunc   ;==>Example

 

Posted

GUIDarkTheme 2026.11.03

  • Changed ListView theme to DarkMode_ItemsView to support groups natively
  • Removed GUIDarkTheme UDF dependency on PMv2 UDF
    • Both UDFs can be used separately or together
  • Added dark theme support for UDF-created ListView controls
  • Added dark theme support for UDF-created TreeView controls
  • Updated internal function __DM_DarkThemeAvailability to do a binary check for DarkMode_DarkTheme
  • Fixed ListBox theme style for selected item
  • Separated WM_DPICHANGED from original __GUIDarkTheme_WndProc
    • __GUIDarkTheme_DpiProc to handle WM_DPICHANGED for scaling
    • The order of subclassing for WM_DPICHANGED needed to change for LIFO (Last-In, First-Out)
  • Some functionality that was difficult for AutoIt (perf) offloaded to high-performance C++ module using MinHook
    • ThemeHook-x64.dll 21KB or ThemeHook-x86.dll 17KB is loaded (memory only) from Base64
    • GetSysColor and GetSysColorBrush hooked (current process only instead of system-wide)
    • Only hooking COLOR_MENU right now but any of the $COLOR_* SysColors can be hooked for dark colors
    • This allows for a single compiled binary without bundling DLLs
    • Ensures that all Scrollbars (ListView, GUI, etc.) are dark themed
    • Handles the painting of the 1px white line under dark menubar
      • This got rid of the busy AutoIt subclassing for WM_WINDOWPOSCHANGED (and WM_NCACTIVATE)
  • Removed lots of unneeded code

Latest download available in the first post of the topic. :)

Posted

And for the purpose of transparency, since that is important to me, here is the C++ code for the ThemeHook DLL:

My intention here was to offload some of the things that really affected the performance of AutoIt the most. Painting of the 1px white line under the dark menubar was definitely one of those performance things. Ensuring that all scrollbars, even non-client area of controls like ListView, get dark theming is something that could not be done in AutoIt. I got the idea from @NoNameCode in the DarkMode UDF for AutoIt's Win32GUIs thread. Version V.03 of that UDF added HookOpenNcThemeData.dll which does exactly as the file name suggests. It hooks OpenNcThemeData and changes all "Scrollbar" internal theme resources to "Explorer::Scrollbar" which does dark or light theme depending on what is set.

Hooking GetSysColor and GetSysColorBrush was also not possible in AutoIt. Right now I am just hooking COLOR_MENU which is used by that 1px white line under the dark menubar. But this can easily be expanded and hook any of the $COLOR_* SysColors which is pretty neat. I am just playing it careful right now and only handling what I needed to be handled.

Anyway, fun stuff. Fun learning experience too. Mini DLL hook, high performance and running entirely from memory so that there is no DLL file on disk or bundled with a compiled binary. :)

#include <windows.h>
#include <uxtheme.h>
#include <delayimp.h>
#include <dbghelp.h>
#include <commctrl.h>
#include "MinHook.h"

#pragma comment(lib, "uxtheme.lib")
#pragma comment(lib, "delayimp.lib")
#pragma comment(lib, "dbghelp.lib")
#pragma comment(lib, "comctl32.lib")

// Function pointer types
typedef HTHEME(WINAPI* OpenThemeData_t)(HWND hwnd, LPCWSTR pszClassList);
typedef DWORD(WINAPI* GetSysColor_t)(int nIndex);
typedef HBRUSH(WINAPI* GetSysColorBrush_t)(int nIndex);

// Global function pointers & tracking variables
OpenThemeData_t fpOpenThemeData = nullptr;
OpenThemeData_t fpComCtlOpenNcThemeData = nullptr;
GetSysColor_t fpGetSysColor = nullptr;
GetSysColorBrush_t fpGetSysColorBrush = nullptr;
PIMAGE_THUNK_DATA g_pComCtlThunk = nullptr;

// Dynamic Color Configuration (Default: RGB 32, 32, 32)
COLORREF g_crWindowBg = RGB(32, 32, 32);

// Cached dark brush (recreated dynamically when color changes)
HBRUSH g_hDarkWindowBrush = nullptr;

// Helper to update and recreate brush safely
void UpdateBrush() {
    if (g_hDarkWindowBrush) DeleteObject(g_hDarkWindowBrush);

    g_hDarkWindowBrush = CreateSolidBrush(g_crWindowBg);
}

// ---------------------------------------------------------
// 1. ScrollBar Hooks
// ---------------------------------------------------------

HTHEME WINAPI DetourOpenThemeData(HWND hwnd, LPCWSTR pszClassList) {
    if (pszClassList) {
        if (wcscmp(pszClassList, L"ScrollBar") == 0 || wcsstr(pszClassList, L"ScrollBar") != nullptr) {
            return fpOpenThemeData(hwnd, L"Explorer::ScrollBar");
        }
    }
    return fpOpenThemeData(hwnd, pszClassList);
}

HTHEME WINAPI DetourComCtlOpenNcThemeData(HWND hwnd, LPCWSTR pszClassList) {
    if (pszClassList) {
        if (wcscmp(pszClassList, L"ScrollBar") == 0 || wcsstr(pszClassList, L"ScrollBar") != nullptr) {
            return fpComCtlOpenNcThemeData(nullptr, L"Explorer::ScrollBar");
        }
    }
    return fpComCtlOpenNcThemeData(hwnd, pszClassList);
}

// ---------------------------------------------------------
// 2. System Color Hooks (GetSysColor & GetSysColorBrush)
// ---------------------------------------------------------

DWORD WINAPI DetourGetSysColor(int nIndex) {
    switch (nIndex) {
    case COLOR_MENU:          return g_crWindowBg;
    }
    return fpGetSysColor(nIndex);
}

HBRUSH WINAPI DetourGetSysColorBrush(int nIndex) {
    switch (nIndex) {
    case COLOR_MENU:          return g_hDarkWindowBrush;
    }
    return fpGetSysColorBrush(nIndex);
}

// ---------------------------------------------------------
// 3. Helper for Delay-Load Thunks
// ---------------------------------------------------------

PIMAGE_THUNK_DATA FindDelayLoadThunkByOrdinal(HMODULE hMod, LPCSTR targetDllName, WORD ordinal) {
    ULONG size = 0;
    PIMAGE_DELAYLOAD_DESCRIPTOR pDelayDesc = (PIMAGE_DELAYLOAD_DESCRIPTOR)ImageDirectoryEntryToDataEx(
        hMod, TRUE, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, &size, NULL);
    if (!pDelayDesc) return nullptr;

    for (; pDelayDesc->DllNameRVA; ++pDelayDesc) {
        LPCSTR dllName = (LPCSTR)((PBYTE)hMod + pDelayDesc->DllNameRVA);
        if (_stricmp(dllName, targetDllName) == 0) {
            PIMAGE_THUNK_DATA pIAT = (PIMAGE_THUNK_DATA)((PBYTE)hMod + pDelayDesc->ImportAddressTableRVA);
            PIMAGE_THUNK_DATA pINT = (PIMAGE_THUNK_DATA)((PBYTE)hMod + pDelayDesc->ImportNameTableRVA);
            for (; pINT->u1.AddressOfData; ++pINT, ++pIAT) {
                if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal)) {
                    if (IMAGE_ORDINAL(pINT->u1.Ordinal) == ordinal) {
                        return pIAT;
                    }
                }
            }
        }
    }
    return nullptr;
}

// ---------------------------------------------------------
// 4. Exported Hook & Configuration Functions
// ---------------------------------------------------------

extern "C" __declspec(dllexport) void SetThemeColor(COLORREF rgbBackground) {
    g_crWindowBg = rgbBackground;

    UpdateBrush();
}

extern "C" __declspec(dllexport) bool InstallHook() {
    UpdateBrush();

    if (MH_Initialize() != MH_OK) return false;

    // 1. Hook standard OpenThemeData (uxtheme.dll)
    HMODULE hUxTheme = GetModuleHandleW(L"uxtheme.dll");
    if (!hUxTheme) hUxTheme = LoadLibraryW(L"uxtheme.dll");
    if (hUxTheme) {
        LPVOID pTarget = (LPVOID)GetProcAddress(hUxTheme, "OpenThemeData");
        if (pTarget) {
            MH_CreateHook(pTarget, &DetourOpenThemeData, reinterpret_cast<LPVOID*>(&fpOpenThemeData));
            MH_EnableHook(pTarget);
        }
    }

    // 2. Hook user32 system color functions (GetSysColor & GetSysColorBrush)
    HMODULE hUser32 = GetModuleHandleW(L"user32.dll");
    if (hUser32) {
        LPVOID pGetSysColorTarget = (LPVOID)GetProcAddress(hUser32, "GetSysColor");
        if (pGetSysColorTarget) {
            MH_CreateHook(pGetSysColorTarget, &DetourGetSysColor, reinterpret_cast<LPVOID*>(&fpGetSysColor));
            MH_EnableHook(pGetSysColorTarget);
        }

        LPVOID pGetSysColorBrushTarget = (LPVOID)GetProcAddress(hUser32, "GetSysColorBrush");
        if (pGetSysColorBrushTarget) {
            MH_CreateHook(pGetSysColorBrushTarget, &DetourGetSysColorBrush, reinterpret_cast<LPVOID*>(&fpGetSysColorBrush));
            MH_EnableHook(pGetSysColorBrushTarget);
        }
    }

    // 3. Patch comctl32.dll delay-load thunk for OpenNcThemeData (Ordinal 49)
    HMODULE hComCtl = LoadLibraryExW(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
    if (hComCtl) {
        g_pComCtlThunk = FindDelayLoadThunkByOrdinal(hComCtl, "uxtheme.dll", 49);
        if (g_pComCtlThunk) {
            DWORD oldProtect;
            if (VirtualProtect(&g_pComCtlThunk->u1.Function, sizeof(g_pComCtlThunk->u1.Function), PAGE_READWRITE, &oldProtect)) {
                fpComCtlOpenNcThemeData = (OpenThemeData_t)g_pComCtlThunk->u1.Function;
                g_pComCtlThunk->u1.Function = (DWORD_PTR)&DetourComCtlOpenNcThemeData;
                VirtualProtect(&g_pComCtlThunk->u1.Function, sizeof(g_pComCtlThunk->u1.Function), oldProtect, &oldProtect);
            }
        }
    }

    return true;
}

extern "C" __declspec(dllexport) void UninstallHook() {
    // 1. Restore the comctl32 delay-load thunk
    if (g_pComCtlThunk && fpComCtlOpenNcThemeData) {
        DWORD oldProtect;
        if (VirtualProtect(&g_pComCtlThunk->u1.Function, sizeof(g_pComCtlThunk->u1.Function), PAGE_READWRITE, &oldProtect)) {
            g_pComCtlThunk->u1.Function = (DWORD_PTR)fpComCtlOpenNcThemeData;
            VirtualProtect(&g_pComCtlThunk->u1.Function, sizeof(g_pComCtlThunk->u1.Function), oldProtect, &oldProtect);
        }
    }

    // 2. Disable hooks and uninitialize MinHook
    MH_DisableHook(MH_ALL_HOOKS);
    MH_Uninitialize();
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        break;
    case DLL_PROCESS_DETACH:
        if (g_hDarkWindowBrush) {
            DeleteObject(g_hDarkWindowBrush);
            g_hDarkWindowBrush = nullptr;
        }
        break;
    }
    return TRUE;
}

 

Posted
23 hours ago, WildByDesign said:

GUIDarkTheme 2026.11.03

  • Changed ListView theme to DarkMode_ItemsView to support groups natively
  • Removed GUIDarkTheme UDF dependency on PMv2 UDF
    • Both UDFs can be used separately or together
  • Added dark theme support for UDF-created ListView controls
  • Added dark theme support for UDF-created TreeView controls
  • Updated internal function __DM_DarkThemeAvailability to do a binary check for DarkMode_DarkTheme
  • Fixed ListBox theme style for selected item
  • Separated WM_DPICHANGED from original __GUIDarkTheme_WndProc
    • __GUIDarkTheme_DpiProc to handle WM_DPICHANGED for scaling
    • The order of subclassing for WM_DPICHANGED needed to change for LIFO (Last-In, First-Out)
  • Some functionality that was difficult for AutoIt (perf) offloaded to high-performance C++ module using MinHook
    • ThemeHook-x64.dll 21KB or ThemeHook-x86.dll 17KB is loaded (memory only) from Base64
    • GetSysColor and GetSysColorBrush hooked (current process only instead of system-wide)
    • Only hooking COLOR_MENU right now but any of the $COLOR_* SysColors can be hooked for dark colors
    • This allows for a single compiled binary without bundling DLLs
    • Ensures that all Scrollbars (ListView, GUI, etc.) are dark themed
    • Handles the painting of the 1px white line under dark menubar
      • This got rid of the busy AutoIt subclassing for WM_WINDOWPOSCHANGED (and WM_NCACTIVATE)
  • Removed lots of unneeded code

Latest download available in the first post of the topic. :)

this version is crashing on my system when launching demo.au3 from scite

Posted
7 minutes ago, jpm said:

this version is crashing on my system when launching demo.au3 from scite

Thanks for letting me know. It looks like the crash is x86-related. By default, my AutoIt runs scripts as x64 which is why I did not notice this initially. But I see the crash now when I specifically run the script as x86. I will look into this and get it fixed. :)

This reminds me. Just in the last 20 minutes I was actually thinking about how AutoIt installer by default has x86 selected for compatibility. So most users who go through the AutoIt installer quickly would end up with x86 by default. Since 32-bit Windows is no longer a thing supported by Microsoft, I feel like AutoIt installer should default to 64-bit interpreter. And allow the user to select the older x86 for compatibility if they need it.

  • Does anyone have any opinions on 64-bit AutoIt interpreter by default?
  • Also, should I even still support 32-bit or should I consider using #AutoIt3Wrapper_UseX64=Y in my scripts?

Either way, I should fix the x86 issue for now.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...