Nikolay Sivov : shell32/shellview: Get rid of intermediate pointer array when filling ListView.
Alexandre Julliard
julliard at winehq.org
Thu Jan 26 14:53:13 CST 2017
Module: wine
Branch: master
Commit: a26d6e375e394f7672555c2ae51fd5aaa03d0525
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a26d6e375e394f7672555c2ae51fd5aaa03d0525
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Jan 25 22:51:30 2017 +0300
shell32/shellview: Get rid of intermediate pointer array when filling ListView.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/shell32/shlview.c | 83 ++++++++++++++++++--------------------------------
1 file changed, 30 insertions(+), 53 deletions(-)
diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
index 4560162..c15a32d 100644
--- a/dlls/shell32/shlview.c
+++ b/dlls/shell32/shlview.c
@@ -110,6 +110,7 @@ typedef struct
LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
POINT ptLastMousePos; /* Mouse position at last DragOver call */
+ UINT columns; /* Number of shell folder columns */
} IShellViewImpl;
static inline IShellViewImpl *impl_from_IShellView3(IShellView3 *iface)
@@ -383,7 +384,6 @@ static void ShellView_InitList(IShellViewImpl *This)
SHELLDETAILS sd;
WCHAR nameW[50];
HRESULT hr;
- INT i;
TRACE("(%p)\n", This);
@@ -405,39 +405,36 @@ static void ShellView_InitList(IShellViewImpl *This)
}
}
- for (i = 0; 1; i++)
+ for (This->columns = 0;; This->columns++)
{
if (This->pSF2Parent)
- hr = IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd);
+ hr = IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, This->columns, &sd);
else
- hr = IShellDetails_GetDetailsOf(details, NULL, i, &sd);
+ hr = IShellDetails_GetDetailsOf(details, NULL, This->columns, &sd);
if (FAILED(hr)) break;
lvColumn.fmt = sd.fmt;
lvColumn.cx = sd.cxChar*8; /* chars->pixel */
StrRetToStrNW(nameW, sizeof(nameW)/sizeof(WCHAR), &sd.str, NULL);
- SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
+ SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, This->columns, (LPARAM)&lvColumn);
}
if (details) IShellDetails_Release(details);
}
-/**********************************************************
-* ShellView_CompareItems()
-*
-* NOTES
-* internal, CALLBACK for DSA_Sort
-*/
-static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
+/* LVM_SORTITEMS callback used when initially inserting items */
+static INT CALLBACK ShellView_CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
{
- int ret;
- TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
+ LPITEMIDLIST pidl1 = (LPITEMIDLIST)lParam1;
+ LPITEMIDLIST pidl2 = (LPITEMIDLIST)lParam2;
+ IShellFolder *folder = (IShellFolder *)lpData;
+ int ret;
- if(!lpData) return 0;
+ TRACE("pidl1=%p, pidl2=%p, shellfolder=%p\n", pidl1, pidl2, folder);
- ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
- TRACE("ret=%i\n",ret);
- return ret;
+ ret = (SHORT)HRESULT_CODE(IShellFolder_CompareIDs(folder, 0, pidl1, pidl2));
+ TRACE("ret=%i\n", ret);
+ return ret;
}
/*************************************************************************
@@ -568,19 +565,19 @@ static int LV_FindItemByPidl(
/**********************************************************
* LV_AddItem()
*/
-static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
+static void shellview_add_item(IShellViewImpl * This, LPCITEMIDLIST pidl)
{
LVITEMW lvItem;
TRACE("(%p)(pidl=%p)\n", This, pidl);
lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
- lvItem.iItem = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0); /*add the item to the end of the list*/
+ lvItem.iItem = 0;
lvItem.iSubItem = 0;
- lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
+ lvItem.lParam = (LPARAM)pidl;
lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
- return ListView_InsertItemW(This->hWndList, &lvItem) != -1;
+ ListView_InsertItemW(This->hWndList, &lvItem);
}
/**********************************************************
@@ -618,16 +615,6 @@ static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCIT
* - fills the list into the view
*/
-static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
-{
- LPITEMIDLIST pidl = ptr;
- IShellViewImpl *This = arg;
- /* in a commdlg This works as a filemask*/
- if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
- SHFree(pidl);
- return TRUE;
-}
-
static HRESULT ShellView_FillList(IShellViewImpl *This)
{
IFolderView2 *folderview = &This->IFolderView2_iface;
@@ -635,40 +622,28 @@ static HRESULT ShellView_FillList(IShellViewImpl *This)
LPITEMIDLIST pidl;
DWORD fetched;
HRESULT hr;
- HDPA hdpa;
TRACE("(%p)\n", This);
/* get the itemlist from the shfolder*/
hr = IShellFolder_EnumObjects(This->pSFParent, This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
- if (hr != S_OK) return hr;
+ if (hr != S_OK)
+ return hr;
- /* create a pointer array */
- hdpa = DPA_Create(16);
- if (!hdpa)
- {
- IEnumIDList_Release(pEnumIDList);
- return E_OUTOFMEMORY;
- }
+ IFolderView2_SetRedraw(folderview, FALSE);
- /* copy the items into the array*/
- while((S_OK == IEnumIDList_Next(pEnumIDList, 1, &pidl, &fetched)) && fetched)
+ /* copy the items into the array */
+ while ((S_OK == IEnumIDList_Next(pEnumIDList, 1, &pidl, &fetched)) && fetched)
{
- if (DPA_InsertPtr(hdpa, DPA_GetPtrCount(hdpa), pidl) == -1)
- {
- SHFree(pidl);
- }
+ if (IncludeObject(This, pidl) == S_OK)
+ shellview_add_item(This, pidl);
}
- /* sort the array */
- DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
+ SendMessageW(This->hWndList, LVM_SORTITEMS, (WPARAM)This->pSFParent, (LPARAM)ShellView_CompareItems);
- IFolderView2_SetRedraw(folderview, FALSE);
- DPA_DestroyCallback(hdpa, fill_list, This);
IFolderView2_SetRedraw(folderview, TRUE);
IEnumIDList_Release(pEnumIDList);
-
return S_OK;
}
@@ -1626,6 +1601,7 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn
static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST *pidls, LONG event)
{
+ LPCITEMIDLIST pidl;
BOOL ret = TRUE;
TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pidls[0], pidls[1], event);
@@ -1634,7 +1610,8 @@ static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST *pi
{
case SHCNE_MKDIR:
case SHCNE_CREATE:
- LV_AddItem(This, pidls[0]);
+ pidl = ILClone(ILFindLastID(pidls[0]));
+ shellview_add_item(This, pidl);
break;
case SHCNE_RMDIR:
case SHCNE_DELETE:
More information about the wine-cvs
mailing list