]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/textctrl.cpp
don't append anything back in DoDeleteOneItem() if the control becomes empty (fixes...
[wxWidgets.git] / src / msw / textctrl.cpp
index 02f25eabc3d32f97cbee1c88d90f76e7895e74b0..9293dcebb717c9b6a936dbb25073dbe6f6a88c41 100644 (file)
@@ -37,6 +37,7 @@
     #include "wx/menu.h"
     #include "wx/math.h"
     #include "wx/module.h"
+    #include "wx/wxcrtvararg.h"
 #endif
 
 #include "wx/sysopt.h"
 
 #include "wx/msw/missing.h"
 
+#if wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT
+
+// dummy value used for m_dropTarget, different from any valid pointer value
+// (which are all even under Windows) and NULL
+static wxDropTarget *
+    wxRICHTEXT_DEFAULT_DROPTARGET = wx_reinterpret_cast(wxDropTarget *, 1);
+
+#endif // wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT
+
 // ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
@@ -288,6 +298,14 @@ void wxTextCtrl::Init()
 
 wxTextCtrl::~wxTextCtrl()
 {
+#if wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT
+    if ( m_dropTarget == wxRICHTEXT_DEFAULT_DROPTARGET )
+    {
+        // don't try to destroy this dummy pointer in the base class dtor
+        m_dropTarget = NULL;
+    }
+#endif // wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT
+
     delete m_privateContextMenu;
 }
 
@@ -300,11 +318,6 @@ bool wxTextCtrl::Create(wxWindow *parent,
                         const wxValidator& validator,
                         const wxString& name)
 {
-#ifdef __WXWINCE__
-    if ((style & wxBORDER_MASK) == 0)
-        style |= wxBORDER_SIMPLE;
-#endif
-
     // base initialization
     if ( !CreateControl(parent, id, pos, size, style, validator, name) )
         return false;
@@ -312,9 +325,34 @@ bool wxTextCtrl::Create(wxWindow *parent,
     if ( !MSWCreateText(value, pos, size) )
         return false;
 
+#if wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT
+    if ( IsRich() )
+    {
+        // rich text controls have a default associated drop target which
+        // allows them to receive (rich) text dropped on them, which is nice,
+        // but prevents us from associating a user-defined drop target with
+        // them as we need to unregister the old one first
+        //
+        // to make it work, we set m_dropTarget to this special value initially
+        // and check for it in our SetDropTarget()
+        m_dropTarget = wxRICHTEXT_DEFAULT_DROPTARGET;
+    }
+#endif // wxUSE_DRAG_AND_DROP && wxUSE_RICHEDIT
+
     return true;
 }
 
+// returns true if the platform should explicitly apply a theme border
+bool wxTextCtrl::CanApplyThemeBorder() const
+{
+#ifdef __WXWINCE__
+    return false;
+#else
+    // Standard text control already handles theming
+    return ((GetWindowStyle() & (wxTE_RICH|wxTE_RICH2)) != 0);
+#endif
+}
+
 bool wxTextCtrl::MSWCreateText(const wxString& value,
                                const wxPoint& pos,
                                const wxSize& size)
@@ -445,7 +483,7 @@ bool wxTextCtrl::MSWCreateText(const wxString& value,
         valueWin = value;
     }
 
-    if ( !MSWCreateControl(windowClass, msStyle, pos, size, valueWin) )
+    if ( !MSWCreateControl(windowClass.wx_str(), msStyle, pos, size, valueWin) )
         return false;
 
 #if wxUSE_RICHEDIT
@@ -495,6 +533,14 @@ bool wxTextCtrl::MSWCreateText(const wxString& value,
     }
 #endif // wxUSE_RICHEDIT
 
+#ifndef __WXWINCE__
+    // Without this, if we pass the size in the constructor and then don't change it,
+    // the themed borders will be drawn incorrectly.
+    SetWindowPos(GetHwnd(), NULL, 0, 0, 0, 0,
+                SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
+                SWP_FRAMECHANGED);
+#endif
+
     return true;
 }
 
@@ -544,7 +590,7 @@ WXDWORD wxTextCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
 {
     long msStyle = wxControl::MSWGetStyle(style, exstyle);
 
-    // styles which we alaways add by default
+    // styles which we always add by default
     if ( style & wxTE_MULTILINE )
     {
         msStyle |= ES_MULTILINE | ES_WANTRETURN;
@@ -608,10 +654,12 @@ WXDWORD wxTextCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
 
 void wxTextCtrl::SetWindowStyleFlag(long style)
 {
-    // changing the alignment of the control dynamically only works under XP
-    // (but not older Windows version) and only for plain EDIT controls (not
-    // RICH ones) and we have to recreate the control to make it always work
-    if ( IsRich() || wxGetWinVersion() < wxWinVersion_XP )
+    // changing the alignment of the control dynamically works under Win2003
+    // (but not older Windows version: it seems to work under some versions of
+    // XP but not other ones, and we have no way to determine it so be
+    // conservative here) and only for plain EDIT controls (not RICH ones) and
+    // we have to recreate the control to make it always work
+    if ( IsRich() || wxGetWinVersion() < wxWinVersion_2003 )
     {
         const long alignMask = wxTE_LEFT | wxTE_CENTRE | wxTE_RIGHT;
         if ( (style & alignMask) != (GetWindowStyle() & alignMask) )
@@ -924,7 +972,7 @@ wxTextCtrl::StreamIn(const wxString& value,
 #else // !wxUSE_UNICODE_MSLU
     wxCSConv conv(encoding);
 
-    const size_t len = conv.MB2WC(NULL, value, value.length());
+    const size_t len = conv.MB2WC(NULL, value.mb_str(), value.length());
 
 #if wxUSE_WCHAR_T
     wxWCharBuffer wchBuf(len);
@@ -934,7 +982,7 @@ wxTextCtrl::StreamIn(const wxString& value,
     wchar_t *wpc = wchBuf;
 #endif
 
-    conv.MB2WC(wpc, value, value.length());
+    conv.MB2WC(wpc, value.mb_str(), value.length());
 #endif // wxUSE_UNICODE_MSLU
 
     // finally, stream it in the control
@@ -1113,7 +1161,7 @@ void wxTextCtrl::DoWriteText(const wxString& value, int flags)
 
         ::SendMessage(GetHwnd(), selectionOnly ? EM_REPLACESEL : WM_SETTEXT,
                       // EM_REPLACESEL takes 1 to indicate the operation should be redoable
-                      selectionOnly ? 1 : 0, (LPARAM)valueDos.c_str());
+                      selectionOnly ? 1 : 0, (LPARAM)valueDos.wx_str());
 
         if ( !ucf.GotUpdate() && (flags & SetValue_SendEvent) )
         {
@@ -1124,9 +1172,7 @@ void wxTextCtrl::DoWriteText(const wxString& value, int flags)
 
 void wxTextCtrl::AppendText(const wxString& text)
 {
-    SetInsertionPointEnd();
-
-    WriteText(text);
+    wxTextEntry::AppendText(text);
 
 #if wxUSE_RICHEDIT
     // don't do this if we're frozen, saves some time
@@ -1143,18 +1189,12 @@ void wxTextCtrl::Clear()
 {
     ::SetWindowText(GetHwnd(), wxEmptyString);
 
-#if wxUSE_RICHEDIT
-    if ( !IsRich() )
-#endif // wxUSE_RICHEDIT
+    if ( IsMultiLine() && !IsRich() )
     {
         // rich edit controls send EN_UPDATE from WM_SETTEXT handler themselves
         // but the normal ones don't -- make Clear() behaviour consistent by
         // always sending this event
-
-        // Windows already sends an update event for single-line
-        // controls.
-        if ( m_windowStyle & wxTE_MULTILINE )
-            SendUpdateEvent();
+        SendUpdateEvent();
     }
 }
 
@@ -1177,91 +1217,10 @@ bool wxTextCtrl::EmulateKeyPress(const wxKeyEvent& event)
 
 #endif // __WIN32__
 
-// ----------------------------------------------------------------------------
-// Clipboard operations
-// ----------------------------------------------------------------------------
-
-void wxTextCtrl::Copy()
-{
-    if (CanCopy())
-    {
-        ::SendMessage(GetHwnd(), WM_COPY, 0, 0L);
-    }
-}
-
-void wxTextCtrl::Cut()
-{
-    if (CanCut())
-    {
-        ::SendMessage(GetHwnd(), WM_CUT, 0, 0L);
-    }
-}
-
-void wxTextCtrl::Paste()
-{
-    if (CanPaste())
-    {
-        ::SendMessage(GetHwnd(), WM_PASTE, 0, 0L);
-    }
-}
-
-bool wxTextCtrl::HasSelection() const
-{
-    long from, to;
-    GetSelection(&from, &to);
-    return from != to;
-}
-
-bool wxTextCtrl::CanCopy() const
-{
-    // Can copy if there's a selection
-    return HasSelection();
-}
-
-bool wxTextCtrl::CanCut() const
-{
-    return CanCopy() && IsEditable();
-}
-
-bool wxTextCtrl::CanPaste() const
-{
-    if ( !IsEditable() )
-        return false;
-
-#if wxUSE_RICHEDIT
-    if ( IsRich() )
-    {
-        UINT cf = 0; // 0 == any format
-
-        return ::SendMessage(GetHwnd(), EM_CANPASTE, cf, 0) != 0;
-    }
-#endif // wxUSE_RICHEDIT
-
-    // Standard edit control: check for straight text on clipboard
-    if ( !::OpenClipboard(GetHwndOf(wxTheApp->GetTopWindow())) )
-        return false;
-
-    bool isTextAvailable = ::IsClipboardFormatAvailable(CF_TEXT) != 0;
-    ::CloseClipboard();
-
-    return isTextAvailable;
-}
-
 // ----------------------------------------------------------------------------
 // Accessors
 // ----------------------------------------------------------------------------
 
-void wxTextCtrl::SetEditable(bool editable)
-{
-    HWND hWnd = GetHwnd();
-    ::SendMessage(hWnd, EM_SETREADONLY, (WPARAM)!editable, (LPARAM)0L);
-}
-
-void wxTextCtrl::SetInsertionPoint(long pos)
-{
-    DoSetSelection(pos, pos);
-}
-
 void wxTextCtrl::SetInsertionPointEnd()
 {
     // we must not do anything if the caret is already there because calling
@@ -1275,21 +1234,7 @@ void wxTextCtrl::SetInsertionPointEnd()
         return;
     }
 
-    long pos;
-
-#if wxUSE_RICHEDIT
-    if ( m_verRichEdit == 1 )
-    {
-        // we don't have to waste time calling GetLastPosition() in this case
-        pos = -1;
-    }
-    else // !RichEdit 1.0
-#endif // wxUSE_RICHEDIT
-    {
-        pos = lastPosition;
-    }
-
-    SetInsertionPoint(pos);
+    SetInsertionPoint(lastPosition);
 }
 
 long wxTextCtrl::GetInsertionPoint() const
@@ -1305,23 +1250,27 @@ long wxTextCtrl::GetInsertionPoint() const
     }
 #endif // wxUSE_RICHEDIT
 
-    DWORD Pos = (DWORD)::SendMessage(GetHwnd(), EM_GETSEL, 0, 0L);
-    return Pos & 0xFFFF;
+    return wxTextEntry::GetInsertionPoint();
 }
 
 wxTextPos wxTextCtrl::GetLastPosition() const
 {
-    int numLines = GetNumberOfLines();
-    long posStartLastLine = XYToPosition(0, numLines - 1);
+    if ( IsMultiLine() )
+    {
+        int numLines = GetNumberOfLines();
+        long posStartLastLine = XYToPosition(0, numLines - 1);
+
+        long lenLastLine = GetLengthOfLineContainingPos(posStartLastLine);
 
-    long lenLastLine = GetLengthOfLineContainingPos(posStartLastLine);
+        return posStartLastLine + lenLastLine;
+    }
 
-    return posStartLastLine + lenLastLine;
+    return wxTextEntry::GetLastPosition();
 }
 
 // If the return values from and to are the same, there is no
 // selection.
-void wxTextCtrl::GetSelection(long* from, long* to) const
+void wxTextCtrl::GetSelection(long *from, long *to) const
 {
 #if wxUSE_RICHEDIT
     if ( IsRich() )
@@ -1335,45 +1284,15 @@ void wxTextCtrl::GetSelection(long* from, long* to) const
     else
 #endif // !wxUSE_RICHEDIT
     {
-        DWORD dwStart, dwEnd;
-        ::SendMessage(GetHwnd(), EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
-
-        *from = dwStart;
-        *to = dwEnd;
+        wxTextEntry::GetSelection(from, to);
     }
 }
 
-bool wxTextCtrl::IsEditable() const
-{
-    // strangely enough, we may be called before the control is created: our
-    // own Create() calls MSWGetStyle() which calls AcceptsFocus() which calls
-    // us
-    if ( !m_hWnd )
-        return true;
-
-    long style = ::GetWindowLong(GetHwnd(), GWL_STYLE);
-
-    return (style & ES_READONLY) == 0;
-}
-
 // ----------------------------------------------------------------------------
 // selection
 // ----------------------------------------------------------------------------
 
-void wxTextCtrl::SetSelection(long from, long to)
-{
-    // if from and to are both -1, it means (in wxWidgets) that all text should
-    // be selected - translate into Windows convention
-    if ( (from == -1) && (to == -1) )
-    {
-        from = 0;
-        to = -1;
-    }
-
-    DoSetSelection(from, to);
-}
-
-void wxTextCtrl::DoSetSelection(long from, long to, bool scrollCaret)
+void wxTextCtrl::DoSetSelection(long from, long to, int flags)
 {
     HWND hWnd = GetHwnd();
 
@@ -1383,15 +1302,15 @@ void wxTextCtrl::DoSetSelection(long from, long to, bool scrollCaret)
         CHARRANGE range;
         range.cpMin = from;
         range.cpMax = to;
-        ::SendMessage(hWnd, EM_EXSETSEL, 0, (LPARAM) &range);
+        ::SendMessage(hWnd, EM_EXSETSEL, 0, (LPARAM)&range);
     }
     else
 #endif // wxUSE_RICHEDIT
     {
-        ::SendMessage(hWnd, EM_SETSEL, (WPARAM)from, (LPARAM)to);
+        wxTextEntry::DoSetSelection(from, to, flags);
     }
 
-    if ( scrollCaret && !IsFrozen() )
+    if ( (flags & SetSel_Scroll) && !IsFrozen() )
     {
 #if wxUSE_RICHEDIT
         // richedit 3.0 (i.e. the version living in riched20.dll distributed
@@ -1425,7 +1344,7 @@ void wxTextCtrl::DoSetSelection(long from, long to, bool scrollCaret)
         }
 #endif // wxUSE_RICHEDIT
 
-        ::SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
+        ::SendMessage(hWnd, EM_SCROLLCARET, 0, (LPARAM)0);
 
 #if wxUSE_RICHEDIT
         // restore ECO_NOHIDESEL if we changed it
@@ -1458,22 +1377,9 @@ bool wxTextCtrl::DoLoadFile(const wxString& file, int fileType)
 }
 
 // ----------------------------------------------------------------------------
-// Editing
+// dirty status
 // ----------------------------------------------------------------------------
 
-void wxTextCtrl::Replace(long from, long to, const wxString& value)
-{
-    // Set selection and remove it
-    DoSetSelection(from, to, false /* don't scroll caret into view */);
-
-    DoWriteText(value);
-}
-
-void wxTextCtrl::Remove(long from, long to)
-{
-    Replace(from, to, wxEmptyString);
-}
-
 bool wxTextCtrl::IsModified() const
 {
     return ::SendMessage(GetHwnd(), EM_GETMODIFY, 0, 0) != 0;
@@ -1481,27 +1387,27 @@ bool wxTextCtrl::IsModified() const
 
 void wxTextCtrl::MarkDirty()
 {
-    ::SendMessage(GetHwnd(), EM_SETMODIFY, TRUE, 0L);
+    ::SendMessage(GetHwnd(), EM_SETMODIFY, TRUE, 0);
 }
 
 void wxTextCtrl::DiscardEdits()
 {
-    ::SendMessage(GetHwnd(), EM_SETMODIFY, FALSE, 0L);
-}
-
-int wxTextCtrl::GetNumberOfLines() const
-{
-    return (int)::SendMessage(GetHwnd(), EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0);
+    ::SendMessage(GetHwnd(), EM_SETMODIFY, FALSE, 0);
 }
 
 // ----------------------------------------------------------------------------
 // Positions <-> coords
 // ----------------------------------------------------------------------------
 
+int wxTextCtrl::GetNumberOfLines() const
+{
+    return (int)::SendMessage(GetHwnd(), EM_GETLINECOUNT, 0, 0);
+}
+
 long wxTextCtrl::XYToPosition(long x, long y) const
 {
     // This gets the char index for the _beginning_ of this line
-    long charIndex = ::SendMessage(GetHwnd(), EM_LINEINDEX, (WPARAM)y, (LPARAM)0);
+    long charIndex = ::SendMessage(GetHwnd(), EM_LINEINDEX, y, 0);
 
     return charIndex + x;
 }
@@ -1515,12 +1421,12 @@ bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
 #if wxUSE_RICHEDIT
     if ( IsRich() )
     {
-        lineNo = ::SendMessage(hWnd, EM_EXLINEFROMCHAR, 0, (LPARAM)pos);
+        lineNo = ::SendMessage(hWnd, EM_EXLINEFROMCHAR, 0, pos);
     }
     else
 #endif // wxUSE_RICHEDIT
     {
-        lineNo = ::SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, 0);
+        lineNo = ::SendMessage(hWnd, EM_LINEFROMCHAR, pos, 0);
     }
 
     if ( lineNo == -1 )
@@ -1530,7 +1436,7 @@ bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
     }
 
     // This gets the char index for the _beginning_ of this line
-    long charIndex = ::SendMessage(hWnd, EM_LINEINDEX, (WPARAM)lineNo, (LPARAM)0);
+    long charIndex = ::SendMessage(hWnd, EM_LINEINDEX, lineNo, 0);
     if ( charIndex == -1 )
     {
         return false;
@@ -1648,21 +1554,21 @@ void wxTextCtrl::ShowPosition(long pos)
 
     // Is this where scrolling is relative to - the line containing the caret?
     // Or is the first visible line??? Try first visible line.
-//    int currentLineLineNo1 = (int)::SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)-1, (LPARAM)0L);
+//    int currentLineLineNo1 = (int)::SendMessage(hWnd, EM_LINEFROMCHAR, -1, 0L);
 
-    int currentLineLineNo = (int)::SendMessage(hWnd, EM_GETFIRSTVISIBLELINE, (WPARAM)0, (LPARAM)0L);
+    int currentLineLineNo = (int)::SendMessage(hWnd, EM_GETFIRSTVISIBLELINE, 0, 0);
 
-    int specifiedLineLineNo = (int)::SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)pos, (LPARAM)0L);
+    int specifiedLineLineNo = (int)::SendMessage(hWnd, EM_LINEFROMCHAR, pos, 0);
 
     int linesToScroll = specifiedLineLineNo - currentLineLineNo;
 
     if (linesToScroll != 0)
-      (void)::SendMessage(hWnd, EM_LINESCROLL, (WPARAM)0, (LPARAM)linesToScroll);
+      ::SendMessage(hWnd, EM_LINESCROLL, 0, linesToScroll);
 }
 
 long wxTextCtrl::GetLengthOfLineContainingPos(long pos) const
 {
-    return ::SendMessage(GetHwnd(), EM_LINELENGTH, (WPARAM)pos, 0);
+    return ::SendMessage(GetHwnd(), EM_LINELENGTH, pos, 0);
 }
 
 int wxTextCtrl::GetLineLength(long lineNo) const
@@ -1695,9 +1601,16 @@ wxString wxTextCtrl::GetLineText(long lineNo) const
             // should never see it
             if ( buf[len - 2] == _T('\r') && buf[len - 1] == _T('\n') )
             {
+                // richedit 1.0 uses "\r\n" as line terminator, so remove "\r"
+                // here and "\n" below
                 buf[len - 2] = _T('\n');
                 len--;
             }
+            else if ( buf[len - 1] == _T('\r') )
+            {
+                // richedit 2.0+ uses only "\r", replace it with "\n"
+                buf[len - 1] = _T('\n');
+            }
         }
 #endif // wxUSE_RICHEDIT
 
@@ -1725,14 +1638,7 @@ void wxTextCtrl::SetMaxLength(unsigned long len)
     else
 #endif // wxUSE_RICHEDIT
     {
-        if ( len >= 0xffff )
-        {
-            // this will set it to a platform-dependent maximum (much more
-            // than 64Kb under NT)
-            len = 0;
-        }
-
-        ::SendMessage(GetHwnd(), EM_LIMITTEXT, len, 0);
+        wxTextEntry::SetMaxLength(len);
     }
 }
 
@@ -1740,41 +1646,27 @@ void wxTextCtrl::SetMaxLength(unsigned long len)
 // Undo/redo
 // ----------------------------------------------------------------------------
 
-void wxTextCtrl::Undo()
-{
-    if (CanUndo())
-    {
-        ::SendMessage(GetHwnd(), EM_UNDO, 0, 0);
-    }
-}
-
 void wxTextCtrl::Redo()
 {
-    if (CanRedo())
-    {
 #if wxUSE_RICHEDIT
-        if (GetRichVersion() > 1)
-            ::SendMessage(GetHwnd(), EM_REDO, 0, 0);
-        else
-#endif
-        // Same as Undo, since Undo undoes the undo, i.e. a redo.
-        ::SendMessage(GetHwnd(), EM_UNDO, 0, 0);
+    if ( GetRichVersion() > 1 )
+    {
+        ::SendMessage(GetHwnd(), EM_REDO, 0, 0);
+        return;
     }
-}
+#endif // wxUSE_RICHEDIT
 
-bool wxTextCtrl::CanUndo() const
-{
-    return ::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0;
+    wxTextEntry::Redo();
 }
 
 bool wxTextCtrl::CanRedo() const
 {
 #if wxUSE_RICHEDIT
-    if (GetRichVersion() > 1)
+    if ( GetRichVersion() > 1 )
         return ::SendMessage(GetHwnd(), EM_CANREDO, 0, 0) != 0;
-    else
-#endif
-    return ::SendMessage(GetHwnd(), EM_CANUNDO, 0, 0) != 0;
+#endif // wxUSE_RICHEDIT
+
+    return wxTextEntry::CanRedo();
 }
 
 // ----------------------------------------------------------------------------
@@ -1788,7 +1680,7 @@ bool wxTextCtrl::ShowNativeCaret(bool show)
         if ( !(show ? ::ShowCaret(GetHwnd()) : ::HideCaret(GetHwnd())) )
         {
             // not an error, may simply indicate that it's not shown/hidden
-            // yet (i.e. it had been hidden/showh 2 times before)
+            // yet (i.e. it had been hidden/shown 2 times before)
             return false;
         }
 
@@ -1799,7 +1691,7 @@ bool wxTextCtrl::ShowNativeCaret(bool show)
 }
 
 // ----------------------------------------------------------------------------
-// implemenation details
+// implementation details
 // ----------------------------------------------------------------------------
 
 void wxTextCtrl::Command(wxCommandEvent & event)
@@ -1892,7 +1784,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
@@ -2029,27 +1921,13 @@ bool wxTextCtrl::SendUpdateEvent()
             return false;
     }
 
-    wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
-    InitCommandEvent(event);
-
-    return ProcessCommand(event);
+    return SendTextUpdatedEvent();
 }
 
 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;
@@ -2065,7 +1943,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;
     }
@@ -2118,7 +1998,7 @@ bool wxTextCtrl::AdjustSpaceLimit()
     return true;
 }
 
-bool wxTextCtrl::AcceptsFocus() const
+bool wxTextCtrl::AcceptsFocusFromKeyboard() 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
@@ -2252,13 +2132,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();
 }
 
 // ----------------------------------------------------------------------------
@@ -2381,6 +2263,22 @@ bool wxTextCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
     return wxTextCtrlBase::MSWOnNotify(idCtrl, lParam, result);
 }
 
+#if wxUSE_DRAG_AND_DROP
+
+void wxTextCtrl::SetDropTarget(wxDropTarget *dropTarget)
+{
+    if ( m_dropTarget == wxRICHTEXT_DEFAULT_DROPTARGET )
+    {
+        // get rid of the built-in drop target
+        ::RevokeDragDrop(GetHwnd());
+        m_dropTarget = NULL;
+    }
+
+    wxTextCtrlBase::SetDropTarget(dropTarget);
+}
+
+#endif // wxUSE_DRAG_AND_DROP
+
 // ----------------------------------------------------------------------------
 // colour setting for the rich edit controls
 // ----------------------------------------------------------------------------
@@ -2429,8 +2327,6 @@ bool wxTextCtrl::SetForegroundColour(const wxColour& colour)
 // styling support for rich edit controls
 // ----------------------------------------------------------------------------
 
-#if wxUSE_RICHEDIT
-
 bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
 {
     if ( !IsRich() )
@@ -2468,7 +2364,7 @@ bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
 
     if ( changeSel )
     {
-        DoSetSelection(start, end, false /* don't scroll caret into view */);
+        DoSetSelection(start, end, SetSel_NoScroll);
     }
 
     // initialize CHARFORMAT struct
@@ -2507,9 +2403,12 @@ bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
         // the real height in twips and not the negative number which
         // wxFillLogFont() returns (this is correct in general and works with
         // the Windows font mapper, but not here)
+
+        wxFont font(style.GetFont());
+
         LOGFONT lf;
-        wxFillLogFont(&lf, &style.GetFont());
-        cf.yHeight = 20*style.GetFont().GetPointSize(); // 1 pt = 20 twips
+        wxFillLogFont(&lf, &font);
+        cf.yHeight = 20*font.GetPointSize(); // 1 pt = 20 twips
         cf.bCharSet = lf.lfCharSet;
         cf.bPitchAndFamily = lf.lfPitchAndFamily;
         wxStrncpy( cf.szFaceName, lf.lfFaceName, WXSIZEOF(cf.szFaceName) );
@@ -2646,7 +2545,7 @@ bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
     if ( changeSel )
     {
         // restore the original selection
-        DoSetSelection(startOld, endOld, false);
+        DoSetSelection(startOld, endOld, SetSel_NoScroll);
     }
 
     return ok;
@@ -2709,7 +2608,7 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
 
     if ( changeSel )
     {
-        DoSetSelection(position, position+1, false /* don't scroll caret into view */);
+        DoSetSelection(position, position + 1, SetSel_NoScroll);
     }
 
     // get the selection formatting
@@ -2809,14 +2708,12 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
     if ( changeSel )
     {
         // restore the original selection
-        DoSetSelection(startOld, endOld, false);
+        DoSetSelection(startOld, endOld, SetSel_NoScroll);
     }
 
     return true;
 }
 
-#endif
-
 // ----------------------------------------------------------------------------
 // wxRichEditModule
 // ----------------------------------------------------------------------------
@@ -2896,7 +2793,7 @@ bool wxRichEditModule::LoadInkEdit()
     wxLogNull logNull;
     return ms_inkEditLib.Load(wxT("inked"));
 }
-#endif
+#endif // wxUSE_INKEDIT
 
 
 #endif // wxUSE_RICHEDIT