From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Wed, 22 Jul 2009 14:30:29 +0000 (+0000)
Subject: Don't call IAutoComplete::Init() twice for the same control as this leaks memory... 
X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/68e6eb7d678e41eb3949fc682b7a9329bff2f3ec

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
---

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);