[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