On Thu, Nov 01, 2018 at 09:41:53PM +0200, Gabriel Ivăncescu wrote:
Windows doesn't reset and re-enumerate it everytime autocompletion happens, and it also sorts the strings. This matches it more closely and makes it more useable on large lists as well.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
dlls/shell32/autocomplete.c | 209 +++++++++++++++++++++++++++++++------------- 1 file changed, 148 insertions(+), 61 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c index b3f86f3..d557a4a 100644 --- a/dlls/shell32/autocomplete.c +++ b/dlls/shell32/autocomplete.c @@ -240,7 +325,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;
Missed this before, but this is an unnecessary change. Let's also have a blank line between variable declarations and code.
- 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;
@@ -276,6 +365,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;
@@ -312,66 +404,58 @@ static BOOL display_matching_strs(IAutoCompleteImpl *ac, WCHAR *text, UINT len, HWND hwnd, enum autoappend_flag flag) { /* Return FALSE if we need to hide the listbox */
- UINT cpt;
- WCHAR **str = ac->enum_strs;
- UINT cnt, i, k;
- if (!str) return (ac->options & ACO_AUTOSUGGEST) ? FALSE : TRUE;
- if (ac->options & ACO_AUTOSUGGEST)
- if (len) {
SendMessageW(ac->hwndListBox, WM_SETREDRAW, FALSE, 0);SendMessageW(ac->hwndListBox, LB_RESETCONTENT, 0, 0);
i = find_matching_enum_str(ac, 0, text, len, -1);if (i == ~0)return (ac->options & ACO_AUTOSUGGEST) ? FALSE : TRUE;if (flag == autoappend_flag_yes)autoappend_str(ac, text, len, str[i], hwnd);if (!(ac->options & ACO_AUTOSUGGEST))return TRUE;/* Find the index beyond the last string that matches */k = find_matching_enum_str(ac, i + 1, text, len, 1); }k = (k == ~0 ? i : k) + 1;
- for (cpt = 0;;)
- {
HRESULT hr;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)
- else {
if (cpt){show_listbox(ac, cpt);SendMessageW(ac->hwndListBox, WM_SETREDRAW, TRUE, 0);}else
if (!(ac->options & ACO_AUTOSUGGEST))return TRUE;i = 0;k = ac->enum_strs_num; }if (k == 0) return FALSE;- cnt = k - i;
I mentioned the variable names in this function last time. 'i' and 'k' would be ok for loops, but here they're not used in that way; 'start' and 'end' would be much better choices. And like I said, then you really don't need 'cnt' at all.
- SendMessageW(ac->hwndListBox, WM_SETREDRAW, FALSE, 0);
- SendMessageW(ac->hwndListBox, LB_RESETCONTENT, 0, 0);
- SendMessageW(ac->hwndListBox, LB_INITSTORAGE, cnt, 0);
- do
SendMessageW(ac->hwndListBox, LB_INSERTSTRING, -1, (LPARAM)str[i]);- while (++i < k);
It's minor, but I would probably write this loop as a for loop with an empty initialization statement.
Huw.