From 68e6eb7d678e41eb3949fc682b7a9329bff2f3ec Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 22 Jul 2009 14:30:29 +0000 Subject: [PATCH] Don't call IAutoComplete::Init() twice for the same control as this leaks memory, just change the strings used for completion instead (closes #10968) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61493 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/textentry.h | 12 +++++++++++- src/msw/textentry.cpp | 24 +++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/wx/msw/textentry.h b/include/wx/msw/textentry.h index 11141000a9..ef5c4e201f 100644 --- a/include/wx/msw/textentry.h +++ b/include/wx/msw/textentry.h @@ -18,7 +18,12 @@ class WXDLLIMPEXP_CORE wxTextEntry : public wxTextEntryBase { public: - wxTextEntry() { } + wxTextEntry() + { +#if wxUSE_OLE + m_enumStrings = NULL; +#endif // wxUSE_OLE + } // implement wxTextEntryBase pure virtual methods virtual void WriteText(const wxString& text); @@ -74,6 +79,11 @@ protected: private: // implement this to return the HWND of the EDIT control virtual WXHWND GetEditHWND() const = 0; + +#if wxUSE_OLE + // enumerator for strings currently used for auto-completion or NULL + class wxIEnumString *m_enumStrings; +#endif // wxUSE_OLE }; #endif // _WX_MSW_TEXTENTRY_H_ diff --git a/src/msw/textentry.cpp b/src/msw/textentry.cpp index 5e1b753ee7..a204d577f4 100644 --- a/src/msw/textentry.cpp +++ b/src/msw/textentry.cpp @@ -79,6 +79,12 @@ public: m_index = 0; } + void ChangeStrings(const wxArrayString& strings) + { + m_strings = strings; + Reset(); + } + DECLARE_IUNKNOWN_METHODS; virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, @@ -156,7 +162,7 @@ private: virtual ~wxIEnumString() { } - const wxArrayString m_strings; + wxArrayString m_strings; unsigned m_index; wxDECLARE_NO_COPY_CLASS(wxIEnumString); @@ -334,6 +340,14 @@ bool wxTextEntry::AutoCompleteFileNames() bool wxTextEntry::AutoComplete(const wxArrayString& choices) { #ifdef HAS_AUTOCOMPLETE + // if we had an old enumerator we must reuse it as IAutoComplete doesn't + // free it if we call Init() again (see #10968) -- and it's also simpler + if ( m_enumStrings ) + { + m_enumStrings->ChangeStrings(choices); + return true; + } + // create an object exposing IAutoComplete interface (don't go for // IAutoComplete2 immediately as, presumably, it might be not available on // older systems as otherwise why do we have both -- although in practice I @@ -354,10 +368,10 @@ bool wxTextEntry::AutoComplete(const wxArrayString& choices) } // associate it with our strings - wxIEnumString *pEnumString = new wxIEnumString(choices); - pEnumString->AddRef(); - hr = pAutoComplete->Init(GetEditHwnd(), pEnumString, NULL, NULL); - pEnumString->Release(); + m_enumStrings = new wxIEnumString(choices); + m_enumStrings->AddRef(); + hr = pAutoComplete->Init(GetEditHwnd(), m_enumStrings, NULL, NULL); + m_enumStrings->Release(); if ( FAILED(hr) ) { wxLogApiError(_T("IAutoComplete::Init"), hr); -- 2.45.2