+// ----------------------------------------------------------------------------
+// auto-completion
+// ----------------------------------------------------------------------------
+
+#if wxUSE_OLE
+bool wxTextEntry::AutoCompleteFileNames()
+{
+#ifdef HAS_AUTOCOMPLETE
+ typedef HRESULT (WINAPI *SHAutoComplete_t)(HWND, DWORD);
+ static SHAutoComplete_t s_pfnSHAutoComplete = (SHAutoComplete_t)-1;
+ static wxDynamicLibrary s_dllShlwapi;
+ if ( s_pfnSHAutoComplete == (SHAutoComplete_t)-1 )
+ {
+ if ( !s_dllShlwapi.Load(wxT("shlwapi.dll"), wxDL_VERBATIM | wxDL_QUIET) )
+ {
+ s_pfnSHAutoComplete = NULL;
+ }
+ else
+ {
+ wxDL_INIT_FUNC(s_pfn, SHAutoComplete, s_dllShlwapi);
+ }
+ }
+
+ if ( !s_pfnSHAutoComplete )
+ return false;
+
+ HRESULT hr = (*s_pfnSHAutoComplete)(GetEditHwnd(), SHACF_FILESYS_ONLY);
+ if ( FAILED(hr) )
+ {
+ wxLogApiError(wxT("SHAutoComplete()"), hr);
+
+ return false;
+ }
+ return true;
+#else // !HAS_AUTOCOMPLETE
+ return false;
+#endif // HAS_AUTOCOMPLETE/!HAS_AUTOCOMPLETE
+}
+
+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
+ // don't know when can this happen)
+ IAutoComplete *pAutoComplete = NULL;
+ HRESULT hr = CoCreateInstance
+ (
+ CLSID_AutoComplete,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IAutoComplete,
+ reinterpret_cast<void **>(&pAutoComplete)
+ );
+ if ( FAILED(hr) )
+ {
+ wxLogApiError(wxT("CoCreateInstance(CLSID_AutoComplete)"), hr);
+ return false;
+ }
+
+ // associate it with our strings
+ m_enumStrings = new wxIEnumString(choices);
+ m_enumStrings->AddRef();
+ hr = pAutoComplete->Init(GetEditHwnd(), m_enumStrings, NULL, NULL);
+ m_enumStrings->Release();
+ if ( FAILED(hr) )
+ {
+ wxLogApiError(wxT("IAutoComplete::Init"), hr);
+ return false;
+ }
+
+ // if IAutoComplete2 is available, set more user-friendly options
+ IAutoComplete2 *pAutoComplete2 = NULL;
+ hr = pAutoComplete->QueryInterface
+ (
+ IID_IAutoComplete2,
+ reinterpret_cast<void **>(&pAutoComplete2)
+ );
+ if ( SUCCEEDED(hr) )
+ {
+ pAutoComplete2->SetOptions(ACO_AUTOSUGGEST | ACO_UPDOWNKEYDROPSLIST);
+ pAutoComplete2->Release();
+ }
+
+ // the docs are unclear about when can we release it but it seems safe to
+ // do it immediately, presumably the edit control itself keeps a reference
+ // to the auto completer object
+ pAutoComplete->Release();
+ return true;
+#else // !HAS_AUTOCOMPLETE
+ wxUnusedVar(choices);
+
+ return false;
+#endif // HAS_AUTOCOMPLETE/!HAS_AUTOCOMPLETE
+}
+#endif // wxUSE_OLE
+
+// ----------------------------------------------------------------------------
+// editable state
+// ----------------------------------------------------------------------------
+