]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/textentry.cpp
fixing focus, fixes #11911
[wxWidgets.git] / src / msw / textentry.cpp
index 7a30e5daf8d80c8d090937e899ac1470ae0bd6ff..298e07b8ebf5559a7ac80e3b11fc4f88f6e34417 100644 (file)
 
 #include "wx/msw/private.h"
 
+#if wxUSE_UXTHEME
+    #include "wx/msw/uxtheme.h"
+#endif
+
 #define GetEditHwnd() ((HWND)(GetEditHWND()))
 
 // ----------------------------------------------------------------------------
@@ -75,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,
@@ -152,7 +162,7 @@ private:
     virtual ~wxIEnumString() { }
 
 
-    const wxArrayString m_strings;
+    wxArrayString m_strings;
     unsigned m_index;
 
     wxDECLARE_NO_COPY_CLASS(wxIEnumString);
@@ -180,7 +190,7 @@ void wxTextEntry::WriteText(const wxString& text)
     ::SendMessage(GetEditHwnd(), EM_REPLACESEL, 0, (LPARAM)text.wx_str());
 }
 
-wxString wxTextEntry::GetValue() const
+wxString wxTextEntry::DoGetValue() const
 {
     return wxGetWindowText(GetEditHWND());
 }
@@ -301,7 +311,7 @@ bool wxTextEntry::AutoCompleteFileNames()
     static wxDynamicLibrary s_dllShlwapi;
     if ( s_pfnSHAutoComplete == (SHAutoComplete_t)-1 )
     {
-        if ( !s_dllShlwapi.Load(_T("shlwapi.dll"), wxDL_VERBATIM | wxDL_QUIET) )
+        if ( !s_dllShlwapi.Load(wxT("shlwapi.dll"), wxDL_VERBATIM | wxDL_QUIET) )
         {
             s_pfnSHAutoComplete = NULL;
         }
@@ -317,7 +327,7 @@ bool wxTextEntry::AutoCompleteFileNames()
     HRESULT hr = (*s_pfnSHAutoComplete)(GetEditHwnd(), SHACF_FILESYS_ONLY);
     if ( FAILED(hr) )
     {
-        wxLogApiError(_T("SHAutoComplete()"), hr);
+        wxLogApiError(wxT("SHAutoComplete()"), hr);
 
         return false;
     }
@@ -330,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
@@ -345,18 +363,18 @@ bool wxTextEntry::AutoComplete(const wxArrayString& choices)
                  );
     if ( FAILED(hr) )
     {
-        wxLogApiError(_T("CoCreateInstance(CLSID_AutoComplete)"), hr);
+        wxLogApiError(wxT("CoCreateInstance(CLSID_AutoComplete)"), hr);
         return false;
     }
 
     // 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);
+        wxLogApiError(wxT("IAutoComplete::Init"), hr);
         return false;
     }
 
@@ -416,4 +434,88 @@ void wxTextEntry::SetMaxLength(unsigned long len)
     ::SendMessage(GetEditHwnd(), EM_LIMITTEXT, len, 0);
 }
 
+// ----------------------------------------------------------------------------
+// hints
+// ----------------------------------------------------------------------------
+
+#if wxUSE_UXTHEME
+
+#ifndef EM_SETCUEBANNER
+    #define EM_SETCUEBANNER 0x1501
+    #define EM_GETCUEBANNER 0x1502
+#endif
+
+bool wxTextEntry::SetHint(const wxString& hint)
+{
+    if ( wxUxThemeEngine::GetIfActive() )
+    {
+        // notice that this message always works with Unicode strings
+        //
+        // we always use TRUE for wParam to show the hint even when the window
+        // has focus, otherwise there would be no way to show the hint for the
+        // initially focused window
+        if ( ::SendMessage(GetEditHwnd(), EM_SETCUEBANNER,
+                             TRUE, (LPARAM)(const wchar_t *)hint.wc_str()) )
+            return true;
+    }
+
+    return wxTextEntryBase::SetHint(hint);
+}
+
+wxString wxTextEntry::GetHint() const
+{
+    if ( wxUxThemeEngine::GetIfActive() )
+    {
+        wchar_t buf[256];
+        if ( ::SendMessage(GetEditHwnd(), EM_GETCUEBANNER,
+                            (WPARAM)buf, WXSIZEOF(buf)) )
+            return wxString(buf);
+    }
+
+    return wxTextEntryBase::GetHint();
+}
+
+
+#endif // wxUSE_UXTHEME
+
+// ----------------------------------------------------------------------------
+// margins support
+// ----------------------------------------------------------------------------
+
+bool wxTextEntry::DoSetMargins(const wxPoint& margins)
+{
+#if !defined(__WXWINCE__)
+    bool res = true;
+
+    if ( margins.x != -1 )
+    {
+        // left margin
+        ::SendMessage(GetEditHwnd(), EM_SETMARGINS,
+                      EC_LEFTMARGIN, MAKELONG(margins.x, 0));
+    }
+
+    if ( margins.y != -1 )
+    {
+        res = false;
+    }
+
+    return res;
+#else
+    return false;
+#endif
+}
+
+wxPoint wxTextEntry::DoGetMargins() const
+{
+#if !defined(__WXWINCE__)
+    LRESULT lResult = ::SendMessage(GetEditHwnd(), EM_GETMARGINS,
+                                    0, 0);
+    int left = LOWORD(lResult);
+    int top = -1;
+    return wxPoint(left, top);
+#else
+    return wxPoint(-1, -1);
+#endif
+}
+
 #endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX