X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/44cc96a80c09c8572e1315be66d29f6d610cbf78..e3276230de335908f70232b2a5ede43665bd8d9d:/src/msw/textctrl.cpp diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 16a0ef075b..47ec9ab448 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -248,6 +248,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase) BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase) EVT_CHAR(wxTextCtrl::OnChar) + EVT_KEY_DOWN(wxTextCtrl::OnKeyDown) EVT_DROP_FILES(wxTextCtrl::OnDropFiles) #if wxUSE_RICHEDIT @@ -483,9 +484,19 @@ bool wxTextCtrl::MSWCreateText(const wxString& value, valueWin = value; } + // suppress events sent during control creation: we're called either from + // the ctor and then we shouldn't generate any events for compatibility + // with the other ports, or from SetWindowStyleFlag() and then we shouldn't + // generate the events because our text doesn't really change, the fact + // that we (sometimes) need to recreate the control is just an + // implementation detail + m_updatesCount = -2; + if ( !MSWCreateControl(windowClass.wx_str(), msStyle, pos, size, valueWin) ) return false; + m_updatesCount = -1; + #if wxUSE_RICHEDIT if (IsRich()) { @@ -784,10 +795,12 @@ wxString wxTextCtrl::GetRange(long from, long to) const encoding = font.GetEncoding(); } +#if wxUSE_INTL if ( encoding == wxFONTENCODING_SYSTEM ) { encoding = wxLocale::GetSystemEncoding(); } +#endif // wxUSE_INTL if ( encoding == wxFONTENCODING_SYSTEM ) { @@ -974,6 +987,9 @@ wxTextCtrl::StreamIn(const wxString& value, const size_t len = conv.MB2WC(NULL, value.mb_str(), value.length()); + if (len == wxCONV_FAILED) + return false; + #if wxUSE_WCHAR_T wxWCharBuffer wchBuf(len); wchar_t *wpc = wchBuf.data(); @@ -1066,7 +1082,8 @@ wxTextCtrl::StreamOut(wxFontEncoding encoding, bool selectionOnly) const // conversion but what else can we do) wxCSConv conv(encoding); size_t lenNeeded = conv.WC2MB(NULL, wchBuf, 0); - if ( lenNeeded++ ) + + if ( lenNeeded != wxCONV_FAILED && lenNeeded++ ) { conv.WC2MB(wxStringBuffer(out, lenNeeded), wchBuf, lenNeeded); } @@ -1299,6 +1316,13 @@ void wxTextCtrl::DoSetSelection(long from, long to, int flags) #if wxUSE_RICHEDIT if ( IsRich() ) { + // if from and to are both -1, it means (in wxWidgets) that all text + // should be selected, translate this into Windows convention + if ( (from == -1) && (to == -1) ) + { + from = 0; + } + CHARRANGE range; range.cpMin = from; range.cpMax = to; @@ -1307,7 +1331,7 @@ void wxTextCtrl::DoSetSelection(long from, long to, int flags) else #endif // wxUSE_RICHEDIT { - ::SendMessage(hWnd, EM_SETSEL, from, to); + wxTextEntry::DoSetSelection(from, to, flags); } if ( (flags & SetSel_Scroll) && !IsFrozen() ) @@ -1784,7 +1808,7 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId); InitCommandEvent(event); event.SetString(GetValue()); - if ( GetEventHandler()->ProcessEvent(event) ) + if ( HandleWindowEvent(event) ) if ( !HasFlag(wxTE_MULTILINE) ) return; //else: multiline controls need Enter for themselves @@ -1833,6 +1857,35 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) event.Skip(); } +void wxTextCtrl::OnKeyDown(wxKeyEvent& event) +{ + // richedit control doesn't send WM_PASTE, WM_CUT and WM_COPY messages + // when Ctrl-V, X or C is pressed and this prevents wxClipboardTextEvent + // from working. So we work around it by intercepting these shortcuts + // ourselves and emitting clipboard events (which richedit will handle, + // so everything works as before, including pasting of rich text): + if ( event.GetModifiers() == wxMOD_CONTROL && IsRich() ) + { + switch ( event.GetKeyCode() ) + { + case 'C': + Copy(); + return; + case 'X': + Cut(); + return; + case 'V': + Paste(); + return; + default: + break; + } + } + + // no, we didn't process it + event.Skip(); +} + WXLRESULT wxTextCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { WXLRESULT lRc = wxTextCtrlBase::MSWWindowProc(nMsg, wParam, lParam); @@ -1877,13 +1930,6 @@ WXLRESULT wxTextCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara } } break; - - case WM_CUT: - case WM_COPY: - case WM_PASTE: - if ( HandleClipboardEvent(nMsg) ) - lRc = 0; - break; } return lRc; @@ -1928,17 +1974,6 @@ bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) { switch ( param ) { - case EN_SETFOCUS: - case EN_KILLFOCUS: - { - wxFocusEvent event(param == EN_KILLFOCUS ? wxEVT_KILL_FOCUS - : wxEVT_SET_FOCUS, - m_windowId); - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); - } - break; - case EN_CHANGE: SendUpdateEvent(); break; @@ -1954,7 +1989,9 @@ bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) } break; - // the other edit notification messages are not processed + // the other edit notification messages are not processed (or, in + // the case of EN_{SET/KILL}FOCUS were already handled at WM_SET/ + // KILLFOCUS level) default: return false; } @@ -2067,15 +2104,12 @@ void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event)) void wxTextCtrl::OnDelete(wxCommandEvent& WXUNUSED(event)) { - long from, to; - GetSelection(& from, & to); - if (from != -1 && to != -1) - Remove(from, to); + RemoveSelection(); } void wxTextCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event)) { - SetSelection(-1, -1); + SelectAll(); } void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event) @@ -2105,14 +2139,12 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event) void wxTextCtrl::OnUpdateDelete(wxUpdateUIEvent& event) { - long from, to; - GetSelection(& from, & to); - event.Enable(from != -1 && to != -1 && from != to && IsEditable()) ; + event.Enable( HasSelection() && IsEditable() ); } void wxTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event) { - event.Enable(GetLastPosition() > 0); + event.Enable( !IsEmpty() ); } void wxTextCtrl::OnContextMenu(wxContextMenuEvent& event) @@ -2141,13 +2173,15 @@ void wxTextCtrl::OnContextMenu(wxContextMenuEvent& event) event.Skip(); } -void wxTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event)) +void wxTextCtrl::OnSetFocus(wxFocusEvent& event) { // be sure the caret remains invisible if the user had hidden it if ( !m_isNativeCaretShown ) { ::HideCaret(GetHwnd()); } + + event.Skip(); } // ----------------------------------------------------------------------------