On Mon, Sep 10, 2018 at 10:09:37PM +0300, Gabriel Ivăncescu wrote:
AutoComplete currently shows up when the user releases a key, which is wrong. Windows does it when the user presses a key, so use both WM_KEYDOWN and WM_CHAR and redesign it so that it matches Windows behavior.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
dlls/shell32/autocomplete.c | 97 +++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 39 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c index 7421679..49cf37a 100644 --- a/dlls/shell32/autocomplete.c +++ b/dlls/shell32/autocomplete.c @@ -134,10 +134,11 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, { IAutoCompleteImpl *This = GetPropW(hwnd, autocomplete_propertyW); HRESULT hr;
- LRESULT ret; WCHAR *hwndText; UINT len, size, cpt; RECT r;
- BOOL displayall = FALSE;
BOOLEAN displayall = FALSE, noautoappend = !(This->options & ACO_AUTOAPPEND); int height, sel;
if (!This->enabled) return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
@@ -154,20 +155,20 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, ShowWindow(This->hwndListBox, SW_HIDE); } return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
case WM_KEYUP:len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);size = len + 1;if (!(hwndText = heap_alloc(size * sizeof(WCHAR))))return 0;len = SendMessageW(hwnd, WM_GETTEXT, size, (LPARAM)hwndText);
case WM_KEYDOWN: switch(wParam) { case VK_RETURN: /* If quickComplete is set and control is pressed, replace the string */ if (This->quickComplete && (GetKeyState(VK_CONTROL) & 0x8000)) { WCHAR *buf;
size_t sz = strlenW(This->quickComplete) + 1 + len;
size_t sz;len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0) + 1; /* include NUL */if (!(hwndText = heap_alloc(len * sizeof(WCHAR))))return 0;len = SendMessageW(hwnd, WM_GETTEXT, len, (LPARAM)hwndText);sz = strlenW(This->quickComplete) + 1 + len;if ((buf = heap_alloc(sz * sizeof(WCHAR)))) { len = format_quick_complete(buf, This->quickComplete, hwndText, len);@@ -175,32 +176,31 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, SendMessageW(hwnd, EM_SETSEL, 0, len); heap_free(buf); }
if (This->options & ACO_AUTOSUGGEST)ShowWindow(This->hwndListBox, SW_HIDE);heap_free(hwndText);return 0; } if (This->options & ACO_AUTOSUGGEST) ShowWindow(This->hwndListBox, SW_HIDE);
heap_free(hwndText);return 0;case VK_LEFT:case VK_RIGHT:heap_free(hwndText);return 0;
break; case VK_UP: case VK_DOWN:
/* Two cases here :- if the listbox is not visible, displays itwith all the entries if the style ACO_UPDOWNKEYDROPSLISTis present but does not select anything.
/* Two cases here:- if the listbox is not visible and ACO_UPDOWNKEYDROPSLIST isset, display it with all the entries, without selecting any - if the listbox is visible, change the selection */
if ( (This->options & (ACO_AUTOSUGGEST | ACO_UPDOWNKEYDROPSLIST))&& (!IsWindowVisible(This->hwndListBox) && (! *hwndText)) ){/* We must display all the entries */displayall = TRUE;} else {heap_free(hwndText);if (IsWindowVisible(This->hwndListBox)) {
if (This->options & ACO_AUTOSUGGEST) {if (!IsWindowVisible(This->hwndListBox)) {if (This->options & ACO_UPDOWNKEYDROPSLIST) {ret = 0;displayall = TRUE;noautoappend = TRUE;goto handle_char;
No. I'm not signing off on this. You're going to have to come on with a much cleaner way to do this.
}} else { int count; count = SendMessageW(This->hwndListBox, LB_GETCOUNT, 0, 0);@@ -228,20 +228,40 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, len = strlenW(This->txtbackup); SendMessageW(hwnd, EM_SETSEL, len, len); }
return 0; }
return 0; } break;case VK_BACK: case VK_DELETE:if ((! *hwndText) && (This->options & ACO_AUTOSUGGEST)) {heap_free(hwndText);ShowWindow(This->hwndListBox, SW_HIDE);return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);}break;
ret = CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);goto handle_control_char;}return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);case WM_CHAR:case WM_UNICHAR:ret = CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);if (wParam < ' '){handle_control_char:len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);if ((This->options & ACO_AUTOSUGGEST) && len == 0){ShowWindow(This->hwndListBox, SW_HIDE);return ret;}if (wParam != 0x16 /* ^V (paste) */)noautoappend = TRUE;}else{handle_char:len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0); }size = len + 1;if (!(hwndText = heap_alloc(size * sizeof(WCHAR))))return ret;len = SendMessageW(hwnd, WM_GETTEXT, size, (LPARAM)hwndText); if (len + 1 != size) hwndText = heap_realloc(hwndText, len + 1);@@ -252,7 +272,7 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, This->txtbackup = hwndText;
if (!displayall && !len)
break;
return ret; IEnumString_Reset(This->enumstr); for(cpt = 0;;) {@@ -264,7 +284,7 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, break;
if (!strncmpiW(hwndText, strs, len)) {
if (cpt == 0 && (This->options & ACO_AUTOAPPEND)) {
if (cpt == 0 && noautoappend == FALSE) { WCHAR buffW[255]; strcpyW(buffW, hwndText);@@ -301,8 +321,7 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, ShowWindow(This->hwndListBox, SW_HIDE); } }
break;
return ret; case WM_DESTROY: { WNDPROC proc = This->wpOrigEditProc;-- 1.9.1