+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);
+#else
+ wchar_t *wchBuf = (wchar_t *)malloc((len + 1)*sizeof(wchar_t));
+#endif
+
+ if ( !::MultiByteToWideChar(codepage, 0, value, -1,
+ (wchar_t *)(const wchar_t *)wchBuf, len) )
+ {
+ wxLogLastError(_T("MultiByteToWideChar"));
+ }
+
+ // finally, stream it in the control
+ const wchar_t *wpc = wchBuf;
+#endif // wxUSE_UNICODE_MSLU
+
+ EDITSTREAM eds;
+ wxZeroMemory(eds);
+ eds.dwCookie = (DWORD)&wpc;
+ // the cast below is needed for broken (very) old mingw32 headers
+ eds.pfnCallback = (EDITSTREAMCALLBACK)wxRichEditStreamIn;
+
+ if ( !::SendMessage(GetHwnd(), EM_STREAMIN,
+ SF_TEXT |
+ SF_UNICODE |
+ (selectionOnly ? SFF_SELECTION : 0),
+ (LPARAM)&eds) || eds.dwError )
+ {
+ wxLogLastError(_T("EM_STREAMIN"));