fixed several problems due to use of GetEditHWND() when the edit control is not available
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 7 Oct 2007 11:19:09 +0000 (11:19 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 7 Oct 2007 11:19:09 +0000 (11:19 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49072 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/combobox.h
src/msw/combobox.cpp

index 7d1b7b702569ba4734748a6e5cf58c671a529193..6b53f6835e2e82b6371e3508d820720ef61db903 100644 (file)
@@ -73,6 +73,7 @@ public:
     // resolve ambiguities among virtual functions inherited from both base
     // classes
     virtual void Clear();
+    virtual wxString GetValue() const;
     virtual void SetValue(const wxString& value);
     virtual wxString GetStringSelection() const
         { return wxChoice::GetStringSelection(); }
@@ -81,8 +82,7 @@ public:
     virtual void SetSelection(long from, long to)
         { wxTextEntry::SetSelection(from, to); }
     virtual int GetSelection() const { return wxChoice::GetSelection(); }
-    virtual void GetSelection(long *from, long *to) const
-        { wxTextEntry::GetSelection(from, to); }
+    virtual void GetSelection(long *from, long *to) const;
 
     virtual bool IsEditable() const;
 
@@ -116,8 +116,19 @@ protected:
     virtual void DoSetToolTip(wxToolTip *tip);
 #endif
 
+    // this is the overridden wxTextEntry method which should only be called
+    // when we do have an edit control so it asserts if this is not the case
     virtual WXHWND GetEditHWND() const;
 
+    // this is the implementation of GetEditHWND() which can also be used when
+    // we don't have the edit control, it simply returns NULL then
+    //
+    // try not to use this function unless absolutely necessary (as in the
+    // message handling code where the edit control might not be created yet
+    // for the messages we receive during the control creation) as normally
+    // just testing for IsEditable() and using GetEditHWND() should be enough
+    WXHWND GetEditHWNDIfAvailable() const;
+
 private:
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxComboBox)
     DECLARE_EVENT_TABLE()
index 93c931c85fdc01282c2fe5dea0943b2d25a59d89..bd3650dc3b47b0e18db87cb87f536dc554532a34 100644 (file)
@@ -235,6 +235,9 @@ WXLRESULT wxComboBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara
             {
                 // combobox selection sometimes spontaneously changes when its
                 // size changes, restore it to the old value if necessary
+                if ( !GetEditHWNDIfAvailable() )
+                    break;
+
                 long fromOld, toOld;
                 GetSelection(&fromOld, &toOld);
                 WXLRESULT result = wxChoice::MSWWindowProc(nMsg, wParam, lParam);
@@ -391,22 +394,27 @@ bool wxComboBox::MSWShouldPreProcessMessage(WXMSG *pMsg)
     return wxChoice::MSWShouldPreProcessMessage(pMsg);
 }
 
+WXHWND wxComboBox::GetEditHWNDIfAvailable() const
+{
+    POINT pt = { 4, 4 };
+    WXHWND hWndEdit = (WXHWND)::ChildWindowFromPoint(GetHwnd(), pt);
+    if ( hWndEdit == GetHWND() )
+        hWndEdit = NULL;
+
+    return hWndEdit;
+}
+
 WXHWND wxComboBox::GetEditHWND() const
 {
     // this function should not be called for wxCB_READONLY controls, it is
-    // the callers responsability to check this
+    // the callers responsibility to check this
     wxASSERT_MSG( !HasFlag(wxCB_READONLY),
                   _T("read-only combobox doesn't have any edit control") );
 
-    POINT pt;
-    pt.x = pt.y = 4;
-    HWND hwndEdit = ::ChildWindowFromPoint(GetHwnd(), pt);
-    if ( !hwndEdit || hwndEdit == GetHwnd() )
-    {
-        wxFAIL_MSG(_T("combobox without edit control?"));
-    }
+    WXHWND hWndEdit = GetEditHWNDIfAvailable();
+    wxASSERT_MSG( hWndEdit, _T("combobox without edit control?") );
 
-    return (WXHWND)hwndEdit;
+    return hWndEdit;
 }
 
 // ----------------------------------------------------------------------------
@@ -502,6 +510,12 @@ WXDWORD wxComboBox::MSWGetStyle(long style, WXDWORD *exstyle) const
 // wxComboBox text control-like methods
 // ----------------------------------------------------------------------------
 
+wxString wxComboBox::GetValue() const
+{
+    return HasFlag(wxCB_READONLY) ? GetStringSelection()
+                                  : wxTextEntry::GetValue();
+}
+
 void wxComboBox::SetValue(const wxString& value)
 {
     if ( HasFlag(wxCB_READONLY) )
@@ -517,6 +531,21 @@ void wxComboBox::Clear()
         wxTextEntry::Clear();
 }
 
+void wxComboBox::GetSelection(long *from, long *to) const
+{
+    if ( !HasFlag(wxCB_READONLY) )
+    {
+        wxTextEntry::GetSelection(from, to);
+    }
+    else // text selection doesn't make sense for read only comboboxes
+    {
+        if ( from )
+            *from = -1;
+        if ( to )
+            *to = -1;
+    }
+}
+
 bool wxComboBox::IsEditable() const
 {
     return !HasFlag(wxCB_READONLY) && wxTextEntry::IsEditable();