X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9ffa72272ba67827a83993b1e3ec8a312ec88434..f75aecd00fc2ace70ffe846ab9e30d9d511214f3:/src/msw/textctrl.cpp diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index d577edd1a2..7dd6a84fcf 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -564,9 +564,8 @@ wxString wxTextCtrl::GetRange(long from, long to) const if ( !str.empty() ) { // we have to manually extract the required part, luckily - // this is easy in this case as EOL characters in richedit - // version > 1 are just '\r's and so positions map to - // string indices one to one (unlike with richedit 1) + // 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); } } @@ -638,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 { @@ -650,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) @@ -681,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; } @@ -783,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 @@ -802,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); } }