implemented, tested and documented wxTextCtrl::SetMaxLength()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11383 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2001-08-15 12:45:53 +00:00
parent 2cefcb34d2
commit d7eee191c5
13 changed files with 119 additions and 12 deletions

View File

@ -15,6 +15,7 @@ All (GUI):
- support for virtual list control added
- wxFindReplaceDialog added (based on work of Markus Greither)
- wxTextCtrl::SetMaxLength() added (wxMSW/wxGTK)
wxHTML:

View File

@ -39,6 +39,10 @@ which is generated by a wxTextCtrl control.}
which is generated by a wxTextCtrl control. Note that you must use
wxTE\_PROCESS\_ENTER flag when creating the control if you want it to generate
such events.}
\twocolitem{{\bf EVT\_TEXT\_MAXLEN(id, func)}}{Process a wxEVT\_COMMAND\_TEXT\_MAXLEN command,
which is generated by a wxTextCtrl control when the user tries to enter more
characters into it than the limit previosuly set with
\helpref{SetMaxLength}{wxtextctrlsetmaxlength}.}
\twocolitem{{\bf EVT\_MENU(id, func)}}{Process a wxEVT\_COMMAND\_MENU\_SELECTED command,
which is generated by a menu item.}
\twocolitem{{\bf EVT\_MENU\_RANGE(id1, id2, func)}}{Process a wxEVT\_COMMAND\_MENU\_RANGE command,

View File

@ -514,6 +514,28 @@ Sets the insertion point at the given position.
Sets the insertion point at the end of the text control. This is equivalent
to \helpref{SetInsertionPoint}{wxtextctrlsetinsertionpoint}(\helpref{GetLastPosition}{wxtextctrlgetlastposition}()).
\membersection{wxTextCtrl::SetMaxLength}\label{wxtextctrlsetmaxlength}
\func{virtual void}{SetMaxLength}{\param{unsigned long }{len}}
This function sets the maximum number of characters the user can enter into the
control. In other words, it allows to limit the text value length to {\it len}
not counting the terminating {\tt NUL} character.
If the user tries to enter more characters into the text control when it
already is filled up to the maximal length, a
{\tt wxEVT\_COMMAND\_TEXT\_MAXLEN} event is sent to notify the program about it
(giving it the possibility to show an explanatory message, for example) and the
extra input is discarded.
Note that this function may only be used with single line text controls.
\wxheading{Compatibility}
Only implemented in wxMSW/wxGTK starting with wxWindows 2.3.2.
The {\tt wxEVT\_COMMAND\_TEXT\_MAXLEN} event is only sent by wxMSW.
\membersection{wxTextCtrl::SetSelection}\label{wxtextctrlsetselection}
\func{virtual void}{SetSelection}{\param{long}{ from}, \param{long}{ to}}

View File

@ -120,6 +120,7 @@ BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED, 7)
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER, 8)
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL, 13)
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN, 14)
#endif // WXWIN_COMPATIBILITY_EVENT_TYPES
DECLARE_EVENT_TYPE(wxEVT_COMMAND_MENU_SELECTED, 9)
DECLARE_EVENT_TYPE(wxEVT_COMMAND_SLIDER_UPDATED, 10)

View File

@ -74,6 +74,8 @@ public:
// clears the dirty flag
virtual void DiscardEdits();
virtual void SetMaxLength(unsigned long len);
// writing text inserts it at the current position, appending always
// inserts it at the end
virtual void WriteText(const wxString& text);

View File

