+// ----------------------------------------------------------------------------
+// kbd input processing
+// ----------------------------------------------------------------------------
+
+bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* pMsg)
+{
+ MSG *msg = (MSG *)pMsg;
+
+ // check for our special keys here: if we don't do it and the parent frame
+ // uses them as accelerators, they wouldn't work at all, so we disable
+ // usual preprocessing for them
+ if ( msg->message == WM_KEYDOWN )
+ {
+ WORD vkey = (WORD) msg->wParam;
+ if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+ {
+ if ( vkey == VK_BACK )
+ return false;
+ }
+ else // no Alt
+ {
+ // we want to process some Ctrl-foo and Shift-bar but no key
+ // combinations without either Ctrl or Shift nor with both of them
+ // pressed
+ const int ctrl = wxIsCtrlDown(),
+ shift = wxIsShiftDown();
+ switch ( ctrl + shift )
+ {
+ default:
+ wxFAIL_MSG( _T("how many modifiers have we got?") );
+ // fall through
+
+ case 0:
+ case 2:
+ break;
+
+ case 1:
+ // either Ctrl or Shift pressed
+ if ( ctrl )
+ {
+ switch ( vkey )
+ {
+ case 'C':
+ case 'V':
+ case 'X':
+ case VK_INSERT:
+ case VK_DELETE:
+ case VK_HOME:
+ case VK_END:
+ return false;
+ }
+ }
+ else // Shift is pressed
+ {
+ if ( vkey == VK_INSERT || vkey == VK_DELETE )
+ return false;
+ }
+ }
+ }
+ }
+
+ return wxControl::MSWShouldPreProcessMessage(pMsg);
+}
+
+void wxTextCtrl::OnChar(wxKeyEvent& event)
+{
+ switch ( event.GetKeyCode() )
+ {
+ case WXK_RETURN:
+ if ( !HasFlag(wxTE_MULTILINE) )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
+ InitCommandEvent(event);
+ event.SetString(GetValue());
+ if ( GetEventHandler()->ProcessEvent(event) )
+ return;
+ }
+ //else: multiline controls need Enter for themselves
+
+ break;
+
+ case WXK_TAB:
+ // ok, so this is getting absolutely ridiculous but I don't see
+ // any other way to fix this bug: when a multiline text control is
+ // inside a wxFrame, we need to generate the navigation event as
+ // otherwise nothing happens at all, but when the same control is
+ // created inside a dialog, IsDialogMessage() *does* switch focus
+ // all by itself and so if we do it here as well, it is advanced
+ // twice and goes to the next control... to prevent this from
+ // happening we're doing this ugly check, the logic being that if
+ // we don't have focus then it had been already changed to the next
+ // control
+ //
+ // the right thing to do would, of course, be to understand what
+ // the hell is IsDialogMessage() doing but this is beyond my feeble
+ // forces at the moment unfortunately
+ if ( !(m_windowStyle & wxTE_PROCESS_TAB))
+ {
+ if ( FindFocus() == this )
+ {
+ int flags = 0;
+ if (!event.ShiftDown())
+ flags |= wxNavigationKeyEvent::IsForward ;
+ if (event.ControlDown())
+ flags |= wxNavigationKeyEvent::WinChange ;
+ if (Navigate(flags))
+ return;
+ }
+ }
+ else
+ {
+ // Insert tab since calling the default Windows handler
+ // doesn't seem to do it
+ WriteText(wxT("\t"));
+ }
+ break;
+ }
+
+ // no, we didn't process it
+ event.Skip();
+}
+
+WXLRESULT wxTextCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+ WXLRESULT lRc = wxTextCtrlBase::MSWWindowProc(nMsg, wParam, lParam);
+
+ if ( nMsg == WM_GETDLGCODE )
+ {
+ // we always want the chars and the arrows: the arrows for navigation
+ // and the chars because we want Ctrl-C to work even in a read only
+ // control
+ long lDlgCode = DLGC_WANTCHARS | DLGC_WANTARROWS;
+
+ if ( IsEditable() )
+ {
+ // we may have several different cases:
+ // 1. normal case: both TAB and ENTER are used for dlg navigation
+ // 2. ctrl which wants TAB for itself: ENTER is used to pass to the
+ // next control in the dialog
+ // 3. ctrl which wants ENTER for itself: TAB is used for dialog
+ // navigation
+ // 4. ctrl which wants both TAB and ENTER: Ctrl-ENTER is used to go
+ // to the next control
+
+ // the multiline edit control should always get <Return> for itself
+ if ( HasFlag(wxTE_PROCESS_ENTER) || HasFlag(wxTE_MULTILINE) )
+ lDlgCode |= DLGC_WANTMESSAGE;
+
+ if ( HasFlag(wxTE_PROCESS_TAB) )
+ lDlgCode |= DLGC_WANTTAB;
+
+ lRc |= lDlgCode;
+ }
+ else // !editable
+ {
+ // NB: use "=", not "|=" as the base class version returns the
+ // same flags is this state as usual (i.e. including
+ // DLGC_WANTMESSAGE). This is strange (how does it work in the
+ // native Win32 apps?) but for now live with it.
+ lRc = lDlgCode;
+ }
+ }
+
+ return lRc;
+}
+
+// ----------------------------------------------------------------------------
+// text control event processing
+// ----------------------------------------------------------------------------
+
+bool wxTextCtrl::SendUpdateEvent()