[PATCH 3/6] shell32/autocomplete: Use the new sorted enumeration cache to AutoComplete

Gabriel Ivăncescu gabrielopcode at gmail.com
Tue Oct 23 06:26:04 CDT 2018


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/shell32/autocomplete.c | 81 ++++++++++++---------------------------------
 1 file changed, 21 insertions(+), 60 deletions(-)

diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 235225e..3083a10 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -25,7 +25,6 @@
   - implement ACO_FILTERPREFIXES style
   - implement ACO_RTLREADING style
   - implement ResetEnumerator
-  - string compares should be case-insensitive, the content of the list should be sorted
   
  */
 #include "config.h"
@@ -469,7 +468,11 @@ static LRESULT change_selection(IAutoCompleteImpl *ac, HWND hwnd, UINT key)
 
 static BOOL do_aclist_expand(IAutoCompleteImpl *ac, WCHAR *txt, WCHAR *last_delim)
 {
-    WCHAR c = last_delim[1];
+    WCHAR c;
+    free_enum_strs(ac);
+    IEnumString_Reset(ac->enumstr);  /* call before expand */
+
+    c = last_delim[1];
     last_delim[1] = '\0';
     IACList_Expand(ac->aclist, txt);
     last_delim[1] = c;
@@ -505,6 +508,9 @@ static BOOL aclist_expand(IAutoCompleteImpl *ac, WCHAR *txt)
         while (i--)
             if (strchrW(delims, txt[i]))
                 return do_aclist_expand(ac, txt, &txt[i]);
+
+        /* Windows doesn't expand without a delim, but it does reset */
+        free_enum_strs(ac);
     }
 
     return FALSE;
@@ -593,9 +599,9 @@ static BOOL display_matching_strs(IAutoCompleteImpl *ac, WCHAR *text, UINT len,
 
 static void autocomplete_text(IAutoCompleteImpl *ac, HWND hwnd, enum autoappend_flag flag)
 {
-    HRESULT hr;
     WCHAR *text;
-    UINT cpt, size, len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
+    BOOL expanded = FALSE;
+    UINT size, len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
 
     if (flag != autoappend_flag_displayempty && len == 0)
     {
@@ -611,74 +617,29 @@ static void autocomplete_text(IAutoCompleteImpl *ac, HWND hwnd, enum autoappend_
     if (len + 1 != size)
         text = heap_realloc(text, (len + 1) * sizeof(WCHAR));
 
-    /* Reset it here to simplify the logic in aclist_expand for
-       empty strings, since it tracks changes using txtbackup,
-       and Reset needs to be called before IACList::Expand */
-    IEnumString_Reset(ac->enumstr);
     if (ac->aclist)
     {
-        aclist_expand(ac, text);
         if (text[len - 1] == '\\' || text[len - 1] == '/')
             flag = autoappend_flag_no;
+        expanded = aclist_expand(ac, text);
+    }
+    if (expanded || !ac->enum_strs)
+    {
+        if (!expanded) IEnumString_Reset(ac->enumstr);
+        enumerate_strings(ac);
     }
 
-    /* Set txtbackup to point to text itself (which must not be released) */
+    /* Set txtbackup to point to text itself (which must not be released),
+       and it must be done here since aclist_expand uses it to track changes */
     heap_free(ac->txtbackup);
     ac->txtbackup = text;
 
-    if (ac->options & ACO_AUTOSUGGEST)
+    if (!display_matching_strs(ac, text, len, hwnd, flag))
     {
-        SendMessageW(ac->hwndListBox, WM_SETREDRAW, FALSE, 0);
+        /* Hide the listbox, but do not clear the enum strs, to match Windows */
+        ShowWindow(ac->hwndListBox, SW_HIDE);
         SendMessageW(ac->hwndListBox, LB_RESETCONTENT, 0, 0);
     }
-    for (cpt = 0;;)
-    {
-        LPOLESTR strs = NULL;
-        ULONG fetched;
-
-        hr = IEnumString_Next(ac->enumstr, 1, &strs, &fetched);
-        if (hr != S_OK)
-            break;
-
-        if (!strncmpiW(text, strs, len))
-        {
-            if (cpt == 0 && flag == autoappend_flag_yes)
-            {
-                autoappend_str(ac, text, len, strs, hwnd);
-                if (!(ac->options & ACO_AUTOSUGGEST))
-                {
-                    CoTaskMemFree(strs);
-                    break;
-                }
-            }
-
-            if (ac->options & ACO_AUTOSUGGEST)
-                SendMessageW(ac->hwndListBox, LB_ADDSTRING, 0, (LPARAM)strs);
-
-            cpt++;
-        }
-
-        CoTaskMemFree(strs);
-    }
-
-    if (ac->options & ACO_AUTOSUGGEST)
-    {
-        if (cpt)
-        {
-            RECT r;
-            UINT height = SendMessageW(ac->hwndListBox, LB_GETITEMHEIGHT, 0, 0);
-            SendMessageW(ac->hwndListBox, LB_CARETOFF, 0, 0);
-            GetWindowRect(hwnd, &r);
-            /* It seems that Windows XP displays 7 lines at most
-               and otherwise displays a vertical scroll bar */
-            SetWindowPos(ac->hwndListBox, HWND_TOP,
-                         r.left, r.bottom + 1, r.right - r.left, height * min(cpt + 1, 7),
-                         SWP_SHOWWINDOW );
-            SendMessageW(ac->hwndListBox, WM_SETREDRAW, TRUE, 0);
-        }
-        else
-            hide_listbox(ac, ac->hwndListBox);
-    }
 }
 
 static void destroy_autocomplete_object(IAutoCompleteImpl *ac)
-- 
1.9.1




More information about the wine-devel mailing list