@ -74,6 +74,8 @@ public:
// clears the dirty flag
virtual void DiscardEdits();
virtual void SetMaxLength(unsigned long len);
// writing text inserts it at the current position, appending always
// inserts it at the end
virtual void WriteText(const wxString& text);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: textctrl.h
// Name: wx/msw/textctrl.h
// Purpose: wxTextCtrl class
// Author: Julian Smart
// Modified by:
@ -72,6 +72,8 @@ public:
// clears the dirty flag
virtual void DiscardEdits();
virtual void SetMaxLength(unsigned long len);
// writing text inserts it at the current position, appending always
// inserts it at the end
virtual void WriteText(const wxString& text);
@ -164,18 +166,21 @@ public:
void OnUpdateRedo(wxUpdateUIEvent& event);
protected:
#if wxUSE_RICHEDIT
bool m_isRich; // Are we using rich text edit to implement this?
#endif
// call this to increase the size limit (will do nothing if the current
// limit is big enough)
void AdjustSpaceLimit();
//
// returns true if we increased the limit to allow entering more text,
// false if we hit the limit set by SetMaxLength() and so didn't change it
bool AdjustSpaceLimit();
// override some base class virtuals
virtual bool MSWShouldPreProcessMessage(WXMSG* pMsg);
virtual wxSize DoGetBestSize() const;
#if wxUSE_RICHEDIT
bool m_isRich; // Are we using rich text edit to implement this?
#endif
private:
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxTextCtrl)

View File

@ -174,6 +174,10 @@ public:
// clears the dirty flag
virtual void DiscardEdits() = 0;
// set the max number of characters which may be entered in a single line
// text control
virtual void SetMaxLength(unsigned long WXUNUSED(len)) { }
// writing text inserts it at the current position, appending always
// inserts it at the end
virtual void WriteText(const wxString& text) = 0;
@ -289,6 +293,7 @@ BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED, 7)
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER, 8)
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL, 13)
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN, 14)
END_DECLARE_EVENT_TYPES()
#endif // !WXWIN_COMPATIBILITY_EVENT_TYPES
@ -332,6 +337,7 @@ typedef void (wxEvtHandler::*wxTextUrlEventFunction)(wxTextUrlEvent&);
#define EVT_TEXT(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_TEXT_UPDATED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL ),
#define EVT_TEXT_ENTER(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_TEXT_ENTER, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL ),
#define EVT_TEXT_URL(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_TEXT_URL, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxTextUrlEventFunction) & fn, (wxObject *) NULL ),
#define EVT_TEXT_MAXLEN(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_TEXT_MAXLEN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL ),
#endif // wxUSE_TEXTCTRL

View File

@ -66,8 +66,11 @@ public:
void OnKeyDown(wxKeyEvent& event);
void OnKeyUp(wxKeyEvent& event);
void OnChar(wxKeyEvent& event);
void OnText(wxCommandEvent& event);
void OnTextURL(wxTextUrlEvent& event);
void OnTextMaxLen(wxCommandEvent& event);
void OnMouseEvent(wxMouseEvent& event);
bool m_hasCapture;
@ -99,6 +102,7 @@ public:
MyTextCtrl *m_enter;
MyTextCtrl *m_tab;
MyTextCtrl *m_readonly;
MyTextCtrl *m_limited;
MyTextCtrl *m_multitext;
MyTextCtrl *m_horizontal;
@ -308,8 +312,11 @@ BEGIN_EVENT_TABLE(MyTextCtrl, wxTextCtrl)
EVT_KEY_DOWN(MyTextCtrl::OnKeyDown)
EVT_KEY_UP(MyTextCtrl::OnKeyUp)
EVT_CHAR(MyTextCtrl::OnChar)
EVT_TEXT(-1, MyTextCtrl::OnText)
EVT_TEXT_URL(-1, MyTextCtrl::OnTextURL)
EVT_TEXT_MAXLEN(-1, MyTextCtrl::OnTextMaxLen)
EVT_MOUSE_EVENTS(MyTextCtrl::OnMouseEvent)
END_EVENT_TABLE()
@ -524,6 +531,11 @@ void MyTextCtrl::OnText(wxCommandEvent& event)
}
}
void MyTextCtrl::OnTextMaxLen(wxCommandEvent& event)
{
wxLogMessage(_T("You can't enter more characters into this control."));
}
void MyTextCtrl::OnTextURL(wxTextUrlEvent& event)
{
const wxMouseEvent& ev = event.GetMouseEvent();
@ -667,6 +679,10 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
m_readonly = new MyTextCtrl( this, -1, "Read only",
wxPoint(10,90), wxSize(140,-1), wxTE_READONLY );
m_limited = new MyTextCtrl(this, -1, "Max 8 ch",
wxPoint(10, 130), wxSize(140, -1));
m_limited->SetMaxLength(8);
// multi line text controls
m_horizontal = new MyTextCtrl( this, -1, "Multiline text control with a horizontal scrollbar.",
@ -990,6 +1006,7 @@ void MyFrame::OnSetEnabled(wxCommandEvent& WXUNUSED(event))
m_panel->m_password->Enable(enabled);
m_panel->m_multitext->Enable(enabled);
m_panel->m_readonly->Enable(enabled);
m_panel->m_limited->Enable(enabled);
m_panel->m_textrich->Enable(enabled);
}

View File

@ -51,6 +51,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent, wxCommandEvent)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN)
// ----------------------------------------------------------------------------
// ctor

