comctl32: Implement LM_GETIDEALSIZE for the syslink control

Thomas Weidenmueller wine-patches at reactsoft.com
Mon Feb 19 09:25:01 CST 2007


Implements LM_GETIDEALSIZE for the syslink control.

- Thomas
-------------- next part --------------
Index: dlls/comctl32/syslink.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/syslink.c,v
retrieving revision 1.20
diff -u -r1.20 syslink.c
--- dlls/comctl32/syslink.c	14 Feb 2007 15:28:49 -0000	1.20
+++ dlls/comctl32/syslink.c	19 Feb 2007 15:20:25 -0000
@@ -643,18 +643,24 @@
  * SYSLINK_Render
  * Renders the document in memory
  */
-static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
+static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc, PRECT pRect)
 {
     RECT rc;
     PDOC_ITEM Current;
     HGDIOBJ hOldFont;
     int x, y, LineHeight;
-    
-    GetClientRect(infoPtr->Self, &rc);
+    SIZE szDoc;
+
+    szDoc.cx = szDoc.cy = 0;
+
+    rc = *pRect;
     rc.right -= SL_RIGHTMARGIN;
     rc.bottom -= SL_BOTTOMMARGIN;
-    
-    if(rc.right - SL_LEFTMARGIN < 0 || rc.bottom - SL_TOPMARGIN < 0) return;
+
+    if(rc.right - SL_LEFTMARGIN < 0)
+        rc.right = MAXLONG;
+    if (rc.bottom - SL_TOPMARGIN < 0)
+        rc.bottom = MAXLONG;
     
     hOldFont = SelectObject(hdc, infoPtr->Font);
     
@@ -715,6 +721,7 @@
             {
                 int LineLen = n;
                 BOOL Wrap = FALSE;
+                PDOC_TEXTBLOCK nbl;
                 
                 if(n != 0)
                 {
@@ -753,30 +760,12 @@
                     }
                 }
                 
-                if(bl != NULL)
-                {
-                    PDOC_TEXTBLOCK nbl = ReAlloc(bl, (nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
-                    if (nbl != NULL)
-                    {
-                        bl = nbl;
-                        nBlocks++;
-                    }
-                    else
-                    {
-                        Free(bl);
-                        bl = NULL;
-                        nBlocks = 0;
-                    }
-                }
-                else
-                {
-                    bl = Alloc(sizeof(DOC_TEXTBLOCK));
-                    if (bl != NULL)
-                        nBlocks++;
-                }
-                
-                if(bl != NULL)
+                nbl = ReAlloc(bl, (nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
+                if (nbl != NULL)
                 {
+                    bl = nbl;
+                    nBlocks++;
+
                     cbl = bl + nBlocks - 1;
                     
                     cbl->nChars = LineLen;
@@ -785,7 +774,12 @@
                     cbl->rc.top = y;
                     cbl->rc.right = x + szDim.cx;
                     cbl->rc.bottom = y + szDim.cy;
-                    
+
+                    if (cbl->rc.right > szDoc.cx)
+                        szDoc.cx = cbl->rc.right;
+                    if (cbl->rc.bottom > szDoc.cy)
+                        szDoc.cy = cbl->rc.bottom;
+
                     if(LineLen != 0)
                     {
                         x += szDim.cx;
@@ -801,6 +795,10 @@
                 }
                 else
                 {
+                    Free(bl);
+                    bl = NULL;
+                    nBlocks = 0;
+
                     ERR("Failed to alloc DOC_TEXTBLOCK structure!\n");
                     break;
                 }
@@ -820,6 +818,9 @@
     }
     
     SelectObject(hdc, hOldFont);
+
+    pRect->right = pRect->left + szDoc.cx;
+    pRect->bottom = pRect->top + szDoc.cy;
 }
 
 /***********************************************************************
@@ -920,6 +921,7 @@
     HDC hdc;
     LOGFONTW lf;
     TEXTMETRICW tm;
+    RECT rcClient;
     HFONT hOldFont = infoPtr->Font;
     infoPtr->Font = hFont;
     
@@ -931,24 +933,27 @@
     }
 
     /* Render text position and word wrapping in memory */
-    hdc = GetDC(infoPtr->Self);
-    if(hdc != NULL)
+    if (GetClientRect(infoPtr->Self, &rcClient))
     {
-        /* create a new underline font */
-        if(GetTextMetricsW(hdc, &tm) &&
-           GetObjectW(infoPtr->Font, sizeof(LOGFONTW), &lf))
-        {
-            lf.lfUnderline = TRUE;
-            infoPtr->LinkFont = CreateFontIndirectW(&lf);
-            infoPtr->BreakChar = tm.tmBreakChar;
-        }
-        else
+        hdc = GetDC(infoPtr->Self);
+        if(hdc != NULL)
         {
-            ERR("Failed to create link font!\n");
-        }
+            /* create a new underline font */
+            if(GetTextMetricsW(hdc, &tm) &&
+               GetObjectW(infoPtr->Font, sizeof(LOGFONTW), &lf))
+            {
+                lf.lfUnderline = TRUE;
+                infoPtr->LinkFont = CreateFontIndirectW(&lf);
+                infoPtr->BreakChar = tm.tmBreakChar;
+            }
+            else
+            {
+                ERR("Failed to create link font!\n");
+            }
 
-        SYSLINK_Render(infoPtr, hdc);
-        ReleaseDC(infoPtr->Self, hdc);
+            SYSLINK_Render(infoPtr, hdc, &rcClient);
+            ReleaseDC(infoPtr->Self, hdc);
+        }
     }
     
     if(bRedraw)
@@ -978,14 +983,19 @@
     /* let's parse the string and create a document */
     if(SYSLINK_ParseText(infoPtr, Text) > 0)
     {
+        RECT rcClient;
+
         /* Render text position and word wrapping in memory */
-        HDC hdc = GetDC(infoPtr->Self);
-        if (hdc != NULL)
+        if (GetClientRect(infoPtr->Self, &rcClient))
         {
-            SYSLINK_Render(infoPtr, hdc);
-            ReleaseDC(infoPtr->Self, hdc);
+            HDC hdc = GetDC(infoPtr->Self);
+            if (hdc != NULL)
+            {
+                SYSLINK_Render(infoPtr, hdc, &rcClient);
+                ReleaseDC(infoPtr->Self, hdc);
 
-            InvalidateRect(infoPtr->Self, NULL, TRUE);
+                InvalidateRect(infoPtr->Self, NULL, TRUE);
+            }
         }
     }
     
@@ -1076,6 +1086,7 @@
         else
         {
             Free(szId);
+
             ERR("Unable to allocate memory for link url\n");
             return FALSE;
         }
@@ -1503,6 +1514,33 @@
 }
 
 /***********************************************************************
+ *           SYSLINK_GetIdealSize
+ * Calculates the ideal size of a link control at a given maximum width.
+ */
+static VOID SYSLINK_GetIdealSize (SYSLINK_INFO *infoPtr, int cxMaxWidth, LPSIZE lpSize)
+{
+    RECT rc;
+    HDC hdc;
+
+    rc.left = rc.top = rc.bottom = 0;
+    rc.right = cxMaxWidth;
+
+    hdc = GetDC(infoPtr->Self);
+    if (hdc != NULL)
+    {
+        HGDIOBJ hOldFont = SelectObject(hdc, infoPtr->Font);
+
+        SYSLINK_Render(infoPtr, hdc, &rc);
+
+        SelectObject(hdc, hOldFont);
+        ReleaseDC(infoPtr->Self, hdc);
+
+        lpSize->cx = rc.right;
+        lpSize->cy = rc.bottom;
+    }
+}
+
+/***********************************************************************
  *           SysLinkWindowProc
  */
 static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
@@ -1542,11 +1580,15 @@
 
     case WM_SIZE:
     {
-        HDC hdc = GetDC(infoPtr->Self);
-        if(hdc != NULL)
+        RECT rcClient;
+        if (GetClientRect(infoPtr->Self, &rcClient))
         {
-          SYSLINK_Render(infoPtr, hdc);
-          ReleaseDC(infoPtr->Self, hdc);
+            HDC hdc = GetDC(infoPtr->Self);
+            if(hdc != NULL)
+            {
+                SYSLINK_Render(infoPtr, hdc, &rcClient);
+                ReleaseDC(infoPtr->Self, hdc);
+            }
         }
         return 0;
     }
@@ -1651,6 +1693,11 @@
         return SYSLINK_GetItem(infoPtr, (PLITEM)lParam);
 
     case LM_GETIDEALHEIGHT:
+        if (lParam)
+        {
+            /* LM_GETIDEALSIZE */
+            SYSLINK_GetIdealSize(infoPtr, (int)wParam, (LPSIZE)lParam);
+        }
         return SYSLINK_GetIdealHeight(infoPtr);
 
     case WM_SETFOCUS:
@@ -1660,10 +1707,10 @@
         return SYSLINK_KillFocus(infoPtr, (HWND)wParam);
 
     case WM_ENABLE:
-	infoPtr->Style &= ~WS_DISABLED;
-	infoPtr->Style |= (wParam ? 0 : WS_DISABLED);
-	InvalidateRect (infoPtr->Self, NULL, FALSE);
-	return 0;
+        infoPtr->Style &= ~WS_DISABLED;
+        infoPtr->Style |= (wParam ? 0 : WS_DISABLED);
+        InvalidateRect (infoPtr->Self, NULL, FALSE);
+        return 0;
 
     case WM_STYLECHANGED:
         if (wParam == GWL_STYLE)
@@ -1710,7 +1757,7 @@
 HandleDefaultMessage:
         if ((message >= WM_USER) && (message < WM_APP))
         {
-	        ERR("unknown msg %04x wp=%04x lp=%08lx\n", message, wParam, lParam );
+            ERR("unknown msg %04x wp=%04x lp=%08lx\n", message, wParam, lParam );
         }
         return DefWindowProcW(hwnd, message, wParam, lParam);
     }
Index: include/commctrl.h
===================================================================
RCS file: /home/wine/wine/include/commctrl.h,v
retrieving revision 1.167
diff -u -r1.167 commctrl.h
--- include/commctrl.h	19 Feb 2007 13:03:31 -0000	1.167
+++ include/commctrl.h	19 Feb 2007 15:22:07 -0000
@@ -4889,6 +4889,7 @@
 /* SysLink messages */
 #define LM_HITTEST           (WM_USER + 768)
 #define LM_GETIDEALHEIGHT    (WM_USER + 769)
+#define LM_GETIDEALSIZE      (LM_GETIDEALHEIGHT)
 #define LM_SETITEM           (WM_USER + 770)
 #define LM_GETITEM           (WM_USER + 771)
 


More information about the wine-patches mailing list