Module: wine Branch: master Commit: bf1183654aa9938c867fd27ca3606fd1c99ea15c URL: https://source.winehq.org/git/wine.git/?a=commit;h=bf1183654aa9938c867fd27ca...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Mon Mar 8 17:44:39 2021 +0300
comctl32/listview: Sort using duplicated items pointer array to preserve original order.
Issue reported by Haoyang Chen.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/comctl32/listview.c | 17 ++++++++++------- include/commctrl.h | 1 + 2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index ee67193ff27..799ec509f33 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -9230,7 +9230,7 @@ static INT LISTVIEW_SetView(LISTVIEW_INFO *infoPtr, DWORD nView)
struct sorting_context { - LISTVIEW_INFO *infoPtr; + HDPA items; PFNLVCOMPARE compare_func; LPARAM lParam; }; @@ -9249,8 +9249,8 @@ static INT WINAPI LISTVIEW_CallBackCompare(LPVOID first, LPVOID second, LPARAM l static INT WINAPI LISTVIEW_CallBackCompareEx(LPVOID first, LPVOID second, LPARAM lParam) { struct sorting_context *context = (struct sorting_context *)lParam; - INT first_idx = DPA_GetPtrIndex( context->infoPtr->hdpaItems, first ); - INT second_idx = DPA_GetPtrIndex( context->infoPtr->hdpaItems, second ); + INT first_idx = DPA_GetPtrIndex( context->items, first ); + INT second_idx = DPA_GetPtrIndex( context->items, second );
return context->compare_func(first_idx, second_idx, context->lParam); } @@ -9272,7 +9272,7 @@ static INT WINAPI LISTVIEW_CallBackCompareEx(LPVOID first, LPVOID second, LPARAM static BOOL LISTVIEW_SortItems(LISTVIEW_INFO *infoPtr, PFNLVCOMPARE pfnCompare, LPARAM lParamSort, BOOL IsEx) { - HDPA hdpaSubItems; + HDPA hdpaSubItems, hdpaItems; ITEM_INFO *lpItem; LPVOID selectionMarkItem = NULL; LPVOID focusedItem = NULL; @@ -9288,6 +9288,7 @@ static BOOL LISTVIEW_SortItems(LISTVIEW_INFO *infoPtr, PFNLVCOMPARE pfnCompare,
/* if there are 0 or 1 items, there is no need to sort */ if (infoPtr->nItemCount < 2) return TRUE; + if (!(hdpaItems = DPA_Clone(infoPtr->hdpaItems, NULL))) return FALSE;
/* clear selection */ ranges_clear(infoPtr->selectionRanges); @@ -9298,13 +9299,15 @@ static BOOL LISTVIEW_SortItems(LISTVIEW_INFO *infoPtr, PFNLVCOMPARE pfnCompare, if (infoPtr->nFocusedItem >= 0) focusedItem = DPA_GetPtr(infoPtr->hdpaItems, infoPtr->nFocusedItem);
- context.infoPtr = infoPtr; + context.items = hdpaItems; context.compare_func = pfnCompare; context.lParam = lParamSort; if (IsEx) - DPA_Sort(infoPtr->hdpaItems, LISTVIEW_CallBackCompareEx, (LPARAM)&context); + DPA_Sort(hdpaItems, LISTVIEW_CallBackCompareEx, (LPARAM)&context); else - DPA_Sort(infoPtr->hdpaItems, LISTVIEW_CallBackCompare, (LPARAM)&context); + DPA_Sort(hdpaItems, LISTVIEW_CallBackCompare, (LPARAM)&context); + DPA_Destroy(infoPtr->hdpaItems); + infoPtr->hdpaItems = hdpaItems;
/* restore selection ranges */ for (i=0; i < infoPtr->nItemCount; i++) diff --git a/include/commctrl.h b/include/commctrl.h index 97e2fcc4df0..5614f64a979 100644 --- a/include/commctrl.h +++ b/include/commctrl.h @@ -5165,6 +5165,7 @@ typedef PVOID (CALLBACK *PFNDPAMERGE)(UINT,PVOID,PVOID,LPARAM); #define DPAM_UNION 0x00000004 #define DPAM_INTERSECT 0x00000008
+HDPA WINAPI DPA_Clone(const HDPA, HDPA); HDPA WINAPI DPA_Create(INT); BOOL WINAPI DPA_Destroy(HDPA); LPVOID WINAPI DPA_DeletePtr(HDPA, INT);