Re: CRichEditCtrl contents from RTF file
Goran, I couldn't see how this resolves reading in an RTF unicode?
I am not yet an UNI-GARBAGE expert, but I got it to work doing this
(excluding the finer details of passing an object):
In InitDialog()
#define BOM L'\xFEFF'
....
EDITSTREAM es = {0};
WCHAR ch;
int n = eulaFile2.Read(&ch, sizeof(WCHAR));
if(n == 2 && ch == BOM) {
es.pfnCallback = (EDITSTREAMCALLBACK)MyStreamInCallbackW;
m_RECtrlW.StreamIn(SF_RTF | SF_UNICODE, es);
} else {
eulaFile2.SeekToBegin();
es.pfnCallback = (EDITSTREAMCALLBACK)MyStreamInCallback;
m_RECtrlW.StreamIn(SF_RTF, es);
}
And the MyStreamInCallbackW() reads in cb amount and converts it a
multi-byte array.
Of course, this can all be done cleanly passing the cookie struct like
you have it to 1 callback and have it do the initial BOM test, but I
would like to know if converting it to a multi-byte array in the
callback was correct or it is redundant based on the StreamIn()
parameters (SF_RTF | SF_UNICODE), etc.
--
Goran wrote:
Whoops! That went out sooner than I wanted... The above worked for
me, regardless of the file size, using unicode in project settings,
and using rtf in two rather distinctive languages.
I don't know why you use OnCreate. It should work, your code, but...
DDX_Control in DoDataExchange is easier.
Other than that, note a canonical form for any non-trivial
OnInitDialog is e.g:
bool CXDialog::OnInitDialog()
{
CDialog::OnInitDialog();
TRY
{
InitBabyInit();
}
CATCH(CException* pe)
{
ReportErrorSomehow(pe);
EndDialog(PROBABLY_ID_CANCEL); // But it's up to you.
}
}
It's a bad idea to let exception escape your callback (possible due to
use of MFC in it), so you should e.g. do:
struct RichEditStreamInContext
{
RichEditStreamInContext(const CString& csFileName) :
m_File(csFileName, CFile::modeRead), m_pError(NULL) {}
CFile m_File;
CException* m_pError;
};
static DWORD CALLBACK MyStreamInCallback(DWORD_PTR dwCookie, LPBYTE
pbBuff, LONG cb, LONG *pcb)
{
RichEditStreamInContext& Ctx =
*reinterpret_cast<RichEditStreamInContext*>(dwCookie);
try
{
*pcb = Ctx.m_File.Read(pbBuff, cb);
return 0;
}
catch (CException* p)
{
ASSERT(FALSE);
Ctx.m_pError = p;
return -1;
}
}
and in OnInitDialog:
...
RichEditStreamInContext Ctx(RTF_PATH_HERE);
EDITSTREAM es = { (DWORD_PTR)&Ctx, 0, &MyStreamInCallback };
MCALLBACK)MyStreamInCallback;
m_Edit.StreamIn(SF_RTF, es);
if (es.dwError)
HandleError(Ctx); // Including looking at Ctx.m_pError;
HTH,
Goran.
--
HLS