Author: mjansen
Date: Mon Apr 17 09:35:08 2017
New Revision: 74347
URL:
http://svn.reactos.org/svn/reactos?rev=74347&view=rev
Log:
[BROWSEUI] Port some IAutoComplete changes from wine + fix a memory leak. This allows the
dropdown to show with ACO_AUTOSUGGEST and an empty input.
Modified:
trunk/reactos/dll/win32/browseui/CAutoComplete.cpp
trunk/reactos/dll/win32/browseui/CAutoComplete.h
Modified: trunk/reactos/dll/win32/browseui/CAutoComplete.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/browseui/CAutoCo…
==============================================================================
--- trunk/reactos/dll/win32/browseui/CAutoComplete.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/browseui/CAutoComplete.cpp [iso-8859-1] Mon Apr 17 09:35:08
2017
@@ -86,12 +86,32 @@
}
/******************************************************************************
+ * create_listbox
+ */
+void CAutoComplete::CreateListbox()
+{
+ HWND hwndParent = GetParent(hwndEdit);
+
+ /* FIXME : The listbox should be resizable with the mouse. WS_THICKFRAME looks ugly
*/
+ hwndListBox = CreateWindowExW(0, WC_LISTBOXW, NULL,
+ WS_BORDER | WS_CHILD | WS_VSCROLL | LBS_HASSTRINGS |
LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT,
+ hwndParent, NULL,
+ (HINSTANCE)GetWindowLongPtrW(hwndParent,
GWLP_HINSTANCE), NULL);
+
+ if (hwndListBox)
+ {
+ wpOrigLBoxProc = (WNDPROC)SetWindowLongPtrW(hwndListBox, GWLP_WNDPROC,
(LONG_PTR)ACLBoxSubclassProc);
+ SetWindowLongPtrW(hwndListBox, GWLP_USERDATA, (LONG_PTR)this);
+ }
+}
+
+
+/******************************************************************************
* IAutoComplete_fnInit
*/
HRESULT WINAPI CAutoComplete::Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR
pwzsRegKeyPath, LPCOLESTR pwszQuickComplete)
{
- static const WCHAR lbName[] =
{'L','i','s','t','B','o','x',0};
-
TRACE("(%p)->(0x%08lx, %p, %s, %s)\n",
this, hwndEdit, punkACL, debugstr_w(pwzsRegKeyPath),
debugstr_w(pwszQuickComplete));
@@ -128,28 +148,14 @@
this->hwndEdit = hwndEdit;
this->initialized = TRUE;
- wpOrigEditProc = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR)
ACEditSubclassProc);
-// SetWindowLongPtrW(hwndEdit, GWLP_USERDATA, (LONG_PTR)this);
- SetPropW( hwndEdit, autocomplete_propertyW, (HANDLE)this );
+ this->wpOrigEditProc = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC,
(LONG_PTR) ACEditSubclassProc);
+ /* Keep at least one reference to the object until the edit window is destroyed. */
+ this->AddRef();
+ SetPropW( this->hwndEdit, autocomplete_propertyW, (HANDLE)this );
if (options & ACO_AUTOSUGGEST)
{
- HWND hwndParent;
-
- hwndParent = GetParent(hwndEdit);
-
- /* FIXME : The listbox should be resizable with the mouse. WS_THICKFRAME looks
ugly */
- hwndListBox = CreateWindowExW(0, lbName, NULL,
- WS_BORDER | WS_CHILD | WS_VSCROLL | LBS_HASSTRINGS |
LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- hwndParent, NULL,
- (HINSTANCE)GetWindowLongPtrW(hwndParent, GWLP_HINSTANCE),
NULL);
-
- if (hwndListBox)
- {
- wpOrigLBoxProc = (WNDPROC)SetWindowLongPtrW(hwndListBox, GWLP_WNDPROC,
(LONG_PTR)ACLBoxSubclassProc);
- SetWindowLongPtrW(hwndListBox, GWLP_USERDATA, (LONG_PTR)this);
- }
+ this->CreateListbox();
}
if (pwzsRegKeyPath)
@@ -247,6 +253,9 @@
options = (AUTOCOMPLETEOPTIONS)dwFlag;
+ if ((options & ACO_AUTOSUGGEST) && hwndEdit && !hwndListBox)
+ CreateListbox();
+
return hr;
}
@@ -255,8 +264,7 @@
*/
LRESULT APIENTRY CAutoComplete::ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
- CAutoComplete *pThis = static_cast<CAutoComplete *>(GetPropW(hwnd,
autocomplete_propertyW));//GetWindowLongPtrW(hwnd, GWLP_USERDATA);
- LPOLESTR strs;
+ CAutoComplete *pThis = static_cast<CAutoComplete *>(GetPropW(hwnd,
autocomplete_propertyW));
HRESULT hr;
WCHAR hwndText[255];
WCHAR *hwndQCText;
@@ -341,9 +349,9 @@
/* Change the selection */
sel = SendMessageW(pThis->hwndListBox, LB_GETCURSEL, 0,
0);
if (wParam == VK_UP)
- sel = ((sel-1)<0)?count-1:sel-1;
+ sel = ((sel-1) < 0) ? count-1 : sel-1;
else
- sel = ((sel+1)>= count)?-1:sel+1;
+ sel = ((sel+1) >= count) ? -1 : sel+1;
SendMessageW(pThis->hwndListBox, LB_SETCURSEL, sel, 0);
@@ -428,26 +436,31 @@
pThis->enumstr->Reset();
filled = FALSE;
-
+ size_t curlen = wcslen(hwndText);
+
for(cpt = 0;;)
{
+ CComHeapPtr<OLECHAR> strs;
hr = pThis->enumstr->Next(1, &strs, &fetched);
if (hr != S_OK)
break;
- if ((LPWSTR)wcsstr(strs, hwndText) == strs)
- {
-
- if (pThis->options & ACO_AUTOAPPEND)
- {
- SetWindowTextW(hwnd, strs);
- SendMessageW(hwnd, EM_SETSEL, wcslen(hwndText), wcslen(strs));
- break;
+ if (!_wcsnicmp(hwndText, strs, curlen))
+ {
+
+ if (pThis->options & ACO_AUTOAPPEND && *hwndText)
+ {
+ CComBSTR str((PCWSTR)strs);
+ memcpy(str.m_str, hwndText, curlen * sizeof(WCHAR));
+ SetWindowTextW(hwnd, str);
+ SendMessageW(hwnd, EM_SETSEL, curlen, str.Length());
+ if (!(pThis->options & ACO_AUTOSUGGEST))
+ break;
}
if (pThis->options & ACO_AUTOSUGGEST)
{
- SendMessageW(pThis->hwndListBox, LB_ADDSTRING, 0,
(LPARAM)strs);
+ SendMessageW(pThis->hwndListBox, LB_ADDSTRING, 0,
(LPARAM)(LPOLESTR)strs);
filled = TRUE;
cpt++;
}
@@ -475,7 +488,15 @@
}
}; break;
-
+
+ case WM_DESTROY:
+ {
+ /* Release our reference that we had since ->Init() */
+ pThis->Release();
+ return 0;
+ }
+
+
default:
{
return CallWindowProcW(pThis->wpOrigEditProc, hwnd, uMsg, wParam,
lParam);
@@ -537,12 +558,28 @@
*/
HRESULT STDMETHODCALLTYPE CAutoComplete::GetDropDownStatus(DWORD *pdwFlags, LPWSTR
*ppwszString)
{
- FIXME("(%p, %p, %p): stub\n", this, pdwFlags, ppwszString);
+ BOOL dropped = IsWindowVisible(hwndListBox);
+
if (pdwFlags)
- *pdwFlags = 0;
+ *pdwFlags = (dropped ? ACDD_VISIBLE : 0);
+
if (ppwszString)
+ {
*ppwszString = NULL;
- return E_NOTIMPL;
+
+ if (dropped)
+ {
+ int sel = SendMessageW(hwndListBox, LB_GETCURSEL, 0, 0);
+ if (sel >= 0)
+ {
+ DWORD len = SendMessageW(hwndListBox, LB_GETTEXTLEN, sel, 0);
+ *ppwszString = (LPWSTR)CoTaskMemAlloc((len+1)*sizeof(WCHAR));
+ SendMessageW(hwndListBox, LB_GETTEXT, sel, (LPARAM)*ppwszString);
+ }
+ }
+ }
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE CAutoComplete::ResetEnumerator()
Modified: trunk/reactos/dll/win32/browseui/CAutoComplete.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/browseui/CAutoCo…
==============================================================================
--- trunk/reactos/dll/win32/browseui/CAutoComplete.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/browseui/CAutoComplete.h [iso-8859-1] Mon Apr 17 09:35:08
2017
@@ -48,6 +48,8 @@
static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
lParam);
static LRESULT APIENTRY ACLBoxSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
lParam);
+ void CreateListbox();
+
// IAutoComplete2
virtual HRESULT WINAPI Enable(BOOL fEnable);
virtual HRESULT WINAPI Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR pwzsRegKeyPath,
LPCOLESTR pwszQuickComplete);