RESEND: [comctl32] Reduce memory usage of the syslink control

Thomas Weidenmueller wine-patches at reactsoft.com
Fri Dec 30 10:19:49 CST 2005


Reduce memory usage of the syslink control.

- Thomas
-------------- next part --------------
Index: dlls/comctl32/syslink.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/syslink.c,v
retrieving revision 1.15
diff -u -r1.15 syslink.c
--- dlls/comctl32/syslink.c	21 Nov 2005 13:34:06 -0000	1.15
+++ dlls/comctl32/syslink.c	30 Dec 2005 16:18:31 -0000
@@ -62,7 +62,6 @@
 typedef struct _DOC_ITEM
 {
     struct _DOC_ITEM *Next; /* Address to the next item */
-    LPWSTR Text;            /* Text of the document item */
     UINT nText;             /* Number of characters of the text */
     SL_ITEM_TYPE Type;      /* type of the item */
     PDOC_TEXTBLOCK Blocks;  /* Array of text blocks */
@@ -79,6 +78,7 @@
             UINT Dummy;
         } Text;
     } u;
+    WCHAR Text[1];          /* Text of the document item */
 } DOC_ITEM, *PDOC_ITEM;
 
 typedef struct
@@ -117,8 +117,14 @@
 {
     if(DocItem->Type == slLink)
     {
-        Free(DocItem->u.Link.szID);
-        Free(DocItem->u.Link.szUrl);
+        if (DocItem->u.Link.szID != NULL)
+        {
+            Free(DocItem->u.Link.szID);
+        }
+        if (DocItem->u.Link.szUrl != NULL)
+        {
+            Free(DocItem->u.Link.szUrl);
+        }
     }
 
     /* we don't free Text because it's just a pointer to a character in the
@@ -135,16 +141,16 @@
                                         SL_ITEM_TYPE type, PDOC_ITEM LastItem)
 {
     PDOC_ITEM Item;
-    Item = Alloc(sizeof(DOC_ITEM) + ((textlen + 1) * sizeof(WCHAR)));
+
+    textlen = min(textlen, lstrlenW(Text));
+    Item = Alloc(FIELD_OFFSET(DOC_ITEM, Text[textlen + 1]));
     if(Item == NULL)
     {
         ERR("Failed to alloc DOC_ITEM structure!\n");
         return NULL;
     }
-    textlen = min(textlen, lstrlenW(Text));
 
     Item->Next = NULL;
-    Item->Text = (LPWSTR)(Item + 1);
     Item->nText = textlen;
     Item->Type = type;
     Item->Blocks = NULL;
@@ -159,7 +165,6 @@
     }
     
     lstrcpynW(Item->Text, Text, textlen + 1);
-    Item->Text[textlen] = 0;
     
     return Item;
 }
@@ -351,12 +356,11 @@
                         if(lpID != NULL)
                         {
                             nc = min(lenId, strlenW(lpID));
-                            nc = min(nc, MAX_LINKID_TEXT);
-                            Last->u.Link.szID = Alloc((MAX_LINKID_TEXT + 1) * sizeof(WCHAR));
+                            nc = min(nc, MAX_LINKID_TEXT - 1);
+                            Last->u.Link.szID = Alloc((nc + 1) * sizeof(WCHAR));
                             if(Last->u.Link.szID != NULL)
                             {
                                 lstrcpynW(Last->u.Link.szID, lpID, nc + 1);
-                                Last->u.Link.szID[nc] = 0;
                             }
                         }
                         else
@@ -364,12 +368,11 @@
                         if(lpUrl != NULL)
                         {
                             nc = min(lenUrl, strlenW(lpUrl));
-                            nc = min(nc, L_MAX_URL_LENGTH);
-                            Last->u.Link.szUrl = Alloc((L_MAX_URL_LENGTH + 1) * sizeof(WCHAR));
+                            nc = min(nc, L_MAX_URL_LENGTH - 1);
+                            Last->u.Link.szUrl = Alloc((nc + 1) * sizeof(WCHAR));
                             if(Last->u.Link.szUrl != NULL)
                             {
                                 lstrcpynW(Last->u.Link.szUrl, lpUrl, nc + 1);
-                                Last->u.Link.szUrl[nc] = 0;
                             }
                         }
                         else
@@ -431,12 +434,11 @@
             if(lpID != NULL)
             {
                 nc = min(lenId, strlenW(lpID));
-                nc = min(nc, MAX_LINKID_TEXT);
-                Last->u.Link.szID = Alloc((MAX_LINKID_TEXT + 1) * sizeof(WCHAR));
+                nc = min(nc, MAX_LINKID_TEXT - 1);
+                Last->u.Link.szID = Alloc((nc + 1) * sizeof(WCHAR));
                 if(Last->u.Link.szID != NULL)
                 {
                     lstrcpynW(Last->u.Link.szID, lpID, nc + 1);
-                    Last->u.Link.szID[nc] = 0;
                 }
             }
             else
@@ -444,12 +446,11 @@
             if(lpUrl != NULL)
             {
                 nc = min(lenUrl, strlenW(lpUrl));
-                nc = min(nc, L_MAX_URL_LENGTH);
-                Last->u.Link.szUrl = Alloc((L_MAX_URL_LENGTH + 1) * sizeof(WCHAR));
+                nc = min(nc, L_MAX_URL_LENGTH - 1);
+                Last->u.Link.szUrl = Alloc((nc + 1) * sizeof(WCHAR));
                 if(Last->u.Link.szUrl != NULL)
                 {
                     lstrcpynW(Last->u.Link.szUrl, lpUrl, nc + 1);
-                    Last->u.Link.szUrl[nc] = 0;
                 }
             }
             else
@@ -751,6 +752,7 @@
                             {
                                 Free(bl);
                                 bl = NULL;
+                                nBlocks = 0;
                             }
                             break;
                         }
@@ -769,11 +771,12 @@
                     {
                         Free(bl);
                         bl = NULL;
+                        nBlocks = 0;
                     }
                 }
                 else
                 {
-                    bl = Alloc((nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
+                    bl = Alloc(sizeof(DOC_TEXTBLOCK));
                     if (bl != NULL)
                         nBlocks++;
                 }
@@ -820,8 +823,6 @@
         {
             Current->Blocks = bl;
         }
-        else
-            Current->Blocks = NULL;
     }
     
     SelectObject(hdc, hOldFont);
@@ -877,10 +878,10 @@
                 ExtTextOutW(hdc, bl->rc.left, bl->rc.top, ETO_OPAQUE | ETO_CLIPPED, &bl->rc, tx, bl->nChars, NULL);
                 if((Current->Type == slLink) && (Current->u.Link.state & LIS_FOCUSED) && infoPtr->HasFocus)
                 {
-                    COLORREF PrevColor;
-                    PrevColor = SetBkColor(hdc, OldBkColor);
+                    COLORREF PrevTextColor;
+                    PrevTextColor = SetTextColor(hdc, infoPtr->TextColor);
                     DrawFocusRect(hdc, &bl->rc);
-                    SetBkColor(hdc, PrevColor);
+                    SetTextColor(hdc, PrevTextColor);
                 }
                 tx += bl->nChars;
                 n -= bl->nChars + bl->nSkip;
@@ -907,8 +908,11 @@
     PAINTSTRUCT ps;
 
     hdc = hdcParam ? hdcParam : BeginPaint (infoPtr->Self, &ps);
-    SYSLINK_Draw (infoPtr, hdc);
-    if (!hdcParam) EndPaint (infoPtr->Self, &ps);
+    if (hdc)
+    {
+        SYSLINK_Draw (infoPtr, hdc);
+        if (!hdcParam) EndPaint (infoPtr->Self, &ps);
+    }
     return 0;
 }
 
@@ -972,8 +976,7 @@
     /* clear the document */
     SYSLINK_ClearDoc(infoPtr);
     
-    textlen = lstrlenW(Text);
-    if(Text == NULL || textlen == 0)
+    if(Text == NULL || (textlen = lstrlenW(Text)) == 0)
     {
         return TRUE;
     }
@@ -983,9 +986,13 @@
     {
         /* Render text position and word wrapping in memory */
         HDC hdc = GetDC(infoPtr->Self);
-        SYSLINK_Render(infoPtr, hdc);
-        SYSLINK_Draw(infoPtr, hdc);
-        ReleaseDC(infoPtr->Self, hdc);
+        if (hdc != NULL)
+        {
+            SYSLINK_Render(infoPtr, hdc);
+            ReleaseDC(infoPtr->Self, hdc);
+
+            InvalidateRect(infoPtr->Self, NULL, TRUE);
+        }
     }
     
     return TRUE;
@@ -1031,6 +1038,7 @@
 static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
 {
     PDOC_ITEM di;
+    int nc;
     BOOL Repaint = FALSE;
     BOOL Ret = TRUE;
 
@@ -1062,35 +1070,41 @@
 
     if(Item->mask & LIF_ITEMID)
     {
-        if(!di->u.Link.szID)
+        if(di->u.Link.szID)
         {
-            di->u.Link.szID = Alloc((MAX_LINKID_TEXT + 1) * sizeof(WCHAR));
-            if(!Item->szID)
-            {
-                ERR("Unable to allocate memory for link id\n");
-                Ret = FALSE;
-            }
+            Free(di->u.Link.szID);
         }
+
+        nc = min(lstrlenW(Item->szID), MAX_LINKID_TEXT - 1);
+        di->u.Link.szID = Alloc((nc + 1) * sizeof(WCHAR));
         if(di->u.Link.szID)
         {
-            lstrcpynW(di->u.Link.szID, Item->szID, MAX_LINKID_TEXT + 1);
+            lstrcpynW(di->u.Link.szID, Item->szID, nc + 1);
+        }
+        else
+        {
+            ERR("Unable to allocate memory for link id\n");
+            Ret = FALSE;
         }
     }
 
     if(Item->mask & LIF_URL)
     {
-        if(!di->u.Link.szUrl)
+        if(di->u.Link.szUrl)
         {
-            di->u.Link.szUrl = Alloc((MAX_LINKID_TEXT + 1) * sizeof(WCHAR));
-            if(!Item->szUrl)
-            {
-                ERR("Unable to allocate memory for link url\n");
-                Ret = FALSE;
-            }
+            Free(di->u.Link.szUrl);
         }
+
+        nc = min(lstrlenW(Item->szUrl), L_MAX_URL_LENGTH - 1);
+        di->u.Link.szUrl = Alloc((nc + 1) * sizeof(WCHAR));
         if(di->u.Link.szUrl)
         {
-            lstrcpynW(di->u.Link.szUrl, Item->szUrl, MAX_LINKID_TEXT + 1);
+            lstrcpynW(di->u.Link.szUrl, Item->szUrl, nc + 1);
+        }
+        else
+        {
+            ERR("Unable to allocate memory for link url\n");
+            Ret = FALSE;
         }
     }
     
@@ -1137,7 +1151,7 @@
     {
         if(di->u.Link.szID)
         {
-            lstrcpynW(Item->szID, di->u.Link.szID, MAX_LINKID_TEXT + 1);
+            lstrcpyW(Item->szID, di->u.Link.szID);
         }
         else
         {
@@ -1149,7 +1163,7 @@
     {
         if(di->u.Link.szUrl)
         {
-            lstrcpynW(Item->szUrl, di->u.Link.szUrl, L_MAX_URL_LENGTH + 1);
+            lstrcpyW(Item->szUrl, di->u.Link.szUrl);
         }
         else
         {
@@ -1209,7 +1223,7 @@
                 HitTest->item.stateMask = 0;
                 if(Current->u.Link.szID)
                 {
-                    lstrcpynW(HitTest->item.szID, Current->u.Link.szID, MAX_LINKID_TEXT + 1);
+                    lstrcpyW(HitTest->item.szID, Current->u.Link.szID);
                 }
                 else
                 {
@@ -1217,7 +1231,7 @@
                 }
                 if(Current->u.Link.szUrl)
                 {
-                    lstrcpynW(HitTest->item.szUrl, Current->u.Link.szUrl, L_MAX_URL_LENGTH + 1);
+                    lstrcpyW(HitTest->item.szUrl, Current->u.Link.szUrl);
                 }
                 else
                 {
@@ -1279,7 +1293,7 @@
     nml.item.stateMask = 0;
     if(Link->u.Link.szID)
     {
-        lstrcpynW(nml.item.szID, Link->u.Link.szID, MAX_LINKID_TEXT + 1);
+        lstrcpyW(nml.item.szID, Link->u.Link.szID);
     }
     else
     {
@@ -1287,7 +1301,7 @@
     }
     if(Link->u.Link.szUrl)
     {
-        lstrcpynW(nml.item.szUrl, Link->u.Link.szUrl, L_MAX_URL_LENGTH + 1);
+        lstrcpyW(nml.item.szUrl, Link->u.Link.szUrl);
     }
     else
     {
@@ -1533,8 +1547,8 @@
         HDC hdc = GetDC(infoPtr->Self);
         if(hdc != NULL)
         {
-          SYSLINK_Render(infoPtr, hdc);
-          ReleaseDC(infoPtr->Self, hdc);
+            SYSLINK_Render(infoPtr, hdc);
+            ReleaseDC(infoPtr->Self, hdc);
         }
         return 0;
     }


More information about the wine-patches mailing list