X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e2bcbdfbc798cccc134c192a4a0185035cd9303c..454180593ffe561accbf9908b6dd335b2c30f898:/src/msw/textctrl.cpp?ds=sidebyside diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index ef70b6f9e3..3172c51558 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -84,20 +84,28 @@ class wxRichEditModule : public wxModule { public: + enum Version + { + Version_1, // riched32.dll + Version_2or3, // both use riched20.dll + Version_41, // msftedit.dll (XP SP1 and Windows 2003) + Version_Max + }; + virtual bool OnInit(); virtual void OnExit(); - // load the richedit DLL of at least of required version - static bool Load(int version = 1); + // load the richedit DLL for the specified version of rich edit + static bool Load(Version version); private: // the handles to richedit 1.0 and 2.0 (or 3.0) DLLs - static HINSTANCE ms_hRichEdit[2]; + static HINSTANCE ms_hRichEdit[Version_Max]; DECLARE_DYNAMIC_CLASS(wxRichEditModule) }; -HINSTANCE wxRichEditModule::ms_hRichEdit[2] = { NULL, NULL }; +HINSTANCE wxRichEditModule::ms_hRichEdit[Version_Max] = { NULL, NULL, NULL }; IMPLEMENT_DYNAMIC_CLASS(wxRichEditModule, wxModule) @@ -212,7 +220,7 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) EVT_DROP_FILES(wxTextCtrl::OnDropFiles) #if wxUSE_RICHEDIT - EVT_RIGHT_UP(wxTextCtrl::OnRightClick) + EVT_CONTEXT_MENU(wxTextCtrl::OnContextMenu) #endif EVT_MENU(wxID_CUT, wxTextCtrl::OnCut) @@ -251,7 +259,6 @@ void wxTextCtrl::Init() m_privateContextMenu = NULL; m_updatesCount = -1; m_isNativeCaretShown = true; - m_isCaretAtEnd = true; } wxTextCtrl::~wxTextCtrl() @@ -282,6 +289,12 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, // do create the control - either an EDIT or RICHEDIT wxString windowClass = wxT("EDIT"); +#if defined(__POCKETPC__) || defined(__SMARTPHONE__) + // A control that capitalizes the first letter + if (style & wxTE_CAPITALIZE) + windowClass = wxT("CAPEDIT"); +#endif + #if wxUSE_RICHEDIT if ( m_windowStyle & wxTE_AUTO_URL ) { @@ -298,63 +311,58 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, // we need to load the richedit DLL before creating the rich edit control if ( m_windowStyle & wxTE_RICH ) { - static bool s_errorGiven = false;// MT-FIXME - - // Which version do we need? Use 1.0 by default because it is much more - // like the the standard EDIT or 2.0 if explicitly requested, but use - // only 2.0 in Unicode mode as 1.0 doesn't support Unicode at all + // versions 2.0, 3.0 and 4.1 of rich edit are mostly compatible with + // each other but not with version 1.0, so we have separate flags for + // the version 1.0 and the others (and so m_verRichEdit may be 0 (plain + // EDIT control), 1 for version 1.0 or 2 for any higher version) // - // TODO: RichEdit 3.0 is apparently capable of emulating RichEdit 1.0 - // (and thus EDIT) much better than RichEdit 2.0 so we probably - // should use 3.0 if available as it is the best of both worlds - - // but as I can't test it right now I don't do it (VZ) + // notice that 1.0 has no Unicode support at all so in Unicode build we + // must use another version + #if wxUSE_UNICODE - const int verRichEdit = 2; + m_verRichEdit = 2; #else // !wxUSE_UNICODE - int verRichEdit = m_windowStyle & wxTE_RICH2 ? 2 : 1; + m_verRichEdit = m_windowStyle & wxTE_RICH2 ? 2 : 1; #endif // wxUSE_UNICODE/!wxUSE_UNICODE - // only give the error msg once if the DLL can't be loaded - if ( !s_errorGiven ) + if ( m_verRichEdit == 2 ) { - // try to load the RichEdit DLL (will do nothing if already done) - if ( !wxRichEditModule::Load(verRichEdit) ) + if ( wxRichEditModule::Load(wxRichEditModule::Version_41) ) { -#if !wxUSE_UNICODE - // try another version? - verRichEdit = 3 - verRichEdit; // 1 <-> 2 - - if ( !wxRichEditModule::Load(verRichEdit) ) -#endif // wxUSE_UNICODE - { - wxLogError(_("Impossible to create a rich edit control, using simple text control instead. Please reinstall riched32.dll")); - - s_errorGiven = true; - } + // yes, class name for version 4.1 really is 5.0 + windowClass = _T("RICHEDIT50W"); + } + else if ( wxRichEditModule::Load(wxRichEditModule::Version_2or3) ) + { + windowClass = _T("RichEdit20") +#if wxUSE_UNICODE + _T("W"); +#else // ANSI + _T("A"); +#endif // Unicode/ANSI + } + else // failed to load msftedit.dll and riched20.dll + { + m_verRichEdit = 1; } } - // have we managed to load any richedit version? - if ( !s_errorGiven ) + if ( m_verRichEdit == 1 ) { - m_verRichEdit = verRichEdit; - if ( m_verRichEdit == 1 ) + if ( wxRichEditModule::Load(wxRichEditModule::Version_1) ) { - windowClass = wxT("RICHEDIT"); + windowClass = _T("RICHEDIT"); } - else + else // failed to load any richedit control DLL { -#ifndef RICHEDIT_CLASS - wxString RICHEDIT_CLASS; - RICHEDIT_CLASS.Printf(_T("RichEdit%d0"), m_verRichEdit); -#if wxUSE_UNICODE - RICHEDIT_CLASS += _T('W'); -#else // ANSI - RICHEDIT_CLASS += _T('A'); -#endif // Unicode/ANSI -#endif // !RICHEDIT_CLASS + // only give the error msg once if the DLL can't be loaded + static bool s_errorGiven = false; // MT ok as only used by GUI - windowClass = RICHEDIT_CLASS; + wxLogError(_("Impossible to create a rich edit control, using simple text control instead. Please reinstall riched32.dll")); + + s_errorGiven = true; + + m_verRichEdit = 0; } } } @@ -1090,8 +1098,6 @@ void wxTextCtrl::SetEditable(bool editable) void wxTextCtrl::SetInsertionPoint(long pos) { DoSetSelection(pos, pos); - - m_isCaretAtEnd = pos == GetLastPosition(); } void wxTextCtrl::SetInsertionPointEnd() @@ -1101,9 +1107,8 @@ void wxTextCtrl::SetInsertionPointEnd() // if it doesn't actually move the caret anywhere and so the simple fact of // doing it results in horrible flicker when appending big amounts of text // to the control in a few chunks (see DoAddText() test in the text sample) - if ( m_isCaretAtEnd || GetInsertionPoint() == GetLastPosition() ) + if ( GetInsertionPoint() == GetLastPosition() ) { - m_isCaretAtEnd = true; return; } @@ -1141,7 +1146,7 @@ long wxTextCtrl::GetInsertionPoint() const return Pos & 0xFFFF; } -long wxTextCtrl::GetLastPosition() const +wxTextPos wxTextCtrl::GetLastPosition() const { int numLines = GetNumberOfLines(); long posStartLastLine = XYToPosition(0, numLines - 1); @@ -1484,9 +1489,6 @@ void wxTextCtrl::ShowPosition(long pos) if (linesToScroll != 0) (void)::SendMessage(hWnd, EM_LINESCROLL, (WPARAM)0, (LPARAM)linesToScroll); - - // be pessimistic - m_isCaretAtEnd = false; } long wxTextCtrl::GetLengthOfLineContainingPos(long pos) const @@ -1563,9 +1565,6 @@ void wxTextCtrl::Undo() if (CanUndo()) { ::SendMessage(GetHwnd(), EM_UNDO, 0, 0); - - // it's not necessarily at the end any more - m_isCaretAtEnd = false; } } @@ -1580,9 +1579,6 @@ void wxTextCtrl::Redo() #endif // Same as Undo, since Undo undoes the undo, i.e. a redo. ::SendMessage(GetHwnd(), EM_UNDO, 0, 0); - - // it's not necessarily at the end any more - m_isCaretAtEnd = false; } } @@ -1836,7 +1832,6 @@ bool wxTextCtrl::SendUpdateEvent() wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); InitCommandEvent(event); - event.SetString(GetValue()); return ProcessCommand(event); } @@ -2044,7 +2039,7 @@ void wxTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event) event.Enable(GetLastPosition() > 0); } -void wxTextCtrl::OnRightClick(wxMouseEvent& event) +void wxTextCtrl::OnContextMenu(wxContextMenuEvent& event) { #if wxUSE_RICHEDIT if (IsRich()) @@ -2062,7 +2057,7 @@ void wxTextCtrl::OnRightClick(wxMouseEvent& event) m_privateContextMenu->AppendSeparator(); m_privateContextMenu->Append(wxID_SELECTALL, _("Select &All")); } - PopupMenu(m_privateContextMenu, event.GetPosition()); + PopupMenu(m_privateContextMenu); return; } else @@ -2083,7 +2078,7 @@ void wxTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event)) // 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). +// the default wxSYS_COLOUR_BTNFACE (is triggered with wxNullColour). // ---------------------------------------------------------------------------- wxVisualAttributes wxTextCtrl::GetDefaultAttributes() const @@ -2467,7 +2462,7 @@ bool wxTextCtrl::SetDefaultStyle(const wxTextAttr& style) { // we have to do this or the style wouldn't apply for the text typed by // the user - long posLast = GetLastPosition(); + wxTextPos posLast = GetLastPosition(); SetStyle(posLast, posLast, m_defaultStyle); } @@ -2532,7 +2527,7 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) wxStrcpy(lf.lfFaceName, cf.szFaceName); //NOTE: we _MUST_ set each of these values to _something_ since we - //do not call wxZeroMemory on the LOGFONT lf + //do not call wxZeroMemory on the LOGFONT lf if (cf.dwEffects & CFE_ITALIC) lf.lfItalic = TRUE; else @@ -2627,6 +2622,8 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) // wxRichEditModule // ---------------------------------------------------------------------------- +static const HINSTANCE INVALID_HINSTANCE = (HINSTANCE)-1; + bool wxRichEditModule::OnInit() { // don't do anything - we will load it when needed @@ -2637,7 +2634,7 @@ void wxRichEditModule::OnExit() { for ( size_t i = 0; i < WXSIZEOF(ms_hRichEdit); i++ ) { - if ( ms_hRichEdit[i] ) + if ( ms_hRichEdit[i] && ms_hRichEdit[i] != INVALID_HINSTANCE ) { ::FreeLibrary(ms_hRichEdit[i]); ms_hRichEdit[i] = NULL; @@ -2646,17 +2643,9 @@ void wxRichEditModule::OnExit() } /* static */ -bool wxRichEditModule::Load(int version) +bool wxRichEditModule::Load(Version version) { - // we don't support loading richedit 3.0 as I don't know how to distinguish - // it from 2.0 anyhow - wxCHECK_MSG( version == 1 || version == 2, false, - _T("incorrect richedit control version requested") ); - - // make it the index in the array - version--; - - if ( ms_hRichEdit[version] == (HINSTANCE)-1 ) + if ( ms_hRichEdit[version] == INVALID_HINSTANCE ) { // we had already tried to load it and failed return false; @@ -2668,16 +2657,21 @@ bool wxRichEditModule::Load(int version) return true; } - wxString dllname = version ? _T("riched20") : _T("riched32"); - dllname += _T(".dll"); + static const wxChar *dllnames[] = + { + _T("riched32"), + _T("riched20"), + _T("msftedit"), + }; + + wxCOMPILE_TIME_ASSERT( WXSIZEOF(dllnames) == Version_Max, + RichEditDllNamesVersionsMismatch ); - ms_hRichEdit[version] = ::LoadLibrary(dllname); + ms_hRichEdit[version] = ::LoadLibrary(dllnames[version]); if ( !ms_hRichEdit[version] ) { - wxLogSysError(_("Could not load Rich Edit DLL '%s'"), dllname.c_str()); - - ms_hRichEdit[version] = (HINSTANCE)-1; + ms_hRichEdit[version] = INVALID_HINSTANCE; return false; }