View File

@ -826,6 +826,14 @@ void wxTextCtrl::DiscardEdits()
m_modified = FALSE;
}
void wxTextCtrl::SetMaxLength(unsigned long len)
{
if ( !HasFlag(wxTE_MULTILINE) )
{
gtk_entry_set_max_length(GTK_ENTRY(m_text), len);
}
}
void wxTextCtrl::SetSelection( long from, long to )
{
wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );

View File

@ -826,6 +826,14 @@ void wxTextCtrl::DiscardEdits()
m_modified = FALSE;
}
void wxTextCtrl::SetMaxLength(unsigned long len)
{
if ( !HasFlag(wxTE_MULTILINE) )
{
gtk_entry_set_max_length(GTK_ENTRY(m_text), len);
}
}
void wxTextCtrl::SetSelection( long from, long to )
{
wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );

View File

@ -878,6 +878,11 @@ wxString wxTextCtrl::GetLineText(long lineNo) const
return str;
}
void wxTextCtrl::SetMaxLength(unsigned long len)
{
::SendMessage(GetHwnd(), EM_LIMITTEXT, len, 0);
}
// ----------------------------------------------------------------------------
// Undo/redo
// ----------------------------------------------------------------------------
@ -1020,8 +1025,8 @@ bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
case EN_KILLFOCUS:
{
wxFocusEvent event(param == EN_KILLFOCUS ? wxEVT_KILL_FOCUS
: wxEVT_SET_FOCUS,
m_windowId);
: wxEVT_SET_FOCUS,
m_windowId);
event.SetEventObject( this );
GetEventHandler()->ProcessEvent(event);
}
@ -1038,7 +1043,13 @@ bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
case EN_MAXTEXT:
// the text size limit has been hit - increase it
AdjustSpaceLimit();
if ( !AdjustSpaceLimit() )
{
wxCommandEvent event(wxEVT_COMMAND_TEXT_MAXLEN, m_windowId);
InitCommandEvent(event);
event.SetString(GetValue());
ProcessCommand(event);
}
break;
// the other notification messages are not processed
@ -1127,11 +1138,27 @@ void wxTextCtrl::OnEraseBackground(wxEraseEvent& event)
}
#endif
void wxTextCtrl::AdjustSpaceLimit()
bool wxTextCtrl::AdjustSpaceLimit()
{
#ifndef __WIN16__
unsigned int len = ::GetWindowTextLength(GetHwnd()),
limit = ::SendMessage(GetHwnd(), EM_GETLIMITTEXT, 0, 0);
unsigned int limit = ::SendMessage(GetHwnd(), 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(GetHwnd());
if ( len >= limit )
{
limit = len + 0x8000; // 32Kb
@ -1156,6 +1183,9 @@ void wxTextCtrl::AdjustSpaceLimit()
}
}
#endif // !Win16
// we changed the limit
return TRUE;
}
bool wxTextCtrl::AcceptsFocus() const