WildByDesign Posted Thursday at 09:54 AM Posted Thursday at 09:54 AM I'm trying to create a dark mode ChooseFont dialog. The initial hook proc with fnHook / CF_ENABLEHOOK has been successful. However, attempting to load ChooseFont dialog with a custom Font.DLG file has not been successful at all. I have tried a few variations with $CF_ENABLETEMPLATE which failed and a few variations with $CF_ENABLETEMPLATEHANDLE that also failed. If anyone is able to help with this, that would be fantastic. I searched back in the forum and could not find any usage of lpTemplateName with the ChooseFont dialog. In the _ChooseFontHooked() function, I left a comment "Hook and template testing" on line 66 which is the start of the area testing hook and template stuff. Thank you for your time. Font.DLG DARKFONTDLG DIALOG 13, 54, 243, 234 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_3DLOOK CAPTION "Font" FONT 9, "Segoe UI" BEGIN LTEXT "&Font:", stc1, 7, 7, 98, 9 COMBOBOX cmb1, 7, 16, 98, 76, CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS | CBS_OWNERDRAWFIXED LTEXT "Font st&yle:", stc2, 114, 7, 74, 9 COMBOBOX cmb2, 114, 16, 74, 76, CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS | CBS_OWNERDRAWFIXED LTEXT "&Size:", stc3, 198, 7, 36, 9 COMBOBOX cmb3, 198, 16, 36, 76, CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS GROUPBOX "Effects", grp1, 7, 97, 98, 76, WS_GROUP AUTOCHECKBOX "Stri&keout", chx1, 13, 111, 90, 10, WS_TABSTOP AUTOCHECKBOX "&Underline", chx2, 13, 127, 90, 10 LTEXT "&Color:", stc4, 13, 144, 89, 9 COMBOBOX cmb4, 13, 155, 85, 100, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP GROUPBOX "Sample", grp2, 114, 97, 120, 43, WS_GROUP CTEXT "AaBbYyZz", stc5, 116, 106, 117, 33, SS_NOPREFIX | NOT WS_VISIBLE LTEXT "", stc6, 7, 178, 227, 20, SS_NOPREFIX | NOT WS_GROUP LTEXT "Sc&ript:", stc7, 114, 145, 118, 9 COMBOBOX cmb5, 114, 155, 120, 30, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP CONTROL "<A>Show more fonts</A>", IDC_MANAGE_LINK, "SysLink", WS_TABSTOP, 7, 199, 227, 9 DEFPUSHBUTTON "OK", IDOK, 141, 215, 45, 14, WS_GROUP PUSHBUTTON "Cancel", IDCANCEL, 190, 215, 45, 14, WS_GROUP PUSHBUTTON "&Apply", psh3, 92, 215, 45, 14, WS_GROUP PUSHBUTTON "&Help", pshHelp, 43, 215, 45, 14, WS_GROUP END Testing script: expandcollapse popup#include <WinAPIProc.au3> #include <FontConstants.au3> #include <StructureConstants.au3> #include <GUIConstantsEx.au3> #include <APIGdiConstants.au3> #include <SendMessage.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsStylesConstants.au3> #include <WinAPIGdiInternals.au3> #include <WinAPIGdiDC.au3> #include <AutoItConstants.au3> #include <WindowsNotifsConstants.au3> #include <WinAPIGdi.au3> #include <Misc.au3> ; Initialize System DPI awareness DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Global Const $CF_ENABLEHOOK = 8 Global Const $CF_ENABLETEMPLATE = 16 Global Const $CF_ENABLETEMPLATEHANDLE = 32 Global Const $sTemplate = @ScriptDir & "\font.dlg" Global Const $sTemplateName = "DARKFONTDLG" Global $hTemplate = FileOpen($sTemplate) Global $g_hDialogProc = 0 _ChooseFontHooked() FileClose($hTemplate) Func _ChooseFontHooked($sFontName = "Courier New", $iPointSize = 10, $iFontColorRef = Default, $iFontWeight = 0, $bItalic = False, $bUnderline = False, $bStrikethru = False, $hWndOwner = 0) Local $iItalic = 0, $iUnderline = 0, $iStrikeout = 0, $iRetExtended = 0 If $sFontName = Default Then $sFontName = "Courier New" If $iPointSize = Default Then $iPointSize = 10 If $iFontColorRef = Default Then $iFontColorRef = 0 Local $aRet = DllCall("user32.dll", "int", "GetSysColor", "int", 18) ; $COLOR_BTNTEXT If @error Then $iRetExtended = @error Else $iFontColorRef = $aRet[0] EndIf EndIf If $iFontWeight = Default Then $iFontWeight = 0 If $bItalic = Default Then $bItalic = False If $bUnderline = Default Then $bUnderline = False If $bStrikethru = Default Then $bStrikethru = False If $hWndOwner = Default Then $hWndOwner = 0 $iFontColorRef = BitOR(BitShift(BitAND($iFontColorRef, 0x000000FF), -16), BitAND($iFontColorRef, 0x0000FF00), BitShift(BitAND($iFontColorRef, 0x00FF0000), 16)) Local $hDC = __MISC_GetDC(0) Local $iHeight = Round(($iPointSize * __MISC_GetDeviceCaps($hDC, $LOGPIXELSX)) / 72, 0) __MISC_ReleaseDC(0, $hDC) Local $tChooseFont = DllStructCreate($tagCHOOSEFONT) Local $tLogFont = DllStructCreate($tagLOGFONT) DllStructSetData($tChooseFont, "Size", DllStructGetSize($tChooseFont)) DllStructSetData($tChooseFont, "hWndOwner", $hWndOwner) DllStructSetData($tChooseFont, "LogFont", DllStructGetPtr($tLogFont)) DllStructSetData($tChooseFont, "PointSize", $iPointSize) ; Hook and template testing $g_hDialogProc = DllCallbackRegister(_DialogProc, "int", "hwnd;uint;wparam;lparam") DllStructSetData($tChooseFont, 'fnHook', DllCallbackGetPtr($g_hDialogProc)) ;DllStructSetData($tChooseFont, "Flags", BitOR($CF_SCREENFONTS, $CF_PRINTERFONTS, $CF_EFFECTS, $CF_INITTOLOGFONTSTRUCT, $CF_NOSCRIPTSEL, $CF_ENABLEHOOK)) ; <<< this works with hook but no custom template DllStructSetData($tChooseFont, "Flags", BitOR($CF_SCREENFONTS, $CF_PRINTERFONTS, $CF_EFFECTS, $CF_INITTOLOGFONTSTRUCT, $CF_NOSCRIPTSEL, $CF_ENABLEHOOK, $CF_ENABLETEMPLATE)) ;DllStructSetData($tChooseFont, "Flags", BitOR($CF_SCREENFONTS, $CF_PRINTERFONTS, $CF_EFFECTS, $CF_INITTOLOGFONTSTRUCT, $CF_NOSCRIPTSEL, $CF_ENABLEHOOK, $CF_ENABLETEMPLATEHANDLE)) ;DllStructSetData($tChooseFont, 'hInstance', $hTemplate) DllStructSetData($tChooseFont, 'hInstance', Null) Local $tagBuffer = "char[4096]", $iBufferSize = 4095 ;If $fUnicode Then $tagBuffer = "w" & $tagBuffer Local $tTemplateName = DllStructCreate($tagBuffer);'char[256]') DllStructSetData($tTemplateName, 1, $sTemplateName) DllStructSetData($tChooseFont, 'lpTemplateName', DllStructGetPtr($tTemplateName)) DllStructSetData($tChooseFont, "rgbColors", $iFontColorRef) DllStructSetData($tChooseFont, "FontType", 0) DllStructSetData($tLogFont, "Height", $iHeight) DllStructSetData($tLogFont, "Weight", $iFontWeight) DllStructSetData($tLogFont, "Italic", $bItalic) DllStructSetData($tLogFont, "Underline", $bUnderline) DllStructSetData($tLogFont, "Strikeout", $bStrikethru) DllStructSetData($tLogFont, "FaceName", $sFontName) Local $aCall = DllCall("comdlg32.dll", "bool", "ChooseFontW", "struct*", $tChooseFont) If @error Then Return SetError(@error, @extended, -2) ; ..to differentiate from the error below If $aCall[0] = 0 Then Return SetError(-3, $iRetExtended, -1) ; user selected cancel or struct settings incorrect Local $sFaceName = DllStructGetData($tLogFont, "FaceName") If StringLen($sFaceName) = 0 And StringLen($sFontName) > 0 Then $sFaceName = $sFontName If DllStructGetData($tLogFont, "Italic") Then $iItalic = 2 If DllStructGetData($tLogFont, "Underline") Then $iUnderline = 4 If DllStructGetData($tLogFont, "Strikeout") Then $iStrikeout = 8 Local $iAttributes = BitOR($iItalic, $iUnderline, $iStrikeout) Local $iSize = DllStructGetData($tChooseFont, "PointSize") / 10 Local $iColorRef = DllStructGetData($tChooseFont, "rgbColors") Local $iWeight = DllStructGetData($tLogFont, "Weight") Local $sColor_picked = Hex(String($iColorRef), 6) Return SetError(0, $iRetExtended, StringSplit($iAttributes & "," & $sFaceName & "," & $iSize & "," & $iWeight & "," & $iColorRef & "," & _ '0x' & $sColor_picked & "," & '0x' & StringMid($sColor_picked, 5, 2) & StringMid($sColor_picked, 3, 2) & StringMid($sColor_picked, 1, 2), ",")) EndFunc ;==>_ChooseFontHooked Func _DialogProc($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Local Static $hBrush Switch $iMsg Case $WM_INITDIALOG _WinAPI_DwmSetWindowAttribute($hWnd, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) $hBrush = _WinAPI_CreateSolidBrush(0x202020) Local $aCtrlsEx = _WinAPI_EnumProcessWindows(0, False) ; allows getting handles for tooltips_class32, ComboLBox, etc. If @error = 0 Then For $i = 1 To $aCtrlsEx[0][0] ;If $aCtrlsEx[$i][1] = 'tooltips_class32' Then _GUIDarkTheme_GUICtrlSetDarkTheme($hGui, $aCtrlsEx[$i][0], $bEnableDarkTheme) If $aCtrlsEx[$i][1] = 'ComboLBox' Then _WinAPI_SetWindowTheme($aCtrlsEx[$i][0], "DarkMode_Explorer") _SendMessage($aCtrlsEx[$i][0], $WM_THEMECHANGED, 0, 0) EndIf Next EndIf ; Find all controls to apply dark theme Local $aCtrls = _WinAPI_EnumChildWindows($hWnd, False) If @error = 0 Then For $i = 1 To $aCtrls[0][0] ;ConsoleWrite("class: " & $aCtrls[$i][1] & " hwnd: " & $aCtrls[$i][0] & @CRLF) If $aCtrls[$i][1] = "Button" Then _WinAPI_SetWindowTheme($aCtrls[$i][0], "DarkMode_Explorer") ;_WinAPI_SetWindowTheme($aCtrls[$i][0], "DarkMode_DarkTheme") ; DarkMode_DarkTheme needed for group box _SendMessage($aCtrls[$i][0], $WM_THEMECHANGED, 0, 0) EndIf If $aCtrls[$i][1] = "ComboBox" Then _WinAPI_SetWindowTheme($aCtrls[$i][0], "DarkMode_CFD") _SendMessage($aCtrls[$i][0], $WM_THEMECHANGED, 0, 0) EndIf If $aCtrls[$i][1] = "ComboLBox" Then _WinAPI_SetWindowTheme($aCtrls[$i][0], "DarkMode_Explorer") _SendMessage($aCtrls[$i][0], $WM_THEMECHANGED, 0, 0) EndIf If $aCtrls[$i][1] = "Edit" Then _WinAPI_SetWindowTheme($aCtrls[$i][0], "DarkMode_Explorer") _SendMessage($aCtrls[$i][0], $WM_THEMECHANGED, 0, 0) _WinAPI_SetWindowLong($aCtrls[$i][0], $GWL_EXSTYLE, BitAND(_WinAPI_GetWindowLong($aCtrls[$i][0], $GWL_EXSTYLE), BitNOT($WS_EX_CLIENTEDGE))) _WinAPI_SetWindowLong($aCtrls[$i][0], $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($aCtrls[$i][0], $GWL_EXSTYLE), $WS_EX_STATICEDGE)) _WinAPI_SetWindowPos($aCtrls[$i][0], 0, 0, 0, 0, 0, BitOR($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOZORDER, $SWP_FRAMECHANGED)) EndIf Next EndIf Case $WM_SHOWWINDOW ; center dialog on desktop Local $aChildPos = WinGetPos($hWnd) WinMove($hWnd, "", (@DesktopWidth / 2 - ($aChildPos[2] / 2)), (@DesktopHeight / 2 - ($aChildPos[3] / 2))) Case $WM_CTLCOLORSTATIC, $WM_CTLCOLORDLG _WinAPI_SetBkMode($wParam, $TRANSPARENT) _WinAPI_SetTextColor($wParam, 0xFFFFFF) Return $hBrush Case $WM_CTLCOLOREDIT, $WM_CTLCOLORLISTBOX _WinAPI_SetBkMode($wParam, $TRANSPARENT) _WinAPI_SetTextColor($wParam, 0xFFFFFF) Return $hBrush Case $WM_CTLCOLORBTN _WinAPI_SetBkColor($wParam, 0x000000) ; needed for focus rectangle Return $hBrush Case $WM_DESTROY _WinAPI_DeleteObject($hBrush) EndSwitch EndFunc
ahmet Posted Thursday at 11:16 AM Posted Thursday at 11:16 AM (edited) I suppose that you need to save font.dlg to the resource of the exe file. There is ResHacker project that might assit you into adding that template into exe file. Edited Thursday at 11:17 AM by ahmet Edit: For hInstance maybe this will be necessary: _WinAPI_GetModuleHandle(Null) WildByDesign 1
WildByDesign Posted Thursday at 11:23 PM Author Posted Thursday at 11:23 PM 12 hours ago, ahmet said: I suppose that you need to save font.dlg to the resource of the exe file. Thanks for your response. Unfortunately I was really hoping to be able to achieve this without compiling to .dll or .exe binary. I'm starting to think that it might not be possible without compiling.
ahmet Posted 18 hours ago Posted 18 hours ago Dialog Box Resources can create file with the dialog resource. That way you can have an exe with only the resource. What is your goal?
argumentum Posted 17 hours ago Posted 17 hours ago 33 minutes ago, ahmet said: Dialog Box Resources can create file with the dialog resource. ..just run the thing and is too CPU intensive. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
WildByDesign Posted 16 hours ago Author Posted 16 hours ago 1 hour ago, ahmet said: What is your goal? I'm trying to replicate this C++ souce code in AutoIt: /** * @brief Hook procedure for customizing common dialogs with dark mode. * * This function handles messages for all Windows common dialogs. * When initialized (`WM_INITDIALOG`), it applies dark mode styling to the dialog. * * ## Special Case: Font Dialog Workaround * - When a hook is used with `ChooseFont`, Windows **automatically falls back** * to an **older template**, losing modern UI elements. * - To prevent this forced downgrade, a **modified template** (based on Font.dlg) is used. * - **CBS_OWNERDRAWFIXED should be removed** from the **Size** and **Script** combo boxes * to restore proper visualization. * - **Custom owner-draw visuals remain** for other font combo boxes to allow font preview. * - Same for the `"AaBbYyZz"` sample text. * - However **Automatic system translation for captions and static texts is lost** in this workaround. * * ## Custom Font Dialog Template (Resource File) * ```rc * IDD_DARK_FONT_DIALOG DIALOG 13, 54, 243, 234 * STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | * DS_3DLOOK * CAPTION "Font" * FONT 9, "Segoe UI" * BEGIN * LTEXT "&Font:", stc1, 7, 7, 98, 9 * COMBOBOX cmb1, 7, 16, 98, 76, * CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | * CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS | * CBS_OWNERDRAWFIXED * * LTEXT "Font st&yle:", stc2, 114, 7, 74, 9 * COMBOBOX cmb2, 114, 16, 74, 76, * CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | * WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS | * CBS_OWNERDRAWFIXED * * LTEXT "&Size:", stc3, 198, 7, 36, 9 * COMBOBOX cmb3, 198, 16, 36, 76, * CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | * CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS | * CBS_OWNERDRAWFIXED // remove CBS_OWNERDRAWFIXED * * GROUPBOX "Effects", grp1, 7, 97, 98, 76, WS_GROUP * AUTOCHECKBOX "Stri&keout", chx1, 13, 111, 90, 10, WS_TABSTOP * AUTOCHECKBOX "&Underline", chx2, 13, 127, 90, 10 * * LTEXT "&Color:", stc4, 13, 144, 89, 9 * COMBOBOX cmb4, 13, 155, 85, 100, * CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | * CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP * * GROUPBOX "Sample", grp2, 114, 97, 120, 43, WS_GROUP * CTEXT "AaBbYyZz", stc5, 116, 106, 117, 33, * SS_NOPREFIX | NOT WS_VISIBLE * LTEXT "", stc6, 7, 178, 227, 20, SS_NOPREFIX | NOT WS_GROUP * * LTEXT "Sc&ript:", stc7, 114, 145, 118, 9 * COMBOBOX cmb5, 114, 155, 120, 30, CBS_DROPDOWNLIST | * CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_HASSTRINGS | // remove CBS_OWNERDRAWFIXED * WS_BORDER | WS_VSCROLL | WS_TABSTOP * * CONTROL "<A>Show more fonts</A>", IDC_MANAGE_LINK, "SysLink", * WS_TABSTOP, 7, 199, 227, 9 * * DEFPUSHBUTTON "OK", IDOK, 141, 215, 45, 14, WS_GROUP * PUSHBUTTON "Cancel", IDCANCEL, 190, 215, 45, 14, WS_GROUP * PUSHBUTTON "&Apply", psh3, 92, 215, 45, 14, WS_GROUP * PUSHBUTTON "&Help", pshHelp, 43, 215, 45, 14, WS_GROUP * END * ``` * * ## Usage Example: * ```cpp * #define IDD_DARK_FONT_DIALOG 1000 // usually in resource.h or other header * * CHOOSEFONT cf{}; * cf.Flags |= CF_ENABLEHOOK | CF_ENABLETEMPLATE; * cf.lpfnHook = static_cast<LPCFHOOKPROC>(dmlib::HookDlgProc); * cf.hInstance = GetModuleHandle(nullptr); * cf.lpTemplateName = MAKEINTRESOURCE(IDD_DARK_FONT_DIALOG); * ``` * * @param[in] hWnd Handle to the dialog window. * @param[in] uMsg Message identifier. * @param[in] wParam First message parameter (unused). * @param[in] lParam Second message parameter (unused). * @return UINT_PTR A value defined by the hook procedure. */ Unfortunately, $CBS_OWNERDRAWFIXED is a style that cannot be removed with _WinAPI_SetWindowLong() after the dialog has already been created. So the technique that I am attempting to do involves loading a modified Font.Dlg template which has $CBS_OWNERDRAWFIXED already removed.
argumentum Posted 16 hours ago Posted 16 hours ago ..if you can load the fancy combo with each line having the font applied to it, we can use that and make out own GUI. Is an interface to choose a font and that's all that is. Go figure if in 27H2 they fix it 🤷♂️ So if this approach don't work out, look for a pleasing familiar ( visually GUI wise ) and go with that. Am sure one of those MVPs will snick it in the standard UDFs somehow 😇 WildByDesign 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
ahmet Posted 2 hours ago Posted 2 hours ago 15 hours ago, argumentum said: ..just run the thing and is too CPU intensive. I did not spot any issues with the Dialog_Box_Resources.au3. There is high CPU usage with the generated files becuse of While loop without Sleep. Once you put sleep in the generated file CPU usage drops.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now