+ 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;
+
+ case EN_MAXTEXT:
+ // the text size limit has been hit -- try to increase it
+ if ( !AdjustSpaceLimit() )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_MAXLEN, m_windowId);
+ InitCommandEvent(event);
+ event.SetString(GetValue());
+ ProcessCommand(event);
+ }
+ break;
+
+ // the other edit notification messages are not processed
+ default:
+ return false;
+ }
+
+ // processed
+ return true;
+}
+
+WXHBRUSH wxTextCtrl::MSWControlColor(WXHDC hDC, WXHWND hWnd)
+{
+ if ( !IsEnabled() && !HasFlag(wxTE_MULTILINE) )
+ return MSWControlColorDisabled(hDC);
+
+ return wxTextCtrlBase::MSWControlColor(hDC, hWnd);
+}
+
+bool wxTextCtrl::HasSpaceLimit(unsigned int *len) const
+{
+ // HACK: we try to automatically extend the limit for the amount of text
+ // to allow (interactively) entering more than 64Kb of text under
+ // Win9x but we shouldn't reset the text limit which was previously
+ // set explicitly with SetMaxLength()
+ //
+ // Unfortunately there is no EM_GETLIMITTEXTSETBYUSER and so we don't
+ // know the limit we set (if any). We could solve this by storing the
+ // limit we set in wxTextCtrl but to save space we prefer to simply
+ // test here the actual limit value: we consider that SetMaxLength()
+ // can only be called for small values while EN_MAXTEXT is only sent
+ // for large values (in practice the default limit seems to be 30000
+ // but make it smaller just to be on the safe side)
+ *len = ::SendMessage(GetHwnd(), EM_GETLIMITTEXT, 0, 0);
+ return *len < 10001;
+
+}
+
+bool wxTextCtrl::AdjustSpaceLimit()
+{
+ unsigned int limit;
+ if ( HasSpaceLimit(&limit) )
+ return false;
+
+ unsigned int len = ::GetWindowTextLength(GetHwnd());
+ if ( len >= limit )
+ {
+ // increment in 32Kb chunks
+ SetMaxLength(len + 0x8000);
+ }
+
+ // we changed the limit
+ return true;
+}
+
+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
+ // to be able to scroll it without mouse
+ return (IsEditable() || IsMultiLine()) && wxControl::AcceptsFocus();
+}
+
+wxSize wxTextCtrl::DoGetBestSize() const
+{
+ int cx, cy;
+ wxGetCharSize(GetHWND(), &cx, &cy, GetFont());
+
+ int wText = DEFAULT_ITEM_WIDTH;
+
+ int hText = cy;
+ if ( m_windowStyle & wxTE_MULTILINE )
+ {
+ hText *= wxMax(wxMin(GetNumberOfLines(), 10), 2);
+ }
+ //else: for single line control everything is ok
+
+ // we have to add the adjustments for the control height only once, not
+ // once per line, so do it after multiplication above
+ hText += EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) - cy;
+
+ return wxSize(wText, hText);
+}
+
+// ----------------------------------------------------------------------------
+// standard handlers for standard edit menu events
+// ----------------------------------------------------------------------------
+
+void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event))
+{
+ Cut();
+}
+
+void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event))
+{
+ Copy();
+}
+
+void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event))
+{
+ Paste();
+}
+
+void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event))
+{
+ Undo();
+}
+
+void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event))
+{
+ Redo();
+}
+
+void wxTextCtrl::OnDelete(wxCommandEvent& WXUNUSED(event))
+{
+ long from, to;
+ GetSelection(& from, & to);
+ if (from != -1 && to != -1)
+ Remove(from, to);
+}
+
+void wxTextCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event))
+{
+ SetSelection(-1, -1);
+}
+
+void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
+{
+ event.Enable( CanCut() );
+}
+
+void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
+{
+ event.Enable( CanCopy() );
+}
+
+void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
+{
+ event.Enable( CanPaste() );
+}
+
+void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
+{
+ event.Enable( CanUndo() );
+}
+
+void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
+{
+ event.Enable( CanRedo() );
+}
+
+void wxTextCtrl::OnUpdateDelete(wxUpdateUIEvent& event)
+{
+ long from, to;
+ GetSelection(& from, & to);
+ event.Enable(from != -1 && to != -1 && from != to && IsEditable()) ;
+}
+
+void wxTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event)
+{
+ event.Enable(GetLastPosition() > 0);
+}
+
+void wxTextCtrl::OnContextMenu(wxContextMenuEvent& event)
+{
+#if wxUSE_RICHEDIT
+ if (IsRich())
+ {
+ if (!m_privateContextMenu)
+ {
+ m_privateContextMenu = new wxMenu;
+ m_privateContextMenu->Append(wxID_UNDO, _("&Undo"));
+ m_privateContextMenu->Append(wxID_REDO, _("&Redo"));
+ m_privateContextMenu->AppendSeparator();
+ m_privateContextMenu->Append(wxID_CUT, _("Cu&t"));
+ m_privateContextMenu->Append(wxID_COPY, _("&Copy"));
+ m_privateContextMenu->Append(wxID_PASTE, _("&Paste"));
+ m_privateContextMenu->Append(wxID_CLEAR, _("&Delete"));
+ m_privateContextMenu->AppendSeparator();
+ m_privateContextMenu->Append(wxID_SELECTALL, _("Select &All"));
+ }
+ PopupMenu(m_privateContextMenu);
+ return;
+ }
+ else
+#endif
+ event.Skip();
+}
+
+void wxTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event))
+{
+ // be sure the caret remains invisible if the user had hidden it
+ if ( !m_isNativeCaretShown )
+ {
+ ::HideCaret(GetHwnd());
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Default colors for MSW text control
+//
+// Set default background color to the native white instead of
+// the default wxSYS_COLOUR_BTNFACE (is triggered with wxNullColour).
+// ----------------------------------------------------------------------------
+
+wxVisualAttributes wxTextCtrl::GetDefaultAttributes() const
+{
+ wxVisualAttributes attrs;
+ attrs.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ attrs.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+ attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); //white
+
+ return attrs;
+}
+
+// the rest of the file only deals with the rich edit controls