[PATCH 2/6] shell32/autocomplete: Introduce helpers for displaying the listbox based on the new enumeration cache

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


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

These will eventually replace most of the code in autocomplete_text in the
next patch.

 dlls/shell32/autocomplete.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index ee3a6be..235225e 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -338,6 +338,21 @@ static void hide_listbox(IAutoCompleteImpl *ac, HWND hwnd)
     free_enum_strs(ac);
 }
 
+static void show_listbox(IAutoCompleteImpl *ac, UINT cnt)
+{
+    RECT r;
+    UINT width, height;
+
+    GetWindowRect(ac->hwndEdit, &r);
+    SendMessageW(ac->hwndListBox, LB_CARETOFF, 0, 0);
+
+    /* Windows XP displays 7 lines at most, then it uses a scroll bar */
+    height = SendMessageW(ac->hwndListBox, LB_GETITEMHEIGHT, 0, 0) * min(cnt + 1, 7);
+    width = r.right - r.left;
+
+    SetWindowPos(ac->hwndListBox, HWND_TOP, r.left, r.bottom + 1, width, height, SWP_SHOWWINDOW);
+}
+
 static size_t format_quick_complete(WCHAR *dst, const WCHAR *qc, const WCHAR *str, size_t str_len)
 {
     /* Replace the first %s directly without using snprintf, to avoid
@@ -522,6 +537,60 @@ static void autoappend_str(IAutoCompleteImpl *ac, WCHAR *text, UINT len, WCHAR *
         heap_free(tmp);
 }
 
+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 */
+    WCHAR **str = ac->enum_strs;
+    UINT cnt, a, b, i;
+    if (!str) return (ac->options & ACO_AUTOSUGGEST) ? FALSE : TRUE;
+
+    if (len)
+    {
+        i = find_first_matching_enum_str(ac, text, len);
+        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 last string that begins with text, starting the search from i,
+           which is guaranteed to find at least one string (if none other, then i) */
+        a = i, b = ac->enum_strs_num;
+        do
+        {
+            UINT mid = (a + b - 1) / 2u;
+            if (!strncmpiW(text, str[mid], len))
+                a = mid + 1;
+            else
+                b = mid;
+        } while (a < b);
+    }
+    else
+    {
+        if (!(ac->options & ACO_AUTOSUGGEST))
+            return TRUE;
+        i = 0;
+        a = ac->enum_strs_num;
+        if (a == 0)
+            return FALSE;
+    }
+    cnt = a - i;
+
+    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 < a);
+
+    show_listbox(ac, cnt);
+    SendMessageW(ac->hwndListBox, WM_SETREDRAW, TRUE, 0);
+    return TRUE;
+}
+
 static void autocomplete_text(IAutoCompleteImpl *ac, HWND hwnd, enum autoappend_flag flag)
 {
     HRESULT hr;
-- 
1.9.1




More information about the wine-devel mailing list