X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e6a8416274252fb6ea33800cfce0e4ba0a0542f1..fcdd53359135f790b85728c4254b97095a56dad8:/src/msw/combobox.cpp diff --git a/src/msw/combobox.cpp b/src/msw/combobox.cpp index 93c931c85f..5faed26cb5 100644 --- a/src/msw/combobox.cpp +++ b/src/msw/combobox.cpp @@ -205,13 +205,6 @@ LRESULT APIENTRY _EXPORT wxComboEditWndProc(HWND hWnd, } } break; - - case WM_CUT: - case WM_COPY: - case WM_PASTE: - if( win->HandleClipboardEvent( message ) ) - return 0; - break; } return ::CallWindowProc(CASTWNDPROC gs_wndprocEdit, hWnd, message, wParam, lParam); @@ -235,6 +228,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); @@ -299,6 +295,11 @@ bool wxComboBox::MSWProcessEditMsg(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam) case WM_KILLFOCUS: return HandleKillFocus((WXHWND)wParam); + + case WM_CUT: + case WM_COPY: + case WM_PASTE: + return HandleClipboardEvent(msg); } return false; @@ -311,6 +312,18 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD id) switch ( param ) { + case CBN_DROPDOWN: + // remember the last selection, just as wxChoice does + m_lastAcceptedSelection = GetCurrentSelection(); + if ( m_lastAcceptedSelection == -1 ) + { + // but unlike with wxChoice we may have no selection but still + // have some text and we should avoid erasing it if the drop + // down is cancelled (see #8474) + m_lastAcceptedSelection = wxID_NONE; + } + break; + case CBN_SELENDOK: #ifndef __SMARTPHONE__ // we need to reset this to prevent the selection from being undone @@ -342,6 +355,7 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD id) // logical as the text does change) case CBN_EDITCHANGE: + if ( m_allowTextEvents ) { wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); @@ -363,7 +377,7 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD id) } // skip wxChoice version as it would generate its own events for - // CBN_SELENDOK + // CBN_SELENDOK and also interfere with our handling of CBN_DROPDOWN return true; } @@ -391,22 +405,28 @@ bool wxComboBox::MSWShouldPreProcessMessage(WXMSG *pMsg) return wxChoice::MSWShouldPreProcessMessage(pMsg); } +WXHWND wxComboBox::GetEditHWNDIfAvailable() const +{ + // notice that a slightly safer alternative could be to use FindWindowEx() + // but it's not available under WinCE so just take the first child for now + // to keep one version of the code for all platforms and fix it later if + // problems are discovered + + // we assume that the only child of the combobox is the edit window + return (WXHWND)::GetWindow(GetHwnd(), GW_CHILD); +} + 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 +522,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 +543,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(); @@ -553,15 +594,12 @@ void wxComboBox::OnRedo(wxCommandEvent& WXUNUSED(event)) void wxComboBox::OnDelete(wxCommandEvent& WXUNUSED(event)) { - long from, to; - GetSelection(& from, & to); - if (from != -1 && to != -1) - Remove(from, to); + RemoveSelection(); } void wxComboBox::OnSelectAll(wxCommandEvent& WXUNUSED(event)) { - SetSelection(-1, -1); + SelectAll(); } void wxComboBox::OnUpdateCut(wxUpdateUIEvent& event) @@ -581,12 +619,12 @@ void wxComboBox::OnUpdatePaste(wxUpdateUIEvent& event) void wxComboBox::OnUpdateUndo(wxUpdateUIEvent& event) { - event.Enable( CanUndo() ); + event.Enable( IsEditable() && CanUndo() ); } void wxComboBox::OnUpdateRedo(wxUpdateUIEvent& event) { - event.Enable( CanRedo() ); + event.Enable( IsEditable() && CanRedo() ); } void wxComboBox::OnUpdateDelete(wxUpdateUIEvent& event) @@ -596,7 +634,7 @@ void wxComboBox::OnUpdateDelete(wxUpdateUIEvent& event) void wxComboBox::OnUpdateSelectAll(wxUpdateUIEvent& event) { - event.Enable(IsEditable() && GetLastPosition() > 0); + event.Enable(IsEditable() && !wxTextEntry::IsEmpty()); } #if wxUSE_TOOLTIPS