Commit 9c221721 authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

shell32/autocomplete: Don't crash when there's another AutoComplete object on…

shell32/autocomplete: Don't crash when there's another AutoComplete object on the same edit control. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22333Signed-off-by: 's avatarGabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 36649d08
......@@ -93,6 +93,14 @@ static inline IAutoCompleteImpl *impl_from_IAutoCompleteDropDown(IAutoCompleteDr
return CONTAINING_RECORD(iface, IAutoCompleteImpl, IAutoCompleteDropDown_iface);
}
static void destroy_autocomplete_object(IAutoCompleteImpl *ac)
{
ac->hwndEdit = NULL;
if (ac->hwndListBox)
DestroyWindow(ac->hwndListBox);
IAutoComplete2_Release(&ac->IAutoComplete2_iface);
}
/*
Window procedure for autocompletion
*/
......@@ -276,10 +284,7 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
RemovePropW(hwnd, autocomplete_propertyW);
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)proc);
This->hwndEdit = NULL;
if (This->hwndListBox)
DestroyWindow(This->hwndListBox);
IAutoComplete2_Release(&This->IAutoComplete2_iface);
destroy_autocomplete_object(This);
return CallWindowProcW(proc, hwnd, uMsg, wParam, lParam);
}
default:
......@@ -434,7 +439,7 @@ static HRESULT WINAPI IAutoComplete2_fnInit(
LPCOLESTR pwzsRegKeyPath,
LPCOLESTR pwszQuickComplete)
{
IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
IAutoCompleteImpl *prev, *This = impl_from_IAutoComplete2(iface);
TRACE("(%p)->(%p, %p, %s, %s)\n",
This, hwndEdit, punkACL, debugstr_w(pwzsRegKeyPath), debugstr_w(pwszQuickComplete));
......@@ -461,10 +466,22 @@ static HRESULT WINAPI IAutoComplete2_fnInit(
This->initialized = TRUE;
This->hwndEdit = hwndEdit;
This->wpOrigEditProc = (WNDPROC) SetWindowLongPtrW( hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc);
/* Keep at least one reference to the object until the edit window is destroyed. */
/* If another AutoComplete object was previously assigned to this edit control,
release it but keep the same callback on the control, to avoid an infinite
recursive loop in ACEditSubclassProc while the property is set to this object */
prev = GetPropW(hwndEdit, autocomplete_propertyW);
SetPropW(hwndEdit, autocomplete_propertyW, This);
if (prev && prev->initialized) {
This->wpOrigEditProc = prev->wpOrigEditProc;
destroy_autocomplete_object(prev);
}
else
This->wpOrigEditProc = (WNDPROC) SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc);
/* Keep at least one reference to the object until the edit window is destroyed */
IAutoComplete2_AddRef(&This->IAutoComplete2_iface);
SetPropW( hwndEdit, autocomplete_propertyW, This );
if (This->options & ACO_AUTOSUGGEST)
create_listbox(This);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment