]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/textctrl.cpp
don't let def window proc start another drag operation if we just started one ourselv...
[wxWidgets.git] / src / univ / textctrl.cpp
index 09bf799a15b969bea2552bb9c90ce3a84924684b..487fb2fca0ec9a269704b69d02faa000d3e8c237 100644 (file)
@@ -1,12 +1,12 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        univ/textctrl.cpp
+// Name:        src/univ/textctrl.cpp
 // Purpose:     wxTextCtrl
 // Author:      Vadim Zeitlin
 // Modified by:
 // Created:     15.09.00
 // RCS-ID:      $Id$
 // Purpose:     wxTextCtrl
 // Author:      Vadim Zeitlin
 // Modified by:
 // Created:     15.09.00
 // RCS-ID:      $Id$
-// Copyright:   (c) 2000 Vadim Zeitlin
-// Licence:     wxWindows license
+// Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 /*
 /////////////////////////////////////////////////////////////////////////////
 
 /*
 
    Everywhere in this file LINE refers to a logical line of text, and ROW to a
    physical line of text on the display. They are the same unless WrapLines()
 
    Everywhere in this file LINE refers to a logical line of text, and ROW to a
    physical line of text on the display. They are the same unless WrapLines()
-   is TRUE in which case a single LINE may correspond to multiple ROWs.
+   is true in which case a single LINE may correspond to multiple ROWs.
 
    A text position is an unsigned int (which for reasons of compatibility is
 
    A text position is an unsigned int (which for reasons of compatibility is
-   still a long) from 0 to GetLastPosition() inclusive. The positions
+   still a long as wxTextPos) from 0 to GetLastPosition() inclusive. The positions
    correspond to the gaps between the letters so the position 0 is just
    before the first character and the last position is the one beyond the last
    character. For an empty text control GetLastPosition() returns 0.
    correspond to the gaps between the letters so the position 0 is just
    before the first character and the last position is the one beyond the last
    character. For an empty text control GetLastPosition() returns 0.
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "univtextctrl.h"
-#endif
-
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
 
 #if wxUSE_TEXTCTRL
 
 
 #if wxUSE_TEXTCTRL
 
+#include "wx/textctrl.h"
+
 #ifndef WX_PRECOMP
     #include "wx/log.h"
 #ifndef WX_PRECOMP
     #include "wx/log.h"
-
     #include "wx/dcclient.h"
     #include "wx/validate.h"
     #include "wx/dcclient.h"
     #include "wx/validate.h"
-    #include "wx/textctrl.h"
+    #include "wx/dataobj.h"
 #endif
 
 #endif
 
+#include <ctype.h>
+
 #include "wx/clipbrd.h"
 
 #include "wx/textfile.h"
 #include "wx/clipbrd.h"
 
 #include "wx/textfile.h"
     #include "wx/tokenzr.h"
 #endif // WXDEBUG_TEXT_REPLACE
 
     #include "wx/tokenzr.h"
 #endif // WXDEBUG_TEXT_REPLACE
 
+// ----------------------------------------------------------------------------
+// wxStdTextCtrlInputHandler: this control handles only the mouse/kbd actions
+// common to Win32 and GTK, platform-specific things are implemented elsewhere
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxStdTextCtrlInputHandler : public wxStdInputHandler
+{
+public:
+    wxStdTextCtrlInputHandler(wxInputHandler *inphand);
+
+    virtual bool HandleKey(wxInputConsumer *consumer,
+                           const wxKeyEvent& event,
+                           bool pressed);
+    virtual bool HandleMouse(wxInputConsumer *consumer,
+                             const wxMouseEvent& event);
+    virtual bool HandleMouseMove(wxInputConsumer *consumer,
+                                 const wxMouseEvent& event);
+    virtual bool HandleFocus(wxInputConsumer *consumer, const wxFocusEvent& event);
+
+protected:
+    // get the position of the mouse click
+    static wxTextPos HitTest(const wxTextCtrl *text, const wxPoint& pos);
+
+    // capture data
+    wxTextCtrl *m_winCapture;
+};
+
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
@@ -191,7 +217,7 @@ static inline void OrderPositions(wxTextPos& from, wxTextPos& to)
 
 // the value which is never used for text position, even not -1 which is
 // sometimes used for some special meaning
 
 // the value which is never used for text position, even not -1 which is
 // sometimes used for some special meaning
-static const wxTextPos INVALID_POS_VALUE = -2;
+static const wxTextPos INVALID_POS_VALUE = wxInvalidTextCoord;
 
 // overlap between pages (when using PageUp/Dn) in lines
 static const size_t PAGE_OVERLAP_IN_LINES = 1;
 
 // overlap between pages (when using PageUp/Dn) in lines
 static const size_t PAGE_OVERLAP_IN_LINES = 1;
@@ -201,7 +227,7 @@ static const size_t PAGE_OVERLAP_IN_LINES = 1;
 // ----------------------------------------------------------------------------
 
 // the data only used by single line text controls
 // ----------------------------------------------------------------------------
 
 // the data only used by single line text controls
-struct WXDLLEXPORT wxTextSingleLineData
+struct wxTextSingleLineData
 {
     // the position of the first visible pixel and the first visible column
     wxCoord m_ofsHorz;
 {
     // the position of the first visible pixel and the first visible column
     wxCoord m_ofsHorz;
@@ -225,7 +251,7 @@ struct WXDLLEXPORT wxTextSingleLineData
 };
 
 // the data only used by multi line text controls
 };
 
 // the data only used by multi line text controls
-struct WXDLLEXPORT wxTextMultiLineData
+struct wxTextMultiLineData
 {
     // the lines of text
     wxArrayString m_lines;
 {
     // the lines of text
     wxArrayString m_lines;
@@ -264,7 +290,7 @@ struct WXDLLEXPORT wxTextMultiLineData
         m_scrollRangeY = 0;
 
         m_updateScrollbarX =
         m_scrollRangeY = 0;
 
         m_updateScrollbarX =
-        m_updateScrollbarY = FALSE;
+        m_updateScrollbarY = false;
 
         m_widthMax = -1;
         m_lineLongest = 0;
 
         m_widthMax = -1;
         m_lineLongest = 0;
@@ -274,7 +300,7 @@ struct WXDLLEXPORT wxTextMultiLineData
 };
 
 // the data only used by multi line text controls in line wrap mode
 };
 
 // the data only used by multi line text controls in line wrap mode
-class WXDLLEXPORT wxWrappedLineData
+class wxWrappedLineData
 {
     // these functions set all our values, so give them access to them
 friend void wxTextCtrl::LayoutLine(wxTextCoord line,
 {
     // these functions set all our values, so give them access to them
 friend void wxTextCtrl::LayoutLine(wxTextCoord line,
@@ -361,14 +387,14 @@ public:
 
     // this code is unused any longer
 #if 0
 
     // this code is unused any longer
 #if 0
-    // return TRUE if the column is in the start of the last row (hence the row
+    // return true if the column is in the start of the last row (hence the row
     // it is in is not wrapped)
     bool IsLastRow(wxTextCoord colRowStart) const
     {
         return colRowStart == GetRowStart(m_rowsStart.GetCount());
     }
 
     // it is in is not wrapped)
     bool IsLastRow(wxTextCoord colRowStart) const
     {
         return colRowStart == GetRowStart(m_rowsStart.GetCount());
     }
 
-    // return TRUE if the column is the last column of the row starting in
+    // return true if the column is the last column of the row starting in
     // colRowStart
     bool IsLastColInRow(wxTextCoord colRowStart,
                         wxTextCoord colRowEnd,
     // colRowStart
     bool IsLastColInRow(wxTextCoord colRowStart,
                         wxTextCoord colRowEnd,
@@ -394,7 +420,7 @@ public:
         // caller got it wrong
         wxFAIL_MSG( _T("this column is not in the start of the row!") );
 
         // caller got it wrong
         wxFAIL_MSG( _T("this column is not in the start of the row!") );
 
-        return FALSE;
+        return false;
     }
 #endif // 0
 
     }
 #endif // 0
 
@@ -434,7 +460,7 @@ WX_DECLARE_OBJARRAY(wxWrappedLineData, wxArrayWrappedLinesData);
 #include "wx/arrimpl.cpp"
 WX_DEFINE_OBJARRAY(wxArrayWrappedLinesData);
 
 #include "wx/arrimpl.cpp"
 WX_DEFINE_OBJARRAY(wxArrayWrappedLinesData);
 
-struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData
+struct wxTextWrappedData : public wxTextMultiLineData
 {
     // the width of the column to the right of the text rect used for the
     // indicator mark display for the wrapped lines
 {
     // the width of the column to the right of the text rect used for the
     // indicator mark display for the wrapped lines
@@ -481,7 +507,7 @@ struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData
 // ----------------------------------------------------------------------------
 
 /*
 // ----------------------------------------------------------------------------
 
 /*
-   We use custom versions of wxWindows command processor to implement undo/redo
+   We use custom versions of wxWidgets command processor to implement undo/redo
    as we want to avoid storing the backpointer to wxTextCtrl in wxCommand
    itself: this is a waste of memory as all commands in the given command
    processor always have the same associated wxTextCtrl and so it makes sense
    as we want to avoid storing the backpointer to wxTextCtrl in wxCommand
    itself: this is a waste of memory as all commands in the given command
    processor always have the same associated wxTextCtrl and so it makes sense
@@ -495,12 +521,12 @@ struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData
 class wxTextCtrlCommand : public wxCommand
 {
 public:
 class wxTextCtrlCommand : public wxCommand
 {
 public:
-    wxTextCtrlCommand(const wxString& name) : wxCommand(TRUE, name) { }
+    wxTextCtrlCommand(const wxString& name) : wxCommand(true, name) { }
 
     // we don't use these methods as they don't make sense for us as we need a
     // wxTextCtrl to be applied
 
     // we don't use these methods as they don't make sense for us as we need a
     // wxTextCtrl to be applied
-    virtual bool Do() { wxFAIL_MSG(_T("shouldn't be called")); return FALSE; }
-    virtual bool Undo() { wxFAIL_MSG(_T("shouldn't be called")); return FALSE; }
+    virtual bool Do() { wxFAIL_MSG(_T("shouldn't be called")); return false; }
+    virtual bool Undo() { wxFAIL_MSG(_T("shouldn't be called")); return false; }
 
     // instead, our command processor uses these methods
     virtual bool Do(wxTextCtrl *text) = 0;
 
     // instead, our command processor uses these methods
     virtual bool Do(wxTextCtrl *text) = 0;
@@ -522,6 +548,8 @@ public:
 
     virtual bool CanUndo() const;
     virtual bool Do(wxTextCtrl *text);
 
     virtual bool CanUndo() const;
     virtual bool Do(wxTextCtrl *text);
+    virtual bool Do() { return wxTextCtrlCommand::Do(); }
+    virtual bool Undo() { return wxTextCtrlCommand::Undo(); }
     virtual bool Undo(wxTextCtrl *text);
 
 private:
     virtual bool Undo(wxTextCtrl *text);
 
 private:
@@ -545,6 +573,8 @@ public:
 
     virtual bool CanUndo() const;
     virtual bool Do(wxTextCtrl *text);
 
     virtual bool CanUndo() const;
     virtual bool Do(wxTextCtrl *text);
+    virtual bool Do() { return wxTextCtrlCommand::Do(); }
+    virtual bool Undo() { return wxTextCtrlCommand::Undo(); }
     virtual bool Undo(wxTextCtrl *text);
 
 private:
     virtual bool Undo(wxTextCtrl *text);
 
 private:
@@ -562,7 +592,7 @@ class wxTextCtrlCommandProcessor : public wxCommandProcessor
 public:
     wxTextCtrlCommandProcessor(wxTextCtrl *text)
     {
 public:
     wxTextCtrlCommandProcessor(wxTextCtrl *text)
     {
-        m_compressInserts = FALSE;
+        m_compressInserts = false;
 
         m_text = text;
     }
 
         m_text = text;
     }
@@ -571,7 +601,7 @@ public:
     virtual void Store(wxCommand *command);
 
     // stop compressing insert commands when this is called
     virtual void Store(wxCommand *command);
 
     // stop compressing insert commands when this is called
-    void StopCompressing() { m_compressInserts = FALSE; }
+    void StopCompressing() { m_compressInserts = false; }
 
     // accessors
     wxTextCtrl *GetTextCtrl() const { return m_text; }
 
     // accessors
     wxTextCtrl *GetTextCtrl() const { return m_text; }
@@ -591,7 +621,7 @@ private:
     // the control we're associated with
     wxTextCtrl *m_text;
 
     // the control we're associated with
     wxTextCtrl *m_text;
 
-    // if the flag is TRUE we're compressing subsequent insert commands into
+    // if the flag is true we're compressing subsequent insert commands into
     // one so that the entire typing could be undone in one call to Undo()
     bool m_compressInserts;
 };
     // one so that the entire typing could be undone in one call to Undo()
     bool m_compressInserts;
 };
@@ -600,15 +630,13 @@ private:
 // implementation
 // ============================================================================
 
 // implementation
 // ============================================================================
 
-BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase)
     EVT_CHAR(wxTextCtrl::OnChar)
 
     EVT_SIZE(wxTextCtrl::OnSize)
     EVT_CHAR(wxTextCtrl::OnChar)
 
     EVT_SIZE(wxTextCtrl::OnSize)
-
-    EVT_IDLE(wxTextCtrl::OnIdle)
 END_EVENT_TABLE()
 
 END_EVENT_TABLE()
 
-IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase)
 
 // ----------------------------------------------------------------------------
 // creation
 
 // ----------------------------------------------------------------------------
 // creation
@@ -620,8 +648,9 @@ void wxTextCtrl::Init()
     m_selStart =
     m_selEnd = -1;
 
     m_selStart =
     m_selEnd = -1;
 
-    m_isModified = FALSE;
-    m_isEditable = TRUE;
+    m_isModified = false;
+    m_isEditable = true;
+    m_wrapLines = false;
 
     m_posLast =
     m_curPos =
 
     m_posLast =
     m_curPos =
@@ -631,9 +660,6 @@ void wxTextCtrl::Init()
     m_heightLine =
     m_widthAvg = -1;
 
     m_heightLine =
     m_widthAvg = -1;
 
-    // init wxScrollHelper
-    SetWindow(this);
-
     // init the undo manager
     m_cmdProcessor = new wxTextCtrlCommandProcessor(this);
 
     // init the undo manager
     m_cmdProcessor = new wxTextCtrlCommandProcessor(this);
 
@@ -661,20 +687,27 @@ bool wxTextCtrl::Create(wxWindow *parent,
             style |= wxALWAYS_SHOW_SB;
         }
 
             style |= wxALWAYS_SHOW_SB;
         }
 
-        if ( style & wxTE_WORDWRAP )
-        {
-            // wrapping words means wrapping, hence no horz scrollbar
-            style &= ~wxHSCROLL;
-        }
+        // wrapping style: wxTE_DONTWRAP == wxHSCROLL so if it's _not_ given,
+        // we won't have horizontal scrollbar automatically, no need to do
+        // anything
 
         // TODO: support wxTE_NO_VSCROLL (?)
 
         // create data object for normal multiline or for controls with line
         // wrap as needed
         if ( style & wxHSCROLL )
 
         // TODO: support wxTE_NO_VSCROLL (?)
 
         // create data object for normal multiline or for controls with line
         // wrap as needed
         if ( style & wxHSCROLL )
+        {
             m_data.mdata = new wxTextMultiLineData;
             m_data.mdata = new wxTextMultiLineData;
-        else
+        }
+        else // we must wrap lines if we don't have horizontal scrollbar
+        {
+            // NB: we can't rely on HasFlag(wxHSCROLL) as the flags can change
+            //     later and even wxWindow::Create() itself temporarily resets
+            //     wxHSCROLL in wxUniv, so remember that we have a wrapped data
+            //     and not just a multi line data in a separate variable
+            m_wrapLines = true;
             m_data.wdata = new wxTextWrappedData;
             m_data.wdata = new wxTextWrappedData;
+        }
     }
     else
     {
     }
     else
     {
@@ -685,10 +718,15 @@ bool wxTextCtrl::Create(wxWindow *parent,
         m_data.sdata = new wxTextSingleLineData;
     }
 
         m_data.sdata = new wxTextSingleLineData;
     }
 
+#if wxUSE_TWO_WINDOWS
+    if ((style & wxBORDER_MASK) == 0)
+        style |= wxBORDER_SUNKEN;
+#endif
+
     if ( !wxControl::Create(parent, id, pos, size, style,
                             validator, name) )
     {
     if ( !wxControl::Create(parent, id, pos, size, style,
                             validator, name) )
     {
-        return FALSE;
+        return false;
     }
 
     SetCursor(wxCURSOR_IBEAM);
     }
 
     SetCursor(wxCURSOR_IBEAM);
@@ -712,7 +750,7 @@ bool wxTextCtrl::Create(wxWindow *parent,
 
     RecalcFontMetrics();
     SetValue(value);
 
     RecalcFontMetrics();
     SetValue(value);
-    SetBestSize(size);
+    SetInitialSize(size);
 
     m_isEditable = !(style & wxTE_READONLY);
 
 
     m_isEditable = !(style & wxTE_READONLY);
 
@@ -721,11 +759,14 @@ bool wxTextCtrl::Create(wxWindow *parent,
 
     // we can't show caret right now as we're not shown yet and so it would
     // result in garbage on the screen - we'll do it after first OnPaint()
 
     // we can't show caret right now as we're not shown yet and so it would
     // result in garbage on the screen - we'll do it after first OnPaint()
-    m_hasCaret = FALSE;
+    m_hasCaret = false;
 
     CreateInputHandler(wxINP_HANDLER_TEXTCTRL);
 
 
     CreateInputHandler(wxINP_HANDLER_TEXTCTRL);
 
-    return TRUE;
+    wxSizeEvent sizeEvent(GetSize(), GetId());
+    GetEventHandler()->ProcessEvent(sizeEvent);
+
+    return true;
 }
 
 wxTextCtrl::~wxTextCtrl()
 }
 
 wxTextCtrl::~wxTextCtrl()
@@ -747,7 +788,7 @@ wxTextCtrl::~wxTextCtrl()
 // set/get the value
 // ----------------------------------------------------------------------------
 
 // set/get the value
 // ----------------------------------------------------------------------------
 
-void wxTextCtrl::SetValue(const wxString& value)
+void wxTextCtrl::DoSetValue(const wxString& value, int flags)
 {
     if ( IsSingleLine() && (value == GetValue()) )
     {
 {
     if ( IsSingleLine() && (value == GetValue()) )
     {
@@ -762,7 +803,8 @@ void wxTextCtrl::SetValue(const wxString& value)
         SetInsertionPoint(0);
     }
 
         SetInsertionPoint(0);
     }
 
-    // TODO: should we generate the event or not, finally?
+    if ( flags & SetValue_SendEvent )
+        SendTextUpdatedEvent();
 }
 
 const wxArrayString& wxTextCtrl::GetLines() const
 }
 
 const wxArrayString& wxTextCtrl::GetLines() const
@@ -802,7 +844,7 @@ wxString wxTextCtrl::GetValue() const
 
 void wxTextCtrl::Clear()
 {
 
 void wxTextCtrl::Clear()
 {
-    SetValue(_T(""));
+    SetValue(wxEmptyString);
 }
 
 bool wxTextCtrl::ReplaceLine(wxTextCoord line,
 }
 
 bool wxTextCtrl::ReplaceLine(wxTextCoord line,
@@ -858,7 +900,7 @@ bool wxTextCtrl::ReplaceLine(wxTextCoord line,
             }
 
             // the number of rows changed
             }
 
             // the number of rows changed
-            return TRUE;
+            return true;
         }
     }
     else // no line wrap
         }
     }
     else // no line wrap
@@ -867,7 +909,7 @@ bool wxTextCtrl::ReplaceLine(wxTextCoord line,
     }
 
     // the number of rows didn't change
     }
 
     // the number of rows didn't change
-    return FALSE;
+    return false;
 }
 
 void wxTextCtrl::RemoveLine(wxTextCoord line)
 }
 
 void wxTextCtrl::RemoveLine(wxTextCoord line)
@@ -984,7 +1026,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
         //     as if it does we need to refresh everything below the changed
         //     text (it will be shifted...) and we can avoid it if there is no
         //     row relayout
         //     as if it does we need to refresh everything below the changed
         //     text (it will be shifted...) and we can avoid it if there is no
         //     row relayout
-        bool rowsNumberChanged = FALSE;
+        bool rowsNumberChanged = false;
 
         // (1) join lines
         const wxArrayString& linesOld = GetLines();
 
         // (1) join lines
         const wxArrayString& linesOld = GetLines();
@@ -1092,7 +1134,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
                 // we have the replacement line for this one
                 if ( ReplaceLine(line, lines[nReplaceLine]) )
                 {
                 // we have the replacement line for this one
                 if ( ReplaceLine(line, lines[nReplaceLine]) )
                 {
-                    rowsNumberChanged = TRUE;
+                    rowsNumberChanged = true;
                 }
 
                 UpdateMaxWidth(line);
                 }
 
                 UpdateMaxWidth(line);
@@ -1101,13 +1143,13 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
             {
                 // (4b) delete all extra lines (note that we need to delete
                 //      them backwards because indices shift while we do it)
             {
                 // (4b) delete all extra lines (note that we need to delete
                 //      them backwards because indices shift while we do it)
-                bool deletedLongestLine = FALSE;
+                bool deletedLongestLine = false;
                 for ( wxTextCoord lineDel = lineEnd; lineDel >= line; lineDel-- )
                 {
                     if ( lineDel == MData().m_lineLongest )
                     {
                         // we will need to recalc the max line width
                 for ( wxTextCoord lineDel = lineEnd; lineDel >= line; lineDel-- )
                 {
                     if ( lineDel == MData().m_lineLongest )
                     {
                         // we will need to recalc the max line width
-                        deletedLongestLine = TRUE;
+                        deletedLongestLine = true;
                     }
 
                     RemoveLine(lineDel);
                     }
 
                     RemoveLine(lineDel);
@@ -1119,7 +1161,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
                 }
 
                 // even the line number changed
                 }
 
                 // even the line number changed
-                rowsNumberChanged = TRUE;
+                rowsNumberChanged = true;
 
                 // update line to exit the loop
                 line = lineEnd + 1;
 
                 // update line to exit the loop
                 line = lineEnd + 1;
@@ -1130,7 +1172,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
         if ( nReplaceLine < nReplaceCount )
         {
             // even the line number changed
         if ( nReplaceLine < nReplaceCount )
         {
             // even the line number changed
-            rowsNumberChanged = TRUE;
+            rowsNumberChanged = true;
 
             do
             {
 
             do
             {
@@ -1188,7 +1230,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
             RefreshLineRange(lineEnd + 1, 0);
 
             // the vert scrollbar might [dis]appear
             RefreshLineRange(lineEnd + 1, 0);
 
             // the vert scrollbar might [dis]appear
-            MData().m_updateScrollbarY = TRUE;
+            MData().m_updateScrollbarY = true;
         }
 
         // must recalculate it - will do later
         }
 
         // must recalculate it - will do later
@@ -1230,7 +1272,7 @@ void wxTextCtrl::Remove(wxTextPos from, wxTextPos to)
     // if necessary
     OrderPositions(from, to);
 
     // if necessary
     OrderPositions(from, to);
 
-    Replace(from, to, _T(""));
+    Replace(from, to, wxEmptyString);
 }
 
 void wxTextCtrl::WriteText(const wxString& text)
 }
 
 void wxTextCtrl::WriteText(const wxString& text)
@@ -1402,8 +1444,12 @@ wxString wxTextCtrl::GetSelectionText() const
 void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to)
 {
     // selecting till -1 is the same as selecting to the end
 void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to)
 {
     // selecting till -1 is the same as selecting to the end
-    if ( to == -1 && from != -1 )
+    if ( to == -1 )
     {
     {
+        // and selecting (-1, -1) range is the same as selecting everything, by
+        // convention
+        if ( from == -1 )
+            from = 0;
         to = GetLastPosition();
     }
 
         to = GetLastPosition();
     }
 
@@ -1413,6 +1459,10 @@ void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to)
     }
     else // valid sel range
     {
     }
     else // valid sel range
     {
+        // remember the 'to' position as the current position, used to move the
+        // caret there later
+        wxTextPos toOrig = to;
+
         OrderPositions(from, to);
 
         wxCHECK_RET( to <= GetLastPosition(),
         OrderPositions(from, to);
 
         wxCHECK_RET( to <= GetLastPosition(),
@@ -1458,8 +1508,8 @@ void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to)
         }
         //else: nothing to do
 
         }
         //else: nothing to do
 
-        // the insertion point is put at the end of selection
-        DoSetInsertionPoint(to);
+        // the insertion point is put at the location where the caret was moved
+        DoSetInsertionPoint(toOrig);
     }
 }
 
     }
 }
 
@@ -1503,7 +1553,7 @@ bool wxTextCtrl::GetSelectedPartOfLine(wxTextCoord line,
     if ( !HasSelection() )
     {
         // no selection at all, hence no selection in this line
     if ( !HasSelection() )
     {
         // no selection at all, hence no selection in this line
-        return FALSE;
+        return false;
     }
 
     wxTextCoord lineStart, colStart;
     }
 
     wxTextCoord lineStart, colStart;
@@ -1511,7 +1561,7 @@ bool wxTextCtrl::GetSelectedPartOfLine(wxTextCoord line,
     if ( lineStart > line )
     {
         // this line is entirely above the selection
     if ( lineStart > line )
     {
         // this line is entirely above the selection
-        return FALSE;
+        return false;
     }
 
     wxTextCoord lineEnd, colEnd;
     }
 
     wxTextCoord lineEnd, colEnd;
@@ -1519,7 +1569,7 @@ bool wxTextCtrl::GetSelectedPartOfLine(wxTextCoord line,
     if ( lineEnd < line )
     {
         // this line is entirely below the selection
     if ( lineEnd < line )
     {
         // this line is entirely below the selection
-        return FALSE;
+        return false;
     }
 
     if ( line == lineStart )
     }
 
     if ( line == lineStart )
@@ -1544,7 +1594,7 @@ bool wxTextCtrl::GetSelectedPartOfLine(wxTextCoord line,
             *end = GetLineLength(line);
     }
 
             *end = GetLineLength(line);
     }
 
-    return TRUE;
+    return true;
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -1562,9 +1612,14 @@ bool wxTextCtrl::IsEditable() const
     return m_isEditable && IsEnabled();
 }
 
     return m_isEditable && IsEnabled();
 }
 
+void wxTextCtrl::MarkDirty()
+{
+    m_isModified = true;
+}
+
 void wxTextCtrl::DiscardEdits()
 {
 void wxTextCtrl::DiscardEdits()
 {
-    m_isModified = FALSE;
+    m_isModified = false;
 }
 
 void wxTextCtrl::SetEditable(bool editable)
 }
 
 void wxTextCtrl::SetEditable(bool editable)
@@ -1620,7 +1675,10 @@ wxString wxTextCtrl::GetLineText(wxTextCoord line) const
     }
     else // multiline
     {
     }
     else // multiline
     {
-        wxCHECK_MSG( (size_t)line < GetLineCount(), _T(""),
+        //this is called during DoGetBestSize
+        if (line == 0 && GetLineCount() == 0) return wxEmptyString ;
+
+        wxCHECK_MSG( (size_t)line < GetLineCount(), wxEmptyString,
                      _T("line index out of range") );
 
         return GetLines()[line];
                      _T("line index out of range") );
 
         return GetLines()[line];
@@ -1639,7 +1697,7 @@ wxTextPos wxTextCtrl::XYToPosition(wxTextCoord x, wxTextCoord y) const
     // if they are out of range
     if ( IsSingleLine() )
     {
     // if they are out of range
     if ( IsSingleLine() )
     {
-        return x > GetLastPosition() || y > 0 ? -1 : x;
+        return ( x > GetLastPosition() || y > 0 ) ? wxOutOfRangeTextCoord : x;
     }
     else // multiline
     {
     }
     else // multiline
     {
@@ -1674,14 +1732,14 @@ bool wxTextCtrl::PositionToXY(wxTextPos pos,
     if ( IsSingleLine() )
     {
         if ( (size_t)pos > m_value.length() )
     if ( IsSingleLine() )
     {
         if ( (size_t)pos > m_value.length() )
-            return FALSE;
+            return false;
 
         if ( x )
             *x = pos;
         if ( y )
             *y = 0;
 
 
         if ( x )
             *x = pos;
         if ( y )
             *y = 0;
 
-        return TRUE;
+        return true;
     }
     else // multiline
     {
     }
     else // multiline
     {
@@ -1706,7 +1764,7 @@ bool wxTextCtrl::PositionToXY(wxTextPos pos,
                               _T("XYToPosition() or PositionToXY() broken") );
 #endif // WXDEBUG_TEXT
 
                               _T("XYToPosition() or PositionToXY() broken") );
 #endif // WXDEBUG_TEXT
 
-                return TRUE;
+                return true;
             }
             else // go further down
             {
             }
             else // go further down
             {
@@ -1715,7 +1773,7 @@ bool wxTextCtrl::PositionToXY(wxTextPos pos,
         }
 
         // beyond the last line
         }
 
         // beyond the last line
-        return FALSE;
+        return false;
     }
 }
 
     }
 }
 
@@ -1789,7 +1847,7 @@ bool wxTextCtrl::PositionToLogicalXY(wxTextPos pos,
     else // must really calculate col/line from pos
     {
         if ( !PositionToXY(pos, &col, &line) )
     else // must really calculate col/line from pos
     {
         if ( !PositionToXY(pos, &col, &line) )
-            return FALSE;
+            return false;
     }
 
     int hLine = GetLineHeight();
     }
 
     int hLine = GetLineHeight();
@@ -1818,7 +1876,7 @@ bool wxTextCtrl::PositionToLogicalXY(wxTextPos pos,
     if ( yOut )
         *yOut = y;
 
     if ( yOut )
         *yOut = y;
 
-    return TRUE;
+    return true;
 }
 
 bool wxTextCtrl::PositionToDeviceXY(wxTextPos pos,
 }
 
 bool wxTextCtrl::PositionToDeviceXY(wxTextPos pos,
@@ -1827,13 +1885,13 @@ bool wxTextCtrl::PositionToDeviceXY(wxTextPos pos,
 {
     wxCoord x, y;
     if ( !PositionToLogicalXY(pos, &x, &y) )
 {
     wxCoord x, y;
     if ( !PositionToLogicalXY(pos, &x, &y) )
-        return FALSE;
+        return false;
 
     // finally translate the logical text rect coords into physical client
     // coords
     CalcScrolledPosition(m_rectText.x + x, m_rectText.y + y, xOut, yOut);
 
 
     // finally translate the logical text rect coords into physical client
     // coords
     CalcScrolledPosition(m_rectText.x + x, m_rectText.y + y, xOut, yOut);
 
-    return TRUE;
+    return true;
 }
 
 wxPoint wxTextCtrl::GetCaretPosition() const
 }
 
 wxPoint wxTextCtrl::GetCaretPosition() const
@@ -1850,7 +1908,9 @@ wxPoint wxTextCtrl::GetCaretPosition() const
 // pos may be -1 to show the current position
 void wxTextCtrl::ShowPosition(wxTextPos pos)
 {
 // pos may be -1 to show the current position
 void wxTextCtrl::ShowPosition(wxTextPos pos)
 {
-    HideCaret();
+    bool showCaret = GetCaret() && GetCaret()->IsVisible();
+    if (showCaret)
+        HideCaret();
 
     if ( IsSingleLine() )
     {
 
     if ( IsSingleLine() )
     {
@@ -1970,7 +2030,8 @@ void wxTextCtrl::ShowPosition(wxTextPos pos)
     }
     //else: multiline but no scrollbars, hence nothing to do
 
     }
     //else: multiline but no scrollbars, hence nothing to do
 
-    ShowCaret();
+    if (showCaret)
+        ShowCaret();
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -2104,13 +2165,13 @@ void wxTextCtrl::Cut()
 bool wxTextCtrl::DoCut()
 {
     if ( !HasSelection() )
 bool wxTextCtrl::DoCut()
 {
     if ( !HasSelection() )
-        return FALSE;
+        return false;
 
     Copy();
 
     RemoveSelection();
 
 
     Copy();
 
     RemoveSelection();
 
-    return TRUE;
+    return true;
 }
 
 void wxTextCtrl::Paste()
 }
 
 void wxTextCtrl::Paste()
@@ -2134,12 +2195,12 @@ bool wxTextCtrl::DoPaste()
         {
             WriteText(text);
 
         {
             WriteText(text);
 
-            return TRUE;
+            return true;
         }
     }
 #endif // wxUSE_CLIPBOARD
 
         }
     }
 #endif // wxUSE_CLIPBOARD
 
-    return FALSE;
+    return false;
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -2179,7 +2240,7 @@ void wxTextCtrlCommandProcessor::Store(wxCommand *command)
         }
 
         // append the following insert commands to this one
         }
 
         // append the following insert commands to this one
-        m_compressInserts = TRUE;
+        m_compressInserts = true;
 
         // let the base class version will do the job normally
     }
 
         // let the base class version will do the job normally
     }
@@ -2214,17 +2275,17 @@ bool wxTextCtrlInsertCommand::Do(wxTextCtrl *text)
     // and now do insert it
     text->WriteText(m_text);
 
     // and now do insert it
     text->WriteText(m_text);
 
-    return TRUE;
+    return true;
 }
 
 bool wxTextCtrlInsertCommand::Undo(wxTextCtrl *text)
 {
 }
 
 bool wxTextCtrlInsertCommand::Undo(wxTextCtrl *text)
 {
-    wxCHECK_MSG( CanUndo(), FALSE, _T("impossible to undo insert cmd") );
+    wxCHECK_MSG( CanUndo(), false, _T("impossible to undo insert cmd") );
 
     // remove the text from where we inserted it
     text->Remove(m_from, m_from + m_text.length());
 
 
     // remove the text from where we inserted it
     text->Remove(m_from, m_from + m_text.length());
 
-    return TRUE;
+    return true;
 }
 
 bool wxTextCtrlRemoveCommand::CanUndo() const
 }
 
 bool wxTextCtrlRemoveCommand::CanUndo() const
@@ -2239,7 +2300,7 @@ bool wxTextCtrlRemoveCommand::Do(wxTextCtrl *text)
     m_textDeleted = text->GetSelectionText();
     text->RemoveSelection();
 
     m_textDeleted = text->GetSelectionText();
     text->RemoveSelection();
 
-    return TRUE;
+    return true;
 }
 
 bool wxTextCtrlRemoveCommand::Undo(wxTextCtrl *text)
 }
 
 bool wxTextCtrlRemoveCommand::Undo(wxTextCtrl *text)
@@ -2250,7 +2311,7 @@ bool wxTextCtrlRemoveCommand::Undo(wxTextCtrl *text)
     text->SetInsertionPoint(m_from > posLast ? posLast : m_from);
     text->WriteText(m_textDeleted);
 
     text->SetInsertionPoint(m_from > posLast ? posLast : m_from);
     text->WriteText(m_textDeleted);
 
-    return TRUE;
+    return true;
 }
 
 void wxTextCtrl::Undo()
 }
 
 void wxTextCtrl::Undo()
@@ -2314,7 +2375,7 @@ wxSize wxTextCtrl::DoGetBestClientSize() const
             lines = 5;
         else if ( lines > 10 )
             lines = 10;
             lines = 5;
         else if ( lines > 10 )
             lines = 10;
-        h *= 10;
+        h *= lines;
     }
 
     wxRect rectText;
     }
 
     wxRect rectText;
@@ -2326,7 +2387,7 @@ wxSize wxTextCtrl::DoGetBestClientSize() const
 
 void wxTextCtrl::UpdateTextRect()
 {
 
 void wxTextCtrl::UpdateTextRect()
 {
-    wxRect rectTotal(wxPoint(0, 0), GetClientSize());
+    wxRect rectTotal(GetClientSize());
     wxCoord *extraSpace = WrapLines() ? &WData().m_widthMark : NULL;
     m_rectText = GetRenderer()->GetTextClientArea(this, rectTotal, extraSpace);
 
     wxCoord *extraSpace = WrapLines() ? &WData().m_widthMark : NULL;
     m_rectText = GetRenderer()->GetTextClientArea(this, rectTotal, extraSpace);
 
@@ -2429,7 +2490,7 @@ void wxTextCtrl::UpdateLastVisible()
     SData().m_colLastVisible += SData().m_colStart;
 
     wxLogTrace(_T("text"), _T("Last visible column/position is %d/%ld"),
     SData().m_colLastVisible += SData().m_colStart;
 
     wxLogTrace(_T("text"), _T("Last visible column/position is %d/%ld"),
-               SData().m_colLastVisible, SData().m_posLastVisible);
+               (int) SData().m_colLastVisible, (long) SData().m_posLastVisible);
 }
 
 void wxTextCtrl::OnSize(wxSizeEvent& event)
 }
 
 void wxTextCtrl::OnSize(wxSizeEvent& event)
@@ -2447,7 +2508,7 @@ void wxTextCtrl::OnSize(wxSizeEvent& event)
 #endif // 0
 
         MData().m_updateScrollbarX =
 #endif // 0
 
         MData().m_updateScrollbarX =
-        MData().m_updateScrollbarY = TRUE;
+        MData().m_updateScrollbarY = true;
     }
 
     event.Skip();
     }
 
     event.Skip();
@@ -2631,7 +2692,7 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
 
     wxString s(text);
     wxTextCoord col;
 
     wxString s(text);
     wxTextCoord col;
-    wxCoord wReal = -1;
+    wxCoord wReal = wxDefaultCoord;
     switch ( HitTestLine(s, m_rectText.width, &col) )
     {
             /*
     switch ( HitTestLine(s, m_rectText.width, &col) )
     {
             /*
@@ -2656,12 +2717,12 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
                     col--;
 
                     // recalc the width
                     col--;
 
                     // recalc the width
-                    wReal = -1;
+                    wReal = wxDefaultCoord;
                 }
                 //else: we can just see it
 
                 // wrap at any character or only at words boundaries?
                 }
                 //else: we can just see it
 
                 // wrap at any character or only at words boundaries?
-                if ( !(GetWindowStyle() & wxTE_LINEWRAP) )
+                if ( !(GetWindowStyle() & wxTE_CHARWRAP) )
                 {
                     // find the (last) not word char before this word
                     wxTextCoord colWordStart;
                 {
                     // find the (last) not word char before this word
                     wxTextCoord colWordStart;
@@ -2675,7 +2736,7 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
                         if ( colWordStart != col )
                         {
                             // will have to recalc the real width
                         if ( colWordStart != col )
                         {
                             // will have to recalc the real width
-                            wReal = -1;
+                            wReal = wxDefaultCoord;
 
                             col = colWordStart;
                         }
 
                             col = colWordStart;
                         }
@@ -2698,7 +2759,7 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
 
     if ( widthReal )
     {
 
     if ( widthReal )
     {
-        if ( wReal == -1 )
+        if ( wReal == wxDefaultCoord )
         {
             // calc it if not done yet
             wReal = GetTextWidth(s.Truncate(col));
         {
             // calc it if not done yet
             wReal = GetTextWidth(s.Truncate(col));
@@ -2918,6 +2979,18 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
     return res;
 }
 
     return res;
 }
 
+wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pt, long *pos) const
+{
+    wxTextCoord x, y;
+    wxTextCtrlHitTestResult rc = HitTest(pt, &x, &y);
+    if ( rc != wxTE_HT_UNKNOWN && pos )
+    {
+        *pos = XYToPosition(x, y);
+    }
+
+    return rc;
+}
+
 wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pos,
                                             wxTextCoord *colOut,
                                             wxTextCoord *rowOut) const
 wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pos,
                                             wxTextCoord *colOut,
                                             wxTextCoord *rowOut) const
@@ -2929,7 +3002,7 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLogical(const wxPoint& pos,
                                                    wxTextCoord *colOut,
                                                    wxTextCoord *rowOut) const
 {
                                                    wxTextCoord *colOut,
                                                    wxTextCoord *rowOut) const
 {
-    return HitTest2(pos.y, pos.x, 0, rowOut, colOut, NULL, NULL, FALSE);
+    return HitTest2(pos.y, pos.x, 0, rowOut, colOut, NULL, NULL, false);
 }
 
 wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
 }
 
 wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
@@ -3133,7 +3206,7 @@ bool wxTextCtrl::GetLineAndRow(wxTextCoord row,
                 rowInLine = 0;
 
     if ( row < 0 )
                 rowInLine = 0;
 
     if ( row < 0 )
-        return FALSE;
+        return false;
 
     int nLines = GetNumberOfLines();
     if ( WrapLines() )
 
     int nLines = GetNumberOfLines();
     if ( WrapLines() )
@@ -3156,13 +3229,13 @@ bool wxTextCtrl::GetLineAndRow(wxTextCoord row,
         if ( line == nLines )
         {
             // the row is out of range
         if ( line == nLines )
         {
             // the row is out of range
-            return FALSE;
+            return false;
         }
     }
     else // no line wrapping, everything is easy
     {
         if ( row >= nLines )
         }
     }
     else // no line wrapping, everything is easy
     {
         if ( row >= nLines )
-            return FALSE;
+            return false;
 
         line = row;
     }
 
         line = row;
     }
@@ -3172,7 +3245,7 @@ bool wxTextCtrl::GetLineAndRow(wxTextCoord row,
     if ( rowInLineOut )
         *rowInLineOut = rowInLine;
 
     if ( rowInLineOut )
         *rowInLineOut = rowInLine;
 
-    return TRUE;
+    return true;
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -3317,7 +3390,7 @@ void wxTextCtrl::ScrollText(wxTextCoord col)
         if ( dx > 0 )
         {
             // refresh the uncovered part on the left
         if ( dx > 0 )
         {
             // refresh the uncovered part on the left
-            Refresh(TRUE, &rect);
+            Refresh(true, &rect);
 
             // and now the area on the right
             rect.x = m_rectText.x + posLastVisible;
 
             // and now the area on the right
             rect.x = m_rectText.x + posLastVisible;
@@ -3330,7 +3403,7 @@ void wxTextCtrl::ScrollText(wxTextCoord col)
             rect.width += m_rectText.width - posLastVisible;
         }
 
             rect.width += m_rectText.width - posLastVisible;
         }
 
-        Refresh(TRUE, &rect);
+        Refresh(true, &rect);
 
         // I don't know exactly why is this needed here but without it we may
         // scroll the window again (from the same method) before the previously
 
         // I don't know exactly why is this needed here but without it we may
         // scroll the window again (from the same method) before the previously
@@ -3498,7 +3571,7 @@ void wxTextCtrl::UpdateScrollbars()
         // just to suppress compiler warnings about using uninit vars below
         charWidth = maxWidth = 0;
 
         // just to suppress compiler warnings about using uninit vars below
         charWidth = maxWidth = 0;
 
-        showScrollbarX = FALSE;
+        showScrollbarX = false;
     }
 
     // calc the scrollbars ranges
     }
 
     // calc the scrollbars ranges
@@ -3535,7 +3608,7 @@ void wxTextCtrl::UpdateScrollbars()
         SetScrollbars(charWidth, lineHeight,
                       scrollRangeX, scrollRangeY,
                       x, y,
         SetScrollbars(charWidth, lineHeight,
                       scrollRangeX, scrollRangeY,
                       x, y,
-                      TRUE /* no refresh */);
+                      true /* no refresh */);
 
         if ( scrollRangeXOld )
         {
 
         if ( scrollRangeXOld )
         {
@@ -3552,10 +3625,10 @@ void wxTextCtrl::UpdateScrollbars()
     }
 
     MData().m_updateScrollbarX =
     }
 
     MData().m_updateScrollbarX =
-    MData().m_updateScrollbarY = FALSE;
+    MData().m_updateScrollbarY = false;
 }
 
 }
 
-void wxTextCtrl::OnIdle(wxIdleEvent& event)
+void wxTextCtrl::OnInternalIdle()
 {
     // notice that single line text control never has scrollbars
     if ( !IsSingleLine() &&
 {
     // notice that single line text control never has scrollbars
     if ( !IsSingleLine() &&
@@ -3563,8 +3636,7 @@ void wxTextCtrl::OnIdle(wxIdleEvent& event)
     {
         UpdateScrollbars();
     }
     {
         UpdateScrollbars();
     }
-
-    event.Skip();
+    wxControl::OnInternalIdle();
 }
 
 bool wxTextCtrl::SendAutoScrollEvents(wxScrollWinEvent& event) const
 }
 
 bool wxTextCtrl::SendAutoScrollEvents(wxScrollWinEvent& event) const
@@ -3674,7 +3746,7 @@ void wxTextCtrl::RefreshTextRange(wxTextPos start, wxTextPos end)
         {
             // intermediate line or the last one but we need to refresh it
             // until the end anyhow - do it
         {
             // intermediate line or the last one but we need to refresh it
             // until the end anyhow - do it
-            posCount = wxSTRING_MAXLEN;
+            posCount = wxString::npos;
         }
         else // last line
         {
         }
         else // last line
         {
@@ -3792,7 +3864,7 @@ void wxTextCtrl::RefreshTextRect(const wxRect& rectClient, bool textOnly)
     rect.Offset(m_rectText.GetPosition());
 
     // don't refresh beyond the text area unless we're refreshing the line wrap
     rect.Offset(m_rectText.GetPosition());
 
     // don't refresh beyond the text area unless we're refreshing the line wrap
-    // marks in which case textOnly is FALSE
+    // marks in which case textOnly is false
     if ( textOnly )
     {
         if ( rect.GetRight() > m_rectText.GetRight() )
     if ( textOnly )
     {
         if ( rect.GetRight() > m_rectText.GetRight() )
@@ -3829,7 +3901,7 @@ void wxTextCtrl::RefreshTextRect(const wxRect& rectClient, bool textOnly)
     wxLogTrace(_T("text"), _T("Refreshing (%d, %d)-(%d, %d)"),
                rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
 
     wxLogTrace(_T("text"), _T("Refreshing (%d, %d)-(%d, %d)"),
                rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
 
-    Refresh(TRUE, &rect);
+    Refresh(true, &rect);
 }
 
 void wxTextCtrl::RefreshLineWrapMarks(wxTextCoord rowFirst,
 }
 
 void wxTextCtrl::RefreshLineWrapMarks(wxTextCoord rowFirst,
@@ -3843,7 +3915,7 @@ void wxTextCtrl::RefreshLineWrapMarks(wxTextCoord rowFirst,
         rectMarks.y = rowFirst*GetLineHeight();
         rectMarks.height = (rowLast - rowFirst)*GetLineHeight();
 
         rectMarks.y = rowFirst*GetLineHeight();
         rectMarks.height = (rowLast - rowFirst)*GetLineHeight();
 
-        RefreshTextRect(rectMarks, FALSE /* don't limit to text area */);
+        RefreshTextRect(rectMarks, false /* don't limit to text area */);
     }
 }
 
     }
 }
 
@@ -4101,6 +4173,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
     // the update region is in window coords and text area is in the client
     // ones, so it must be shifted before computing intersection
     wxRegion rgnUpdate = GetUpdateRegion();
     // the update region is in window coords and text area is in the client
     // ones, so it must be shifted before computing intersection
     wxRegion rgnUpdate = GetUpdateRegion();
+
     wxRect rectTextArea = GetRealTextArea();
     wxPoint pt = GetClientAreaOrigin();
     wxRect rectTextAreaAdjusted = rectTextArea;
     wxRect rectTextArea = GetRealTextArea();
     wxPoint pt = GetClientAreaOrigin();
     wxRect rectTextAreaAdjusted = rectTextArea;
@@ -4165,11 +4238,11 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
 
     // show caret first time only: we must show it after drawing the text or
     // the display can be corrupted when it's hidden
 
     // show caret first time only: we must show it after drawing the text or
     // the display can be corrupted when it's hidden
-    if ( !m_hasCaret && GetCaret() )
+    if ( !m_hasCaret && GetCaret() && (FindFocus() == this) )
     {
         ShowCaret();
 
     {
         ShowCaret();
 
-        m_hasCaret = TRUE;
+        m_hasCaret = true;
     }
 }
 
     }
 }
 
@@ -4180,7 +4253,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
 bool wxTextCtrl::SetFont(const wxFont& font)
 {
     if ( !wxControl::SetFont(font) )
 bool wxTextCtrl::SetFont(const wxFont& font)
 {
     if ( !wxControl::SetFont(font) )
-        return FALSE;
+        return false;
 
     // and refresh everything, of course
     InitInsertionPoint();
 
     // and refresh everything, of course
     InitInsertionPoint();
@@ -4200,17 +4273,20 @@ bool wxTextCtrl::SetFont(const wxFont& font)
 
     Refresh();
 
 
     Refresh();
 
-    return TRUE;
+    return true;
 }
 
 bool wxTextCtrl::Enable(bool enable)
 {
     if ( !wxTextCtrlBase::Enable(enable) )
 }
 
 bool wxTextCtrl::Enable(bool enable)
 {
     if ( !wxTextCtrlBase::Enable(enable) )
-        return FALSE;
+        return false;
 
 
-    ShowCaret(enable);
+    if (FindFocus() == this && GetCaret() &&
+        ((enable && !GetCaret()->IsVisible()) ||
+         (!enable && GetCaret()->IsVisible())))
+        ShowCaret(enable);
 
 
-    return TRUE;
+    return true;
 }
 
 void wxTextCtrl::CreateCaret()
 }
 
 void wxTextCtrl::CreateCaret()
@@ -4221,9 +4297,6 @@ void wxTextCtrl::CreateCaret()
     {
         // FIXME use renderer
         caret = new wxCaret(this, 1, GetLineHeight());
     {
         // FIXME use renderer
         caret = new wxCaret(this, 1, GetLineHeight());
-#ifndef __WXMSW__
-        caret->SetBlinkTime(0);
-#endif // __WXMSW__
     }
     else
     {
     }
     else
     {
@@ -4244,7 +4317,9 @@ void wxTextCtrl::ShowCaret(bool show)
         caret->Move(GetCaretPosition());
 
         // and show it there
         caret->Move(GetCaretPosition());
 
         // and show it there
-        caret->Show(show);
+        if ((show && !caret->IsVisible()) ||
+            (!show && caret->IsVisible()))
+            caret->Show(show);
     }
 }
 
     }
 }
 
@@ -4336,28 +4411,28 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
                                const wxString& strArg)
 {
     // has the text changed as result of this action?
                                const wxString& strArg)
 {
     // has the text changed as result of this action?
-    bool textChanged = FALSE;
+    bool textChanged = false;
 
     // the remembered cursor abscissa for multiline text controls is usually
     // reset after each user action but for ones which do use it (UP and DOWN
     // for example) we shouldn't do it - as indicated by this flag
 
     // the remembered cursor abscissa for multiline text controls is usually
     // reset after each user action but for ones which do use it (UP and DOWN
     // for example) we shouldn't do it - as indicated by this flag
-    bool rememberAbscissa = FALSE;
+    bool rememberAbscissa = false;
 
     // the command this action corresponds to or NULL if this action doesn't
     // change text at all or can't be undone
     wxTextCtrlCommand *command = (wxTextCtrlCommand *)NULL;
 
     wxString action;
 
     // the command this action corresponds to or NULL if this action doesn't
     // change text at all or can't be undone
     wxTextCtrlCommand *command = (wxTextCtrlCommand *)NULL;
 
     wxString action;
-    bool del = FALSE,
-         sel = FALSE;
+    bool del = false,
+         sel = false;
     if ( actionOrig.StartsWith(wxACTION_TEXT_PREFIX_DEL, &action) )
     {
         if ( IsEditable() )
     if ( actionOrig.StartsWith(wxACTION_TEXT_PREFIX_DEL, &action) )
     {
         if ( IsEditable() )
-            del = TRUE;
+            del = true;
     }
     else if ( actionOrig.StartsWith(wxACTION_TEXT_PREFIX_SEL, &action) )
     {
     }
     else if ( actionOrig.StartsWith(wxACTION_TEXT_PREFIX_SEL, &action) )
     {
-        sel = TRUE;
+        sel = true;
     }
     else // not selection nor delete action
     {
     }
     else // not selection nor delete action
     {
@@ -4397,7 +4472,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
             if ( newPos != INVALID_POS_VALUE )
             {
                 // remember where the cursor original had been
             if ( newPos != INVALID_POS_VALUE )
             {
                 // remember where the cursor original had been
-                rememberAbscissa = TRUE;
+                rememberAbscissa = true;
             }
         }
     }
             }
         }
     }
@@ -4410,7 +4485,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
             if ( newPos != INVALID_POS_VALUE )
             {
                 // remember where the cursor original had been
             if ( newPos != INVALID_POS_VALUE )
             {
                 // remember where the cursor original had been
-                rememberAbscissa = TRUE;
+                rememberAbscissa = true;
             }
         }
     }
             }
         }
     }
@@ -4437,7 +4512,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
             // inserting text can be undone
             command = new wxTextCtrlInsertCommand(strArg);
 
             // inserting text can be undone
             command = new wxTextCtrlInsertCommand(strArg);
 
-            textChanged = TRUE;
+            textChanged = true;
         }
     }
     else if ( (action == wxACTION_TEXT_PAGE_UP) ||
         }
     }
     else if ( (action == wxACTION_TEXT_PAGE_UP) ||
@@ -4454,7 +4529,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
             }
 
             // remember where the cursor original had been
             }
 
             // remember where the cursor original had been
-            rememberAbscissa = TRUE;
+            rememberAbscissa = true;
 
             bool goUp = action == wxACTION_TEXT_PAGE_UP;
             for ( size_t line = 0; line < count; line++ )
 
             bool goUp = action == wxACTION_TEXT_PAGE_UP;
             for ( size_t line = 0; line < count; line++ )
@@ -4501,7 +4576,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
             }
 
             // scroll vertically only
             }
 
             // scroll vertically only
-            Scroll(-1, y);
+            Scroll(wxDefaultCoord, y);
         }
     }
     else if ( action == wxACTION_TEXT_SEL_WORD )
         }
     }
     else if ( action == wxACTION_TEXT_SEL_WORD )
@@ -4616,7 +4691,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
         m_cmdProcessor->Submit(command);
 
         // undoable commands always change text
         m_cmdProcessor->Submit(command);
 
         // undoable commands always change text
-        textChanged = TRUE;
+        textChanged = true;
     }
     else // no undoable command
     {
     }
     else // no undoable command
     {
@@ -4629,14 +4704,13 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
 
         wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
         InitCommandEvent(event);
 
         wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
         InitCommandEvent(event);
-        event.SetString(GetValue());
         GetEventHandler()->ProcessEvent(event);
 
         // as the text changed...
         GetEventHandler()->ProcessEvent(event);
 
         // as the text changed...
-        m_isModified = TRUE;
+        m_isModified = true;
     }
 
     }
 
-    return TRUE;
+    return true;
 }
 
 void wxTextCtrl::OnChar(wxKeyEvent& event)
 }
 
 void wxTextCtrl::OnChar(wxKeyEvent& event)
@@ -4645,6 +4719,9 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
     if ( !event.HasModifiers() )
     {
         int keycode = event.GetKeyCode();
     if ( !event.HasModifiers() )
     {
         int keycode = event.GetKeyCode();
+#if wxUSE_UNICODE
+        wxChar unicode = event.GetUnicodeKey();
+#endif
         if ( keycode == WXK_RETURN )
         {
             if ( IsSingleLine() || (GetWindowStyle() & wxTE_PROCESS_ENTER) )
         if ( keycode == WXK_RETURN )
         {
             if ( IsSingleLine() || (GetWindowStyle() & wxTE_PROCESS_ENTER) )
@@ -4666,6 +4743,14 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
             // skip event.Skip() below
             return;
         }
             // skip event.Skip() below
             return;
         }
+#if wxUSE_UNICODE
+        else if (unicode > 0)
+        {
+            PerformAction(wxACTION_TEXT_INSERT, -1, unicode);
+
+            return;
+        }
+#endif
     }
 #ifdef __WXDEBUG__
     // Ctrl-R refreshes the control in debug mode
     }
 #ifdef __WXDEBUG__
     // Ctrl-R refreshes the control in debug mode
@@ -4676,6 +4761,14 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
     event.Skip();
 }
 
     event.Skip();
 }
 
+/* static */
+wxInputHandler *wxTextCtrl::GetStdInputHandler(wxInputHandler *handlerDef)
+{
+    static wxStdTextCtrlInputHandler s_handler(handlerDef);
+
+    return &s_handler;
+}
+
 // ----------------------------------------------------------------------------
 // wxStdTextCtrlInputHandler
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // wxStdTextCtrlInputHandler
 // ----------------------------------------------------------------------------
@@ -4705,13 +4798,13 @@ wxTextPos wxStdTextCtrlInputHandler::HitTest(const wxTextCtrl *text,
     return pos;
 }
 
     return pos;
 }
 
-bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control,
+bool wxStdTextCtrlInputHandler::HandleKey(wxInputConsumer *consumer,
                                           const wxKeyEvent& event,
                                           bool pressed)
 {
     // we're only interested in key presses
     if ( !pressed )
                                           const wxKeyEvent& event,
                                           bool pressed)
 {
     // we're only interested in key presses
     if ( !pressed )
-        return FALSE;
+        return false;
 
     int keycode = event.GetKeyCode();
 
 
     int keycode = event.GetKeyCode();
 
@@ -4765,14 +4858,12 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control,
             break;
 
         case WXK_PAGEDOWN:
             break;
 
         case WXK_PAGEDOWN:
-        case WXK_NEXT:
             // we don't map Ctrl-PgUp/Dn to anything special - what should it
             // to? for now, it's the same as without control
             action << wxACTION_TEXT_PAGE_DOWN;
             break;
 
         case WXK_PAGEUP:
             // we don't map Ctrl-PgUp/Dn to anything special - what should it
             // to? for now, it's the same as without control
             action << wxACTION_TEXT_PAGE_DOWN;
             break;
 
         case WXK_PAGEUP:
-        case WXK_PRIOR:
             action << wxACTION_TEXT_PAGE_UP;
             break;
 
             action << wxACTION_TEXT_PAGE_UP;
             break;
 
@@ -4822,22 +4913,22 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control,
 
     if ( (action != wxACTION_NONE) && (action != wxACTION_TEXT_PREFIX_SEL) )
     {
 
     if ( (action != wxACTION_NONE) && (action != wxACTION_TEXT_PREFIX_SEL) )
     {
-        control->PerformAction(action, -1, str);
+        consumer->PerformAction(action, -1, str);
 
 
-        return TRUE;
+        return true;
     }
 
     }
 
-    return wxStdInputHandler::HandleKey(control, event, pressed);
+    return wxStdInputHandler::HandleKey(consumer, event, pressed);
 }
 
 }
 
-bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control,
+bool wxStdTextCtrlInputHandler::HandleMouse(wxInputConsumer *consumer,
                                             const wxMouseEvent& event)
 {
     if ( event.LeftDown() )
     {
         wxASSERT_MSG( !m_winCapture, _T("left button going down twice?") );
 
                                             const wxMouseEvent& event)
 {
     if ( event.LeftDown() )
     {
         wxASSERT_MSG( !m_winCapture, _T("left button going down twice?") );
 
-        wxTextCtrl *text = wxStaticCast(control, wxTextCtrl);
+        wxTextCtrl *text = wxStaticCast(consumer->GetInputWindow(), wxTextCtrl);
 
         m_winCapture = text;
         m_winCapture->CaptureMouse();
 
         m_winCapture = text;
         m_winCapture->CaptureMouse();
@@ -4853,7 +4944,7 @@ bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control,
     else if ( event.LeftDClick() )
     {
         // select the word the cursor is on
     else if ( event.LeftDClick() )
     {
         // select the word the cursor is on
-        control->PerformAction(wxACTION_TEXT_SEL_WORD);
+        consumer->PerformAction(wxACTION_TEXT_SEL_WORD);
     }
     else if ( event.LeftUp() )
     {
     }
     else if ( event.LeftUp() )
     {
@@ -4866,10 +4957,10 @@ bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control,
         }
     }
 
         }
     }
 
-    return wxStdInputHandler::HandleMouse(control, event);
+    return wxStdInputHandler::HandleMouse(consumer, event);
 }
 
 }
 
-bool wxStdTextCtrlInputHandler::HandleMouseMove(wxControl *control,
+bool wxStdTextCtrlInputHandler::HandleMouseMove(wxInputConsumer *consumer,
                                                 const wxMouseEvent& event)
 {
     if ( m_winCapture )
                                                 const wxMouseEvent& event)
 {
     if ( m_winCapture )
@@ -4883,19 +4974,31 @@ bool wxStdTextCtrlInputHandler::HandleMouseMove(wxControl *control,
         }
     }
 
         }
     }
 
-    return wxStdInputHandler::HandleMouseMove(control, event);
+    return wxStdInputHandler::HandleMouseMove(consumer, event);
 }
 
 }
 
-bool wxStdTextCtrlInputHandler::HandleFocus(wxControl *control,
-                                            const wxFocusEvent& event)
+bool
+wxStdTextCtrlInputHandler::HandleFocus(wxInputConsumer *consumer,
+                                       const wxFocusEvent& event)
 {
 {
-    wxTextCtrl *text = wxStaticCast(control, wxTextCtrl);
+    wxTextCtrl *text = wxStaticCast(consumer->GetInputWindow(), wxTextCtrl);
 
     // the selection appearance changes depending on whether we have the focus
     text->RefreshSelection();
 
 
     // the selection appearance changes depending on whether we have the focus
     text->RefreshSelection();
 
+    if (event.GetEventType() == wxEVT_SET_FOCUS)
+    {
+        if (text->GetCaret() && !text->GetCaret()->IsVisible())
+            text->ShowCaret();
+    }
+    else
+    {
+        if (text->GetCaret() && text->GetCaret()->IsVisible())
+            text->HideCaret();
+    }
+
     // never refresh entirely
     // never refresh entirely
-    return FALSE;
+    return false;
 }
 
 #endif // wxUSE_TEXTCTRL
 }
 
 #endif // wxUSE_TEXTCTRL