comctl32: Reduce memory usage of the syslink control.

This commit is contained in:
Thomas Weidenmueller 2006-01-06 13:08:09 +01:00 committed by Alexandre Julliard
parent adc416b756
commit bb56d907e5
1 changed files with 88 additions and 66 deletions

View File

@ -1,7 +1,7 @@
/* /*
* SysLink control * SysLink control
* *
* Copyright 2004, 2005 Thomas Weidenmueller <w3seek@reactos.com> * Copyright 2004 - 2006 Thomas Weidenmueller <w3seek@reactos.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -62,7 +62,6 @@ typedef enum
typedef struct _DOC_ITEM typedef struct _DOC_ITEM
{ {
struct _DOC_ITEM *Next; /* Address to the next 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 */ UINT nText; /* Number of characters of the text */
SL_ITEM_TYPE Type; /* type of the item */ SL_ITEM_TYPE Type; /* type of the item */
PDOC_TEXTBLOCK Blocks; /* Array of text blocks */ PDOC_TEXTBLOCK Blocks; /* Array of text blocks */
@ -79,6 +78,7 @@ typedef struct _DOC_ITEM
UINT Dummy; UINT Dummy;
} Text; } Text;
} u; } u;
WCHAR Text[1]; /* Text of the document item */
} DOC_ITEM, *PDOC_ITEM; } DOC_ITEM, *PDOC_ITEM;
typedef struct typedef struct
@ -117,8 +117,14 @@ static VOID SYSLINK_FreeDocItem (PDOC_ITEM DocItem)
{ {
if(DocItem->Type == slLink) if(DocItem->Type == slLink)
{ {
Free(DocItem->u.Link.szID); if (DocItem->u.Link.szID != NULL)
Free(DocItem->u.Link.szUrl); {
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 /* we don't free Text because it's just a pointer to a character in the
@ -135,16 +141,16 @@ static PDOC_ITEM SYSLINK_AppendDocItem (SYSLINK_INFO *infoPtr, LPCWSTR Text, UIN
SL_ITEM_TYPE type, PDOC_ITEM LastItem) SL_ITEM_TYPE type, PDOC_ITEM LastItem)
{ {
PDOC_ITEM Item; 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) if(Item == NULL)
{ {
ERR("Failed to alloc DOC_ITEM structure!\n"); ERR("Failed to alloc DOC_ITEM structure!\n");
return NULL; return NULL;
} }
textlen = min(textlen, lstrlenW(Text));
Item->Next = NULL; Item->Next = NULL;
Item->Text = (LPWSTR)(Item + 1);
Item->nText = textlen; Item->nText = textlen;
Item->Type = type; Item->Type = type;
Item->Blocks = NULL; Item->Blocks = NULL;
@ -159,7 +165,6 @@ static PDOC_ITEM SYSLINK_AppendDocItem (SYSLINK_INFO *infoPtr, LPCWSTR Text, UIN
} }
lstrcpynW(Item->Text, Text, textlen + 1); lstrcpynW(Item->Text, Text, textlen + 1);
Item->Text[textlen] = 0;
return Item; return Item;
} }
@ -351,12 +356,11 @@ CheckParameter:
if(lpID != NULL) if(lpID != NULL)
{ {
nc = min(lenId, strlenW(lpID)); nc = min(lenId, strlenW(lpID));
nc = min(nc, MAX_LINKID_TEXT); nc = min(nc, MAX_LINKID_TEXT - 1);
Last->u.Link.szID = Alloc((MAX_LINKID_TEXT + 1) * sizeof(WCHAR)); Last->u.Link.szID = Alloc((nc + 1) * sizeof(WCHAR));
if(Last->u.Link.szID != NULL) if(Last->u.Link.szID != NULL)
{ {
lstrcpynW(Last->u.Link.szID, lpID, nc + 1); lstrcpynW(Last->u.Link.szID, lpID, nc + 1);
Last->u.Link.szID[nc] = 0;
} }
} }
else else
@ -364,12 +368,11 @@ CheckParameter:
if(lpUrl != NULL) if(lpUrl != NULL)
{ {
nc = min(lenUrl, strlenW(lpUrl)); nc = min(lenUrl, strlenW(lpUrl));
nc = min(nc, L_MAX_URL_LENGTH); nc = min(nc, L_MAX_URL_LENGTH - 1);
Last->u.Link.szUrl = Alloc((L_MAX_URL_LENGTH + 1) * sizeof(WCHAR)); Last->u.Link.szUrl = Alloc((nc + 1) * sizeof(WCHAR));
if(Last->u.Link.szUrl != NULL) if(Last->u.Link.szUrl != NULL)
{ {
lstrcpynW(Last->u.Link.szUrl, lpUrl, nc + 1); lstrcpynW(Last->u.Link.szUrl, lpUrl, nc + 1);
Last->u.Link.szUrl[nc] = 0;
} }
} }
else else
@ -431,12 +434,11 @@ CheckParameter:
if(lpID != NULL) if(lpID != NULL)
{ {
nc = min(lenId, strlenW(lpID)); nc = min(lenId, strlenW(lpID));
nc = min(nc, MAX_LINKID_TEXT); nc = min(nc, MAX_LINKID_TEXT - 1);
Last->u.Link.szID = Alloc((MAX_LINKID_TEXT + 1) * sizeof(WCHAR)); Last->u.Link.szID = Alloc((nc + 1) * sizeof(WCHAR));
if(Last->u.Link.szID != NULL) if(Last->u.Link.szID != NULL)
{ {
lstrcpynW(Last->u.Link.szID, lpID, nc + 1); lstrcpynW(Last->u.Link.szID, lpID, nc + 1);
Last->u.Link.szID[nc] = 0;
} }
} }
else else
@ -444,12 +446,11 @@ CheckParameter:
if(lpUrl != NULL) if(lpUrl != NULL)
{ {
nc = min(lenUrl, strlenW(lpUrl)); nc = min(lenUrl, strlenW(lpUrl));
nc = min(nc, L_MAX_URL_LENGTH); nc = min(nc, L_MAX_URL_LENGTH - 1);
Last->u.Link.szUrl = Alloc((L_MAX_URL_LENGTH + 1) * sizeof(WCHAR)); Last->u.Link.szUrl = Alloc((nc + 1) * sizeof(WCHAR));
if(Last->u.Link.szUrl != NULL) if(Last->u.Link.szUrl != NULL)
{ {
lstrcpynW(Last->u.Link.szUrl, lpUrl, nc + 1); lstrcpynW(Last->u.Link.szUrl, lpUrl, nc + 1);
Last->u.Link.szUrl[nc] = 0;
} }
} }
else else
@ -751,6 +752,7 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
{ {
Free(bl); Free(bl);
bl = NULL; bl = NULL;
nBlocks = 0;
} }
break; break;
} }
@ -769,11 +771,12 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
{ {
Free(bl); Free(bl);
bl = NULL; bl = NULL;
nBlocks = 0;
} }
} }
else else
{ {
bl = Alloc((nBlocks + 1) * sizeof(DOC_TEXTBLOCK)); bl = Alloc(sizeof(DOC_TEXTBLOCK));
if (bl != NULL) if (bl != NULL)
nBlocks++; nBlocks++;
} }
@ -820,8 +823,6 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
{ {
Current->Blocks = bl; Current->Blocks = bl;
} }
else
Current->Blocks = NULL;
} }
SelectObject(hdc, hOldFont); SelectObject(hdc, hOldFont);
@ -1037,8 +1038,10 @@ static PDOC_ITEM SYSLINK_SetFocusLink (SYSLINK_INFO *infoPtr, PDOC_ITEM DocItem)
static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item) static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
{ {
PDOC_ITEM di; PDOC_ITEM di;
int nc;
PWSTR szId = NULL;
PWSTR szUrl = NULL;
BOOL Repaint = FALSE; BOOL Repaint = FALSE;
BOOL Ret = TRUE;
if(!(Item->mask & LIF_ITEMINDEX) || !(Item->mask & (LIF_FLAGSMASK))) if(!(Item->mask & LIF_ITEMINDEX) || !(Item->mask & (LIF_FLAGSMASK)))
{ {
@ -1052,7 +1055,60 @@ static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
ERR("Link %d couldn't be found\n", Item->iLink); ERR("Link %d couldn't be found\n", Item->iLink);
return FALSE; return FALSE;
} }
if(Item->mask & LIF_ITEMID)
{
nc = min(lstrlenW(Item->szID), MAX_LINKID_TEXT - 1);
szId = Alloc((nc + 1) * sizeof(WCHAR));
if(szId)
{
lstrcpynW(szId, Item->szID, nc + 1);
}
else
{
ERR("Unable to allocate memory for link id\n");
return FALSE;
}
}
if(Item->mask & LIF_URL)
{
nc = min(lstrlenW(Item->szUrl), L_MAX_URL_LENGTH - 1);
szUrl = Alloc((nc + 1) * sizeof(WCHAR));
if(szUrl)
{
lstrcpynW(szUrl, Item->szUrl, nc + 1);
}
else
{
if (szId)
{
Free(szId);
}
ERR("Unable to allocate memory for link url\n");
return FALSE;
}
}
if(Item->mask & LIF_ITEMID)
{
if(di->u.Link.szID)
{
Free(di->u.Link.szID);
}
di->u.Link.szID = szId;
}
if(Item->mask & LIF_URL)
{
if(di->u.Link.szUrl)
{
Free(di->u.Link.szUrl);
}
di->u.Link.szUrl = szUrl;
}
if(Item->mask & LIF_STATE) if(Item->mask & LIF_STATE)
{ {
UINT oldstate = di->u.Link.state; UINT oldstate = di->u.Link.state;
@ -1065,47 +1121,13 @@ static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
/* update the focus */ /* update the focus */
SYSLINK_SetFocusLink(infoPtr, ((di->u.Link.state & LIS_FOCUSED) ? di : NULL)); SYSLINK_SetFocusLink(infoPtr, ((di->u.Link.state & LIS_FOCUSED) ? di : NULL));
} }
if(Item->mask & LIF_ITEMID)
{
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;
}
}
if(di->u.Link.szID)
{
lstrcpynW(di->u.Link.szID, Item->szID, MAX_LINKID_TEXT + 1);
}
}
if(Item->mask & LIF_URL)
{
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;
}
}
if(di->u.Link.szUrl)
{
lstrcpynW(di->u.Link.szUrl, Item->szUrl, MAX_LINKID_TEXT + 1);
}
}
if(Repaint) if(Repaint)
{ {
SYSLINK_RepaintLink(infoPtr, di); SYSLINK_RepaintLink(infoPtr, di);
} }
return Ret; return TRUE;
} }
/*********************************************************************** /***********************************************************************
@ -1143,7 +1165,7 @@ static LRESULT SYSLINK_GetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
{ {
if(di->u.Link.szID) if(di->u.Link.szID)
{ {
lstrcpynW(Item->szID, di->u.Link.szID, MAX_LINKID_TEXT + 1); lstrcpyW(Item->szID, di->u.Link.szID);
} }
else else
{ {
@ -1155,7 +1177,7 @@ static LRESULT SYSLINK_GetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
{ {
if(di->u.Link.szUrl) 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 else
{ {
@ -1215,7 +1237,7 @@ static LRESULT SYSLINK_HitTest (SYSLINK_INFO *infoPtr, PLHITTESTINFO HitTest)
HitTest->item.stateMask = 0; HitTest->item.stateMask = 0;
if(Current->u.Link.szID) 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 else
{ {
@ -1223,7 +1245,7 @@ static LRESULT SYSLINK_HitTest (SYSLINK_INFO *infoPtr, PLHITTESTINFO HitTest)
} }
if(Current->u.Link.szUrl) 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 else
{ {
@ -1285,7 +1307,7 @@ static LRESULT SYSLINK_SendParentNotify (SYSLINK_INFO *infoPtr, UINT code, PDOC_
nml.item.stateMask = 0; nml.item.stateMask = 0;
if(Link->u.Link.szID) 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 else
{ {
@ -1293,7 +1315,7 @@ static LRESULT SYSLINK_SendParentNotify (SYSLINK_INFO *infoPtr, UINT code, PDOC_
} }
if(Link->u.Link.szUrl) 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 else
{ {