📄 textctrlce.cpp
字号:
{ len--; } buf[len] = 0; tmp.SetLength(len); } return str;}void wxTextCtrl::SetMaxLength(unsigned long len){ ::SendMessage(GetBuddyHwnd(), EM_LIMITTEXT, len, 0);}// ----------------------------------------------------------------------------// Undo/redo// ----------------------------------------------------------------------------void wxTextCtrl::Undo(){ if (CanUndo()) { ::SendMessage(GetBuddyHwnd(), EM_UNDO, 0, 0); }}void wxTextCtrl::Redo(){ if (CanRedo()) { ::SendMessage(GetBuddyHwnd(), EM_UNDO, 0, 0); }}bool wxTextCtrl::CanUndo() const{ return ::SendMessage(GetBuddyHwnd(), EM_CANUNDO, 0, 0) != 0;}bool wxTextCtrl::CanRedo() const{ return ::SendMessage(GetBuddyHwnd(), EM_CANUNDO, 0, 0) != 0;}// ----------------------------------------------------------------------------// caret handling// ----------------------------------------------------------------------------// ----------------------------------------------------------------------------// implemenation details// ----------------------------------------------------------------------------void wxTextCtrl::Command(wxCommandEvent & event){ SetValue(event.GetString()); ProcessCommand (event);}// ----------------------------------------------------------------------------// kbd input processing// ----------------------------------------------------------------------------void wxTextCtrl::OnChar(wxKeyEvent& event){ switch ( event.GetKeyCode() ) { case WXK_RETURN: if ( !HasFlag(wxTE_MULTILINE) ) { wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId); InitCommandEvent(event); event.SetString(GetValue()); if ( GetEventHandler()->ProcessEvent(event) ) return; } //else: multiline controls need Enter for themselves break; case WXK_TAB: // ok, so this is getting absolutely ridiculous but I don't see // any other way to fix this bug: when a multiline text control is // inside a wxFrame, we need to generate the navigation event as // otherwise nothing happens at all, but when the same control is // created inside a dialog, IsDialogMessage() *does* switch focus // all by itself and so if we do it here as well, it is advanced // twice and goes to the next control... to prevent this from // happening we're doing this ugly check, the logic being that if // we don't have focus then it had been already changed to the next // control // // the right thing to do would, of course, be to understand what // the hell is IsDialogMessage() doing but this is beyond my feeble // forces at the moment unfortunately if ( !(m_windowStyle & wxTE_PROCESS_TAB)) { if ( FindFocus() == this ) { int flags = 0; if (!event.ShiftDown()) flags |= wxNavigationKeyEvent::IsForward ; if (event.ControlDown()) flags |= wxNavigationKeyEvent::WinChange ; if (Navigate(flags)) return; } } else { // Insert tab since calling the default Windows handler // doesn't seem to do it WriteText(wxT("\t")); } 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); if ( nMsg == WM_GETDLGCODE ) { // we always want the chars and the arrows: the arrows for navigation // and the chars because we want Ctrl-C to work even in a read only // control long lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS; if ( IsEditable() ) { // we may have several different cases: // 1. normal case: both TAB and ENTER are used for dlg navigation // 2. ctrl which wants TAB for itself: ENTER is used to pass to the // next control in the dialog // 3. ctrl which wants ENTER for itself: TAB is used for dialog // navigation // 4. ctrl which wants both TAB and ENTER: Ctrl-ENTER is used to go // to the next control // the multiline edit control should always get <Return> for itself if ( HasFlag(wxTE_PROCESS_ENTER) || HasFlag(wxTE_MULTILINE) ) lDlgCode |= DLGC_WANTMESSAGE; if ( HasFlag(wxTE_PROCESS_TAB) ) lDlgCode |= DLGC_WANTTAB; lRc |= lDlgCode; } else // !editable { // NB: use "=", not "|=" as the base class version returns the // same flags is this state as usual (i.e. including // DLGC_WANTMESSAGE). This is strange (how does it work in the // native Win32 apps?) but for now live with it. lRc = lDlgCode; } } return lRc;}// ----------------------------------------------------------------------------// text control event processing// ----------------------------------------------------------------------------bool wxTextCtrl::SendUpdateEvent(){ // is event reporting suspended? if ( m_suppressNextUpdate ) { // do process the next one m_suppressNextUpdate = false; return false; } wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); InitCommandEvent(event); event.SetString(GetValue()); return ProcessCommand(event);}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; case EN_MAXTEXT: // the text size limit has been hit -- try to increase it if ( !AdjustSpaceLimit() ) { wxCommandEvent event(wxEVT_COMMAND_TEXT_MAXLEN, m_windowId); InitCommandEvent(event); event.SetString(GetValue()); ProcessCommand(event); } break; // the other edit notification messages are not processed default: return false; } // processed return true;}bool wxTextCtrl::AdjustSpaceLimit(){ unsigned int limit = ::SendMessage(GetBuddyHwnd(), EM_GETLIMITTEXT, 0, 0); // HACK: we try to automatically extend the limit for the amount of text // to allow (interactively) entering more than 64Kb of text under // Win9x but we shouldn't reset the text limit which was previously // set explicitly with SetMaxLength() // // we could solve this by storing the limit we set in wxTextCtrl but // to save space we prefer to simply test here the actual limit // value: we consider that SetMaxLength() can only be called for // values < 32Kb if ( limit < 0x8000 ) { // we've got more text than limit set by SetMaxLength() return false; } unsigned int len = ::GetWindowTextLength(GetBuddyHwnd()); if ( len >= limit ) { limit = len + 0x8000; // 32Kb if ( limit > 0xffff ) { // this will set it to a platform-dependent maximum (much more // than 64Kb under NT) limit = 0; } ::SendMessage(GetBuddyHwnd(), EM_LIMITTEXT, limit, 0L); } // we changed the limit return true;}bool wxTextCtrl::AcceptsFocus() const{ // we don't want focus if we can't be edited unless we're a multiline // control because then it might be still nice to get focus from keyboard // to be able to scroll it without mouse return (IsEditable() || IsMultiLine()) && wxControl::AcceptsFocus();}void wxTextCtrl::DoMoveWindow(int x, int y, int width, int height){ int widthBtn = GetBestSpinnerSize(IsVertical(GetWindowStyle())).x / 2; int widthText = width - widthBtn - MARGIN_BETWEEN; if ( widthText <= 0 ) { wxLogDebug(_T("not enough space for wxSpinCtrl!")); } if ( !::MoveWindow(GetBuddyHwnd(), x, y, widthText, height, TRUE) ) { wxLogLastError(wxT("MoveWindow(buddy)")); } x += widthText + MARGIN_BETWEEN; if ( !::MoveWindow(GetHwnd(), x, y, widthBtn, height, TRUE) ) { wxLogLastError(wxT("MoveWindow")); }}wxSize wxTextCtrl::DoGetBestSize() const{ int cx, cy; wxGetCharSize(GetBuddyHwnd(), &cx, &cy, GetFont()); int wText = DEFAULT_ITEM_WIDTH; int hText = cy; if ( m_windowStyle & wxTE_MULTILINE ) { hText *= wxMax(GetNumberOfLines(), 5); } //else: for single line control everything is ok // we have to add the adjustments for the control height only once, not // once per line, so do it after multiplication above hText += EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) - cy; return wxSize(wText, hText);}// ----------------------------------------------------------------------------// standard handlers for standard edit menu events// ----------------------------------------------------------------------------void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event)){ Cut();}void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event)){ Copy();}void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event)){ Paste();}void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event)){ Undo();}void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event)){ Redo();}void wxTextCtrl::OnDelete(wxCommandEvent& WXUNUSED(event)){ long from, to; GetSelection(& from, & to); if (from != -1 && to != -1) Remove(from, to);}void wxTextCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event)){ SetSelection(-1, -1);}void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event){ event.Enable( CanCut() );}void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event){ event.Enable( CanCopy() );}void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event){ event.Enable( CanPaste() );}void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event){ event.Enable( CanUndo() );}void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event){ event.Enable( CanRedo() );}void wxTextCtrl::OnUpdateDelete(wxUpdateUIEvent& event){ long from, to; GetSelection(& from, & to); event.Enable(from != -1 && to != -1 && from != to && IsEditable()) ;}void wxTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event){ event.Enable(GetLastPosition() > 0);}void wxTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event)){ // be sure the caret remains invisible if the user had hidden it if ( !m_isNativeCaretShown ) { ::HideCaret(GetBuddyHwnd()); }}#endif // wxUSE_TEXTCTRL && __SMARTPHONE__ && __WXWINCE__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -