[PATCH v2 7/8] shell32/autocomplete: Fix handling of Return key when an auto-suggestion item is selected
Gabriel Ivăncescu
gabrielopcode at gmail.com
Tue Sep 25 06:55:33 CDT 2018
When selecting an item from the AutoComplete's listbox, the Return key
should act the same as a left click on it (place the text, select it,
and hide the listbox). This matches Windows behavior.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
Also fixes quickComplete since a VK_RETURN is sent as a WM_CHAR of '\n'
when CTRL is pressed and it must not be forwarded in WM_CHAR. Furthermore,
we have to process this in WM_KEYDOWN to ensure correct behavior.
The problem isn't the autocompletion here, but rather the edit control,
which must not receive that character at all.
no_fwd_char is also needed for future patches (and even the next patch)
to suppress forwarding the respective char from the KeyDown (for example,
when ACO_USETAB will be implemented).
dlls/shell32/autocomplete.c | 39 +++++++++++++++++++++++++++++++++++++--
1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index b3a6808..e2ae8aa 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -69,6 +69,7 @@ typedef struct
LONG ref;
BOOLEAN initialized;
BOOLEAN enabled;
+ UCHAR no_fwd_char;
AUTOCOMPLETEOPTIONS options;
HWND hwndEdit;
HWND hwndListBox;
@@ -134,6 +135,34 @@ static size_t format_quick_complete(WCHAR *dst, const WCHAR *qc, const WCHAR *st
return dst - base;
}
+static BOOL select_item_with_return_key(IAutoCompleteImpl *ac, HWND hwnd)
+{
+ WCHAR *text;
+ HWND hwndListBox = ac->hwndListBox;
+ if (!(ac->options & ACO_AUTOSUGGEST))
+ return FALSE;
+
+ if (IsWindowVisible(hwndListBox))
+ {
+ INT sel = SendMessageW(hwndListBox, LB_GETCURSEL, 0, 0);
+ if (sel >= 0)
+ {
+ UINT len = SendMessageW(hwndListBox, LB_GETTEXTLEN, sel, 0);
+ if ((text = heap_alloc((len + 1) * sizeof(WCHAR))))
+ {
+ len = SendMessageW(hwndListBox, LB_GETTEXT, sel, (LPARAM)text);
+ set_text_and_selection(ac, hwnd, text, 0, len);
+ ShowWindow(hwndListBox, SW_HIDE);
+ ac->no_fwd_char = '\r'; /* RETURN char */
+ heap_free(text);
+ return TRUE;
+ }
+ }
+ }
+ ShowWindow(hwndListBox, SW_HIDE);
+ return FALSE;
+}
+
static LRESULT change_selection(IAutoCompleteImpl *ac, HWND hwnd, UINT key)
{
INT count = SendMessageW(ac->hwndListBox, LB_GETCOUNT, 0, 0);
@@ -324,6 +353,8 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
WCHAR *text, *buf;
size_t sz;
UINT len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
+ ac->no_fwd_char = '\n'; /* CTRL+RETURN char */
+
if (!(text = heap_alloc((len + 1) * sizeof(WCHAR))))
return 0;
len = SendMessageW(hwnd, WM_GETTEXT, len + 1, (LPARAM)text);
@@ -342,8 +373,8 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
return 0;
}
- if (ac->options & ACO_AUTOSUGGEST)
- ShowWindow(ac->hwndListBox, SW_HIDE);
+ if (select_item_with_return_key(ac, hwnd))
+ return 0;
break;
case VK_UP:
case VK_DOWN:
@@ -375,6 +406,7 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
return ret;
}
}
+ ac->no_fwd_char = '\0';
return CallWindowProcW(ac->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}
@@ -404,6 +436,9 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
return ACEditSubclassProc_KeyDown(This, hwnd, uMsg, wParam, lParam);
case WM_CHAR:
case WM_UNICHAR:
+ if (wParam == This->no_fwd_char) return 0;
+ This->no_fwd_char = '\0';
+
/* Don't autocomplete at all on most control characters */
if (iscntrlW(wParam) && !(wParam >= '\b' && wParam <= '\r'))
break;
--
1.9.1
More information about the wine-devel
mailing list