[PATCH v5 1/4] shell32/autocomplete: Implement a cache and sort the enumerated strings for proper behavior
Huw Davies
huw at codeweavers.com
Fri Nov 2 06:44:58 CDT 2018
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 at 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.
More information about the wine-devel
mailing list