user32: Patch for font size = 0x7fff in dialog templates (try #4)

Koro webmaster at korosoft.net
Fri Sep 26 11:32:38 CDT 2008


(Note: This is the fourth and last time I try to send this patch, the 
two previous times, I think the email got swallowed by my ISP's mail 
server because of wrongly set SPF on my domain)

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.

Credit the patch to Patrick Gauthier.

-------------- next part --------------
>From eb05fee5101be4448f065ba61bb85e6c98e09af2 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