+ if ( classname.IsSameAs(_T("EDIT"), FALSE /* no case */) )
+ {
+ m_verRichEdit = 0;
+ }
+ else // rich edit?
+ {
+ wxChar c;
+ if ( wxSscanf(classname, _T("RichEdit%d0%c"), &m_verRichEdit, &c) != 2 )
+ {
+ wxLogDebug(_T("Unknown edit control '%s'."), classname.c_str());
+
+ m_verRichEdit = 0;
+ }
+ }
+#endif // wxUSE_RICHEDIT
+
+ if (style & ES_MULTILINE)
+ m_windowStyle |= wxTE_MULTILINE;
+ if (style & ES_PASSWORD)
+ m_windowStyle |= wxTE_PASSWORD;
+ if (style & ES_READONLY)
+ m_windowStyle |= wxTE_READONLY;
+ if (style & ES_WANTRETURN)
+ m_windowStyle |= wxTE_PROCESS_ENTER;
+}
+
+// ----------------------------------------------------------------------------
+// set/get the controls text
+// ----------------------------------------------------------------------------
+
+wxString wxTextCtrl::GetValue() const
+{
+ // range 0..-1 is special for GetRange() and means to retrieve all text
+ return GetRange(0, -1);
+}
+
+wxString wxTextCtrl::GetRange(long from, long to) const
+{
+ wxString str;
+
+ if ( from >= to && to != -1 )
+ {
+ // nothing to retrieve
+ return str;
+ }
+
+#if wxUSE_RICHEDIT
+ if ( IsRich() )
+ {
+ int len = GetWindowTextLength(GetHwnd());
+ if ( len > from )
+ {
+ // alloc one extra WORD as needed by the control
+ wxChar *p = str.GetWriteBuf(++len);
+
+ TEXTRANGE textRange;
+ textRange.chrg.cpMin = from;
+ textRange.chrg.cpMax = to == -1 ? len : to;
+ textRange.lpstrText = p;
+
+ (void)SendMessage(GetHwnd(), EM_GETTEXTRANGE, 0, (LPARAM)&textRange);
+
+ if ( m_verRichEdit > 1 )
+ {
+ // RichEdit 2.0 uses just CR ('\r') for the newlines which is
+ // neither Unix nor Windows style - convert it to something
+ // reasonable
+ for ( ; *p; p++ )
+ {
+ if ( *p == _T('\r') )
+ *p = _T('\n');
+ }
+ }
+
+ str.UngetWriteBuf();
+
+ if ( m_verRichEdit == 1 )
+ {
+ // convert to the canonical form - see comment below
+ str = wxTextFile::Translate(str, wxTextFileType_Unix);
+ }
+ }
+ //else: no text at all, leave the string empty
+ }
+ else
+#endif // wxUSE_RICHEDIT
+ {
+ // retrieve all text
+ str = wxGetWindowText(GetHWND());
+
+ // need only a range?
+ if ( from < to )
+ {
+ str = str.Mid(from, to - from);
+ }
+
+ // WM_GETTEXT uses standard DOS CR+LF (\r\n) convention - convert to the
+ // canonical one (same one as above) for consistency with the other kinds
+ // of controls and, more importantly, with the other ports
+ str = wxTextFile::Translate(str, wxTextFileType_Unix);
+ }
+
+ return str;
+}
+
+void wxTextCtrl::SetValue(const wxString& value)
+{
+ // if the text is long enough, it's faster to just set it instead of first
+ // comparing it with the old one (chances are that it will be different
+ // anyhow, this comparison is there to avoid flicker for small single-line
+ // edit controls mostly)
+ if ( (value.length() > 0x400) || (value != GetValue()) )
+ {
+ DoWriteText(value, FALSE /* not selection only */);
+
+ // mark the control as being not dirty - we changed its text, not the
+ // user
+ DiscardEdits();
+
+ // for compatibility, don't move the cursor when doing SetValue()
+ SetInsertionPoint(0);
+ }
+}
+
+#if wxUSE_RICHEDIT && (!wxUSE_UNICODE || wxUSE_UNICODE_MSLU)
+
+DWORD CALLBACK wxRichEditStreamIn(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb)
+{
+ *pcb = 0;
+
+ wchar_t *wbuf = (wchar_t *)buf;
+ const wchar_t *wpc = *(const wchar_t **)dwCookie;
+ while ( cb && *wpc )
+ {
+ *wbuf++ = *wpc++;
+
+ cb -= sizeof(wchar_t);
+ (*pcb) += sizeof(wchar_t);
+ }
+
+ *(const wchar_t **)dwCookie = wpc;
+
+ return 0;
+}
+
+extern long wxEncodingToCodepage(wxFontEncoding encoding); // from utils.cpp
+
+#if wxUSE_UNICODE_MSLU
+bool wxTextCtrl::StreamIn(const wxString& value,
+ wxFontEncoding WXUNUSED(encoding),
+ bool selectionOnly)
+{
+ const wchar_t *wpc = value.c_str();
+#else // !wxUSE_UNICODE_MSLU
+bool wxTextCtrl::StreamIn(const wxString& value,
+ wxFontEncoding encoding,
+ bool selectionOnly)
+{
+ // we have to use EM_STREAMIN to force richedit control 2.0+ to show any
+ // text in the non default charset - otherwise it thinks it knows better
+ // than we do and always shows it in the default one
+
+ // first get the Windows code page for this encoding
+ long codepage = wxEncodingToCodepage(encoding);
+ if ( codepage == -1 )
+ {
+ // unknown encoding
+ return FALSE;
+ }
+
+ // next translate to Unicode using this code page
+ int len = ::MultiByteToWideChar(codepage, 0, value, -1, NULL, 0);
+
+#if wxUSE_WCHAR_T
+ wxWCharBuffer wchBuf(len);