X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cb0afb266214f827417c42474168c7edda7c953e..e2c922f53f6a8f08e8a82817c75981822dbe9ca1:/src/msw/textctrl.cpp diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index e96a9b03e3..7dd6a84fcf 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -534,24 +534,39 @@ wxString wxTextCtrl::GetRange(long from, long to) const // we must use EM_STREAMOUT if we don't want to lose all characters // not representable in the current character set (EM_GETTEXTRANGE // simply replaces them with question marks...) - // - // as EM_STREAMOUT only works for the entire controls contents (or - // just the selection but it's probably a bad idea to play games - // with selection here...), we can't use it unless we're called - // from GetValue(), i.e. we want to retrieve all text - if ( GetRichVersion() > 1 && (from == 0 && to >= len) ) + if ( GetRichVersion() > 1 ) { + // we must have some encoding, otherwise any 8bit chars in the + // control are simply *lost* (replaced by '?') + wxFontEncoding encoding = wxFONTENCODING_SYSTEM; + wxFont font = m_defaultStyle.GetFont(); if ( !font.Ok() ) font = GetFont(); if ( font.Ok() ) { - wxFontEncoding encoding = font.GetEncoding(); - if ( encoding != wxFONTENCODING_SYSTEM ) - { - str = StreamOut(encoding); - } + encoding = font.GetEncoding(); + } + + if ( encoding == wxFONTENCODING_SYSTEM ) + { + encoding = wxLocale::GetSystemEncoding(); + } + + if ( encoding == wxFONTENCODING_SYSTEM ) + { + encoding = wxFONTENCODING_ISO8859_1; + } + + str = StreamOut(encoding); + + if ( !str.empty() ) + { + // we have to manually extract the required part, luckily + // this is easy in this case as EOL characters in str are + // just LFs because we remove CRs in wxRichEditStreamOut + str = str.Mid(from, to - from); } } @@ -622,6 +637,9 @@ void wxTextCtrl::SetValue(const wxString& value) if ( (value.length() > 0x400) || (value != GetValue()) ) { DoWriteText(value, FALSE /* not selection only */); + + // for compatibility, don't move the cursor when doing SetValue() + SetInsertionPoint(0); } else // same text { @@ -634,9 +652,6 @@ void wxTextCtrl::SetValue(const wxString& value) // 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) @@ -665,24 +680,37 @@ wxRichEditStreamIn(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb) return 0; } +// helper struct used to pass parameters from wxTextCtrl to wxRichEditStreamOut +struct wxStreamOutData +{ + wchar_t *wpc; + size_t len; +}; + DWORD CALLBACK wxRichEditStreamOut(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb) { *pcb = 0; - wchar_t ** const ppws = (wchar_t **)dwCookie; + wxStreamOutData *data = (wxStreamOutData *)dwCookie; const wchar_t *wbuf = (const wchar_t *)buf; - wchar_t *wpc = *ppws; - while ( cb && *wpc ) + wchar_t *wpc = data->wpc; + while ( cb ) { - *wpc++ = *wbuf++; + wchar_t wch = *wbuf++; + + // turn "\r\n" into "\n" on the fly + if ( wch != L'\r' ) + *wpc++ = wch; + else + data->len--; cb -= sizeof(wchar_t); (*pcb) += sizeof(wchar_t); } - *ppws = wpc; + data->wpc = wpc; return 0; } @@ -767,9 +795,13 @@ wxTextCtrl::StreamOut(wxFontEncoding encoding, bool selectionOnly) const wchar_t *wpc = wchBuf; #endif + wxStreamOutData data; + data.wpc = wpc; + data.len = len; + EDITSTREAM eds; wxZeroMemory(eds); - eds.dwCookie = (DWORD)&wpc; + eds.dwCookie = (DWORD)&data; eds.pfnCallback = wxRichEditStreamOut; ::SendMessage @@ -786,13 +818,17 @@ wxTextCtrl::StreamOut(wxFontEncoding encoding, bool selectionOnly) const } else // streamed out ok { - // now convert to the given encoding (this is a lossful conversion but - // what else can we do) + // NUL-terminate the string because its length could have been + // decreased by wxRichEditStreamOut + *(wchBuf.data() + data.len) = L'\0'; + + // now convert to the given encoding (this is a possibly lossful + // conversion but what else can we do) wxCSConv conv(encoding); - size_t lenNeeded = conv.WC2MB(NULL, wchBuf, len); - if ( lenNeeded ) + size_t lenNeeded = conv.WC2MB(NULL, wchBuf, 0); + if ( lenNeeded++ ) { - conv.WC2MB(wxStringBuffer(out, lenNeeded), wchBuf, len); + conv.WC2MB(wxStringBuffer(out, lenNeeded), wchBuf, lenNeeded); } } @@ -1229,13 +1265,7 @@ void wxTextCtrl::Replace(long from, long to, const wxString& value) // Set selection and remove it DoSetSelection(from, to, FALSE /* don't scroll caret into view */); - SendMessage(GetHwnd(), EM_REPLACESEL, -#ifdef __WIN32__ - TRUE, -#else - FALSE, -#endif - (LPARAM)value.c_str()); + DoWriteText(value, TRUE /* selection only */); } void wxTextCtrl::Remove(long from, long to)