Improved header control performance by maintaining an internal order
array.
This commit is contained in:
parent
c486949985
commit
682dd707c8
|
@ -87,6 +87,7 @@ typedef struct
|
|||
|
||||
HIMAGELIST himl; /* handle to an image list (may be 0) */
|
||||
HEADER_ITEM *items; /* pointer to array of HEADER_ITEM's */
|
||||
INT *order; /* array of item IDs indexed by order */
|
||||
BOOL bRectsValid; /* validity flag for bounding rectangles */
|
||||
} HEADER_INFO;
|
||||
|
||||
|
@ -113,14 +114,10 @@ HEADER_OrderToIndex(HWND hwnd, WPARAM wParam)
|
|||
{
|
||||
HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
|
||||
INT iorder = (INT)wParam;
|
||||
UINT i;
|
||||
|
||||
if ((iorder <0) || iorder >infoPtr->uNumItem)
|
||||
if ((iorder <0) || iorder >= infoPtr->uNumItem)
|
||||
return iorder;
|
||||
for (i=0; i<infoPtr->uNumItem; i++)
|
||||
if (HEADER_IndexToOrder(hwnd,i) == iorder)
|
||||
return i;
|
||||
return iorder;
|
||||
return infoPtr->order[iorder];
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -647,16 +644,19 @@ HEADER_DeleteItem (HWND hwnd, WPARAM wParam)
|
|||
if (infoPtr->items[0].pszText)
|
||||
Free (infoPtr->items[0].pszText);
|
||||
Free (infoPtr->items);
|
||||
Free(infoPtr->order);
|
||||
infoPtr->items = 0;
|
||||
infoPtr->order = 0;
|
||||
infoPtr->uNumItem = 0;
|
||||
}
|
||||
else {
|
||||
HEADER_ITEM *oldItems = infoPtr->items;
|
||||
HEADER_ITEM *pItem;
|
||||
INT i;
|
||||
INT iOrder;
|
||||
TRACE("Complex delete! [iItem=%d]\n", iItem);
|
||||
|
||||
for (i = 0; i < infoPtr->uNumItem; i++)
|
||||
TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder);
|
||||
if (infoPtr->items[iItem].pszText)
|
||||
Free (infoPtr->items[iItem].pszText);
|
||||
iOrder = infoPtr->items[iItem].iOrder;
|
||||
|
@ -676,11 +676,21 @@ HEADER_DeleteItem (HWND hwnd, WPARAM wParam)
|
|||
}
|
||||
|
||||
/* Correct the orders */
|
||||
for (i=infoPtr->uNumItem, pItem = infoPtr->items; i; i--, pItem++)
|
||||
if (iOrder < infoPtr->uNumItem)
|
||||
{
|
||||
if (pItem->iOrder > iOrder)
|
||||
pItem->iOrder--;
|
||||
memmove(&infoPtr->order[iOrder], &infoPtr->order[iOrder + 1],
|
||||
(infoPtr->uNumItem - iOrder) * sizeof(INT));
|
||||
for (i = 0; i < infoPtr->uNumItem; i++)
|
||||
{
|
||||
if (infoPtr->order[i] > iItem)
|
||||
infoPtr->order[i]--;
|
||||
if (i >= iOrder)
|
||||
infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < infoPtr->uNumItem; i++)
|
||||
TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder);
|
||||
Free (oldItems);
|
||||
}
|
||||
|
||||
|
@ -850,14 +860,13 @@ HEADER_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
static LRESULT
|
||||
HEADER_GetOrderArray(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int i;
|
||||
LPINT order = (LPINT) lParam;
|
||||
HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
|
||||
|
||||
if ((unsigned int)wParam <infoPtr->uNumItem)
|
||||
return FALSE;
|
||||
for (i=0; i<(int)wParam; i++)
|
||||
*order++=HEADER_OrderToIndex(hwnd,i);
|
||||
|
||||
memcpy(order, infoPtr->order, infoPtr->uNumItem * sizeof(INT));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -871,6 +880,7 @@ HEADER_SetOrderArray(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
if ((unsigned int)wParam <infoPtr->uNumItem)
|
||||
return FALSE;
|
||||
memcpy(infoPtr->order, order, infoPtr->uNumItem * sizeof(INT));
|
||||
for (i=0; i<(int)wParam; i++)
|
||||
{
|
||||
lpItem = &infoPtr->items[*order++];
|
||||
|
@ -923,10 +933,12 @@ HEADER_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
if (infoPtr->uNumItem == 0) {
|
||||
infoPtr->items = Alloc (sizeof (HEADER_ITEM));
|
||||
infoPtr->order = Alloc(sizeof(INT));
|
||||
infoPtr->uNumItem++;
|
||||
}
|
||||
else {
|
||||
HEADER_ITEM *oldItems = infoPtr->items;
|
||||
INT *oldOrder = infoPtr->order;
|
||||
|
||||
infoPtr->uNumItem++;
|
||||
infoPtr->items = Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
|
||||
|
@ -949,13 +961,21 @@ HEADER_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
}
|
||||
|
||||
infoPtr->order = Alloc(sizeof(INT) * infoPtr->uNumItem);
|
||||
memcpy(infoPtr->order, oldOrder, iOrder * sizeof(INT));
|
||||
infoPtr->order[iOrder] = nItem;
|
||||
memcpy(&infoPtr->order[iOrder + 1], &oldOrder[iOrder],
|
||||
(infoPtr->uNumItem - iOrder - 1) * sizeof(INT));
|
||||
|
||||
Free (oldItems);
|
||||
Free(oldOrder);
|
||||
}
|
||||
|
||||
for (i=0; i < infoPtr->uNumItem; i++)
|
||||
for (i = 0; i < infoPtr->uNumItem; i++)
|
||||
{
|
||||
if (infoPtr->items[i].iOrder >= iOrder)
|
||||
infoPtr->items[i].iOrder++;
|
||||
if (i != iOrder && infoPtr->order[i] >= nItem)
|
||||
infoPtr->order[i]++;
|
||||
infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i];
|
||||
}
|
||||
|
||||
lpItem = &infoPtr->items[nItem];
|
||||
|
@ -1025,10 +1045,12 @@ HEADER_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
if (infoPtr->uNumItem == 0) {
|
||||
infoPtr->items = Alloc (sizeof (HEADER_ITEM));
|
||||
infoPtr->order = Alloc(sizeof(INT));
|
||||
infoPtr->uNumItem++;
|
||||
}
|
||||
else {
|
||||
HEADER_ITEM *oldItems = infoPtr->items;
|
||||
INT *oldOrder = infoPtr->order;
|
||||
|
||||
infoPtr->uNumItem++;
|
||||
infoPtr->items = Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
|
||||
|
@ -1051,13 +1073,21 @@ HEADER_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
}
|
||||
|
||||
infoPtr->order = Alloc(infoPtr->uNumItem * sizeof(INT));
|
||||
memcpy(infoPtr->order, oldOrder, iOrder * sizeof(INT));
|
||||
infoPtr->order[iOrder] = nItem;
|
||||
memcpy(&infoPtr->order[iOrder + 1], &oldOrder[iOrder],
|
||||
(infoPtr->uNumItem - iOrder - 1) * sizeof(INT));
|
||||
|
||||
Free (oldItems);
|
||||
Free(oldOrder);
|
||||
}
|
||||
|
||||
for (i=0; i < infoPtr->uNumItem; i++)
|
||||
for (i = 0; i < infoPtr->uNumItem; i++)
|
||||
{
|
||||
if (infoPtr->items[i].iOrder >= iOrder)
|
||||
infoPtr->items[i].iOrder++;
|
||||
if (i != iOrder && infoPtr->order[i] >= nItem)
|
||||
infoPtr->order[i]++;
|
||||
infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i];
|
||||
}
|
||||
|
||||
lpItem = &infoPtr->items[nItem];
|
||||
|
@ -1224,7 +1254,27 @@ HEADER_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
if (phdi->mask & HDI_ORDER)
|
||||
{
|
||||
lpItem->iOrder = phdi->iOrder;
|
||||
INT i, nMin, nMax;
|
||||
|
||||
if (lpItem->iOrder < phdi->iOrder)
|
||||
{
|
||||
memmove(&infoPtr->order[lpItem->iOrder],
|
||||
&infoPtr->order[lpItem->iOrder + 1],
|
||||
(phdi->iOrder - lpItem->iOrder) * sizeof(INT));
|
||||
}
|
||||
if (phdi->iOrder < lpItem->iOrder)
|
||||
{
|
||||
memmove(&infoPtr->order[phdi->iOrder + 1],
|
||||
&infoPtr->order[phdi->iOrder],
|
||||
(lpItem->iOrder - phdi->iOrder) * sizeof(INT));
|
||||
}
|
||||
infoPtr->order[phdi->iOrder] = nItem;
|
||||
nMin = min(lpItem->iOrder, phdi->iOrder);
|
||||
nMax = max(lpItem->iOrder, phdi->iOrder);
|
||||
for (i = nMin; i <= nMax; i++)
|
||||
{
|
||||
infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i];
|
||||
}
|
||||
}
|
||||
|
||||
HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGEDA, nItem, phdi->mask);
|
||||
|
@ -1289,7 +1339,27 @@ HEADER_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
if (phdi->mask & HDI_ORDER)
|
||||
{
|
||||
lpItem->iOrder = phdi->iOrder;
|
||||
INT i, nMin, nMax;
|
||||
|
||||
if (lpItem->iOrder < phdi->iOrder)
|
||||
{
|
||||
memmove(&infoPtr->order[lpItem->iOrder],
|
||||
&infoPtr->order[lpItem->iOrder + 1],
|
||||
(phdi->iOrder - lpItem->iOrder) * sizeof(INT));
|
||||
}
|
||||
if (phdi->iOrder < lpItem->iOrder)
|
||||
{
|
||||
memmove(&infoPtr->order[phdi->iOrder + 1],
|
||||
&infoPtr->order[phdi->iOrder],
|
||||
(lpItem->iOrder - phdi->iOrder) * sizeof(INT));
|
||||
}
|
||||
infoPtr->order[phdi->iOrder] = nItem;
|
||||
nMin = min(lpItem->iOrder, phdi->iOrder);
|
||||
nMax = max(lpItem->iOrder, phdi->iOrder);
|
||||
for (i = nMin; i <= nMax; i++)
|
||||
{
|
||||
infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i];
|
||||
}
|
||||
}
|
||||
|
||||
HEADER_SendHeaderNotify(hwnd, HDN_ITEMCHANGEDW, nItem, phdi->mask);
|
||||
|
@ -1328,6 +1398,7 @@ HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
infoPtr->uNumItem = 0;
|
||||
infoPtr->hFont = 0;
|
||||
infoPtr->items = 0;
|
||||
infoPtr->order = 0;
|
||||
infoPtr->bRectsValid = FALSE;
|
||||
infoPtr->hcurArrow = LoadCursorW (0, (LPWSTR)IDC_ARROW);
|
||||
infoPtr->hcurDivider = LoadCursorW (COMCTL32_hModule, MAKEINTRESOURCEW(IDC_DIVIDER));
|
||||
|
@ -1372,6 +1443,9 @@ HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
Free (infoPtr->items);
|
||||
}
|
||||
|
||||
if (infoPtr->order)
|
||||
Free(infoPtr->order);
|
||||
|
||||
if (infoPtr->himl)
|
||||
ImageList_Destroy (infoPtr->himl);
|
||||
|
||||
|
@ -1505,6 +1579,9 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
lpItem= &infoPtr->items[infoPtr->iMoveItem];
|
||||
lpItem->iOrder = newindex;
|
||||
|
||||
infoPtr->order[oldindex] = nItem;
|
||||
infoPtr->order[newindex] = infoPtr->iMoveItem;
|
||||
|
||||
infoPtr->bRectsValid = FALSE;
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
/* FIXME: Should some WM_NOTIFY be sent */
|
||||
|
|
Loading…
Reference in New Issue