Patch for font size = 0x7fff in dialog templates

Koro webmaster at korosoft.net
Fri Aug 1 19:38:05 CDT 2008


This is a patch that fixes a discrepancy between WINE's dialog manager
and the real Windows one. If, in a dialog template, (assuming DS_SETFONT
is set) the font size is 0x7fff, it means that the dialog manager must
use the message box font and not read the rest of the font data
(facename and others) off the template.

This quirk is "documented" in a comment there, and I have myself
confirmed this behavior with some of my code a few months ago:
http://blogs.msdn.com/oldnewthing/archive/2005/04/29/412577.aspx#413552

Sending patch as attachment because putting it inline would probably
word-wrap it all over the place.

-------------- next part --------------
>From 057d46d0beb7c3d3687c816a2a3e7894e8a45db1 Mon Sep 17 00:00:00 2001
From: Koro <koro at k-vpc-xubuntu.(none)>
Date: Fri, 1 Aug 2008 20:10:06 -0400
Subject: Added support for 0x7fff font size in dialog templates. See http://blogs.msdn.com/oldnewthing/archive/2005/04/29/412577.aspx#413552

---
 dlls/user32/dialog.c |   74 +++++++++++++++++++++++++++++++++++++------------
 1 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/dlls/user32/dialog.c b/dlls/user32/dialog.c
index 444a73d..d7fa5ee 100644
--- a/dlls/user32/dialog.c
+++ b/dlls/user32/dialog.c
@@ -74,6 +74,7 @@ typedef struct
     LPCWSTR    menuName;
     LPCWSTR    className;
     LPCWSTR    caption;
+    BOOL       useMessageFont;
     INT16      pointSize;
     WORD       weight;
     BOOL       italic;
@@ -427,6 +428,7 @@ static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
 
     /* Get the font name */
 
+    result->useMessageFont = FALSE;
     result->pointSize = 0;
     result->faceName = NULL;
     result->weight = FW_DONTCARE;
@@ -436,16 +438,34 @@ static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
     {
         result->pointSize = GET_WORD(p);
         p++;
-        if (result->dialogEx)
+        
+        /* If pointSize is 0x7fff, it means that we need to use the font
+         * in NONCLIENTMETRICSW.lfMessageFont, and NOT read the weight,
+         * italic, and facename from the dialog template. */
+        if (result->pointSize == 0x7fff)
         {
-            result->weight = GET_WORD(p); p++;
-            result->italic = LOBYTE(GET_WORD(p)); p++;
+            /* We could call SystemParametersInfo here, but then we'd have
+             * to convert from pixel size to point size (which can be
+             * imprecise). Instead, we'll set a flag that will be picked
+             * up by DIALOG_CreateIndirect. */
+            
+            result->useMessageFont = TRUE;
+            TRACE(" FONT: Using message box font\n");
+        }
+        else
+        {
+            if (result->dialogEx)
+            {
+                result->weight = GET_WORD(p); p++;
+                result->italic = LOBYTE(GET_WORD(p)); p++;
+            }
+            result->faceName = (LPCWSTR)p;
+            p += strlenW( result->faceName ) + 1;
+        
+            TRACE(" FONT %d, %s, %d, %s\n",
+                  result->pointSize, debugstr_w( result->faceName ),
+                  result->weight, result->italic ? "TRUE" : "FALSE" );
         }
-        result->faceName = (LPCWSTR)p;
-        p += strlenW( result->faceName ) + 1;
-        TRACE(" FONT %d, %s, %d, %s\n",
-              result->pointSize, debugstr_w( result->faceName ),
-              result->weight, result->italic ? "TRUE" : "FALSE" );
     }
 
     /* First control is on dword boundary */
@@ -492,16 +512,34 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
 
     if (template.style & DS_SETFONT)
     {
-          /* We convert the size to pixels and then make it -ve.  This works
-           * for both +ve and -ve template.pointSize */
-        HDC dc;
-        int pixels;
-        dc = GetDC(0);
-        pixels = MulDiv(template.pointSize, GetDeviceCaps(dc , LOGPIXELSY), 72);
-        hUserFont = CreateFontW( -pixels, 0, 0, 0, template.weight,
-                                          template.italic, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
-                                          PROOF_QUALITY, FF_DONTCARE,
-                                          template.faceName );
+        HDC dc = GetDC(0);
+        
+        if (template.useMessageFont)
+        {
+            /* We get the message font from the non-client metrics */
+            NONCLIENTMETRICSW ncm;
+            
+            ncm.cbSize = sizeof(NONCLIENTMETRICSW);
+            if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
+                sizeof(NONCLIENTMETRICSW),
+                (void*) &ncm,
+                0L))
+            {
+                hUserFont = CreateFontIndirectW( &ncm.lfMessageFont );
+            }
+        }
+        else
+        {
+            /* We convert the size to pixels and then make it -ve.  This works
+             * for both +ve and -ve template.pointSize */
+            int pixels;
+            pixels = MulDiv(template.pointSize, GetDeviceCaps(dc , LOGPIXELSY), 72);
+            hUserFont = CreateFontW( -pixels, 0, 0, 0, template.weight,
+                                              template.italic, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
+                                              PROOF_QUALITY, FF_DONTCARE,
+                                              template.faceName );
+        }
+        
         if (hUserFont)
         {
             SIZE charSize;
-- 
1.5.4.3




More information about the wine-patches mailing list