comctl32: Reduce memory usage of the syslink control.
This commit is contained in:
parent
adc416b756
commit
bb56d907e5
|
@ -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
|
||||||
|
@ -116,10 +116,16 @@ static const WCHAR SL_LINKCLOSE[] = { '<','/','a','>',0 };
|
||||||
static VOID SYSLINK_FreeDocItem (PDOC_ITEM DocItem)
|
static VOID SYSLINK_FreeDocItem (PDOC_ITEM DocItem)
|
||||||
{
|
{
|
||||||
if(DocItem->Type == slLink)
|
if(DocItem->Type == slLink)
|
||||||
|
{
|
||||||
|
if (DocItem->u.Link.szID != NULL)
|
||||||
{
|
{
|
||||||
Free(DocItem->u.Link.szID);
|
Free(DocItem->u.Link.szID);
|
||||||
|
}
|
||||||
|
if (DocItem->u.Link.szUrl != NULL)
|
||||||
|
{
|
||||||
Free(DocItem->u.Link.szUrl);
|
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
|
||||||
entire window text string */
|
entire window text string */
|
||||||
|
@ -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)))
|
||||||
{
|
{
|
||||||
|
@ -1053,6 +1056,59 @@ static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
|
||||||
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;
|
||||||
|
@ -1066,46 +1122,12 @@ static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
|
||||||
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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue