+long wxTextCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+    long lRc = wxTextCtrlBase::MSWWindowProc(nMsg, wParam, lParam);
+
+    if ( nMsg == WM_GETDLGCODE )
+    {
+        if ( IsEditable() )
+        {
+            // we always want the chars and the arrows
+            long lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS;
+
+            // we may have several different cases:
+            // 1. normal case: both TAB and ENTER are used for dlg navigation
+            // 2. ctrl which wants TAB for itself: ENTER is used to pass to the
+            //    next control in the dialog
+            // 3. ctrl which wants ENTER for itself: TAB is used for dialog
+            //    navigation
+            // 4. ctrl which wants both TAB and ENTER: Ctrl-ENTER is used to go
+            //    to the next control
+
+            // the multiline edit control should always get <Return> for itself
+            if ( HasFlag(wxTE_PROCESS_ENTER) || HasFlag(wxTE_MULTILINE) )
+                lDlgCode |= DLGC_WANTMESSAGE;
+
+            if ( HasFlag(wxTE_PROCESS_TAB) )
+                lDlgCode |= DLGC_WANTTAB;
+
+            lRc |= lDlgCode;
+        }
+        else // !editable
+        {
+            // when the control can't be edited by user, it doesn't need any
+            // extra keys at all
+            lRc = 0;
+        }
+    }
+
+    return lRc;
+}
+
+// ----------------------------------------------------------------------------
+// text control event processing
+// ----------------------------------------------------------------------------
+
+bool wxTextCtrl::SendUpdateEvent()
+{
+    // is event reporting suspended?
+    if ( m_suppressNextUpdate )
+    {
+        // do process the next one
+        m_suppressNextUpdate = FALSE;
+
+        return FALSE;
+    }
+
+    wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
+    InitCommandEvent(event);
+    event.SetString(GetValue());
+
+    return ProcessCommand(event);
+}
+