From 6b6f9719398ea56f93b31db5234b4b799af723ec Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 28 Sep 2020 09:27:01 +0900 Subject: [PATCH] [BROWSEUI][SHELL32] Enable Ctrl+Backspace in AutoComplete edit boxes (#3242) The key combination Ctrl+Back is well working in auto-completion edit boxes. CORE-1419 --- dll/win32/browseui/CAutoComplete.cpp | 51 +++++++++++++++++++++++++++ dll/win32/shell32/dialogs/dialogs.cpp | 7 ++++ 2 files changed, 58 insertions(+) diff --git a/dll/win32/browseui/CAutoComplete.cpp b/dll/win32/browseui/CAutoComplete.cpp index 8bf5b152e84..e984dab2f17 100644 --- a/dll/win32/browseui/CAutoComplete.cpp +++ b/dll/win32/browseui/CAutoComplete.cpp @@ -3,6 +3,7 @@ * * Copyright 2004 Maxime Bellengé * Copyright 2009 Andrew Hill + * Copyright 2020 Katayama Hirofumi MZ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -279,6 +280,48 @@ HRESULT WINAPI CAutoComplete::SetOptions(DWORD dwFlag) return hr; } +/* Edit_BackWord --- Delete previous word in text box */ +static void Edit_BackWord(HWND hwndEdit) +{ + INT iStart, iEnd; + iStart = iEnd = 0; + SendMessageW(hwndEdit, EM_GETSEL, (WPARAM)&iStart, (LPARAM)&iEnd); + + if (iStart != iEnd) + return; + + DWORD cchText = GetWindowTextLengthW(hwndEdit); + size_t cb = (cchText + 1) * sizeof(WCHAR); + LPWSTR pszText = (LPWSTR)CoTaskMemAlloc(cb); + if (pszText == NULL) + return; + + if (GetWindowTextW(hwndEdit, pszText, cchText + 1) <= 0) + { + CoTaskMemFree(pszText); + return; + } + + for (; 0 < iStart; --iStart) + { + if (IsCharSpaceW(pszText[iStart - 1]) && IsCharAlphaNumericW(pszText[iStart])) + { + SendMessageW(hwndEdit, EM_SETSEL, iStart, iEnd); + SendMessageW(hwndEdit, EM_REPLACESEL, TRUE, (LPARAM)L""); + iStart = -1; + break; + } + } + + if (iStart == 0) + { + SendMessageW(hwndEdit, EM_SETSEL, iStart, iEnd); + SendMessageW(hwndEdit, EM_REPLACESEL, TRUE, (LPARAM)L""); + } + + CoTaskMemFree(pszText); +} + /* Window procedure for autocompletion */ @@ -407,6 +450,14 @@ LRESULT APIENTRY CAutoComplete::ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM }; break; case VK_BACK: + { + if (GetKeyState(VK_CONTROL) < 0) // Ctrl+Backspace + { + Edit_BackWord(hwnd); + return 0; + } + } + // FALL THROUGH case VK_DELETE: { if ((! *hwndText) && (pThis->options & ACO_AUTOSUGGEST)) diff --git a/dll/win32/shell32/dialogs/dialogs.cpp b/dll/win32/shell32/dialogs/dialogs.cpp index aa71de0b1f4..6996a416076 100644 --- a/dll/win32/shell32/dialogs/dialogs.cpp +++ b/dll/win32/shell32/dialogs/dialogs.cpp @@ -547,11 +547,18 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA ComboInfo.cbSize = sizeof(ComboInfo); GetComboBoxInfo(hwndCombo, &ComboInfo); hwndEdit = ComboInfo.hwndItem; + ASSERT(::IsWindow(hwndEdit)); + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // SHAutoComplete needs co init SHAutoComplete(hwndEdit, SHACF_FILESYSTEM | SHACF_FILESYS_ONLY | SHACF_URLALL); SetFocus(hwndCombo); return TRUE; + case WM_DESTROY: + CoUninitialize(); + break; + case WM_COMMAND: switch (LOWORD(wParam)) {