[PATCH 3/3] comdlg32: Optimize locking in file dialog.

Lauri Kenttä lauri.kentta at gmail.com
Thu Jun 23 06:29:56 CDT 2016


Related to bug 26803.

When FILEDLG95_FILENAME_FillFromSelection loops through the files,
it repeatedly calls IDataObject_GetData, GlobalLock etc.
This patch locks the memory only once, when the loop begins.

This gives 20% speed-up for selecting 253 files with shift-click.

Signed-off-by: Lauri Kenttä <lauri.kentta at gmail.com>
---
 dlls/comdlg32/filedlg.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c
index ffe1471..6ba511b 100644
--- a/dlls/comdlg32/filedlg.c
+++ b/dlls/comdlg32/filedlg.c
@@ -225,6 +225,8 @@ LPITEMIDLIST  GetParentPidl(LPITEMIDLIST pidl);
 static LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPWSTR lpcstrFileName);
 static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl);
 static UINT GetNumSelected( IDataObject *doSelected );
+static void COMCTL32_ReleaseStgMedium(STGMEDIUM medium);
+static FORMATETC* GetFormatEtc(void);
 
 /* Shell memory allocation */
 static void *MemAlloc(UINT size);
@@ -3631,12 +3633,19 @@ void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
   UINT nFiles = 0, nFileToOpen, nFileSelected, nLength = 0, nTempLength;
   WCHAR lpstrTemp[MAX_PATH];
   LPWSTR lpstrAllFiles;
+  STGMEDIUM medium;
+  LPIDA cida;
 
   TRACE("\n");
   fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
+  if (FAILED(IDataObject_GetData(fodInfos->Shell.FOIDataObject, GetFormatEtc(), &medium)))
+    return;
+
+  cida = GlobalLock(medium.u.hGlobal);
+
   /* Count how many files we have */
-  nFileSelected = GetNumSelected( fodInfos->Shell.FOIDataObject );
+  nFileSelected = cida->cidl;
 
   /* Allocate a buffer that is surely big enough; n * (MAX_PATH + quotes) + extra space at the end */
   lpstrAllFiles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nFileSelected * (MAX_PATH + 2) + 1) * sizeof(WCHAR));
@@ -3646,7 +3655,7 @@ void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
   /* Loop through the selection, handle only files (not folders) */
   for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
   {
-    pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
+    pidl = (LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nFileToOpen+1]]);
     if (pidl)
     {
       if (!IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl))
@@ -3663,7 +3672,6 @@ void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
         lpstrAllFiles[nLength++] = ' ';
         lpstrAllFiles[nLength] = 0;
       }
-      COMDLG32_SHFree( pidl );
     }
   }
 
@@ -3680,6 +3688,7 @@ void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
   }
 
   HeapFree(GetProcessHeap(), 0, lpstrAllFiles);
+  COMCTL32_ReleaseStgMedium(medium);
 }
 
 
-- 
2.9.0




More information about the wine-patches mailing list