
Introduction
There are a number of articles on the Internet offering advice on streaming the constituent text out of rich edit components. Although some provided source code, they still seemed a little ambiguous, and in certain cases did not provide fully what I wanted.
Reading rich text from a Rich Edit View simply involves defining a suitable callback function to transfer data. The job of calling these functions is then even easier. Example callback functions are frequently found on the Internet, however, for my own use these were unsuitable as they did not handle large amounts of text (as you would expect if you had inline objects). The code presented below is able to handle much larger documents, involving multiple calls to the callback function.
I will first describe the callback functions themselves, giving a short overview of what we're trying to achieve, then move onto explaining how you would use them in your own program.
Stream in callback function
This function takes a string passed via
dwCookie
and copies as much as it is allow (specified by
cb
) into the buffer. When the copy is done it crops the copied data from the string, reader for the next call (if necessary).
DWORD __stdcall MEditStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CString *psBuffer = (CString *)dwCookie;
if (cb < psBuffer->GetLength()) cb = psBuffer->GetLength();
for (int i=0;i<cb;i++)
{
*(pbBuff+i) = psBuffer->GetAt(i);
}
*pcb = cb;
*psBuffer = psBuffer->Mid(cb);
return 0;
}
Stream out callback function
This copies as much as the buffer contains to a temporary
CString
, then to the end of the whole
CString
.
DWORD __stdcall MEditStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CString sThisWrite;
sThisWrite.GetBufferSetLength(cb);
CString *psBuffer = (CString *)dwCookie;
for (int i=0;i<cb;i++) {
sThisWrite.SetAt(i,*(pbBuff+i));
}
*psBuffer += sThisWrite;
*pcb = sThisWrite.GetLength();
sThisWrite.ReleaseBuffer();
return 0;
}
These functions can near enough be copied and pasted into your project. I recommend adding them to the MyApp.cpp
and MyApp.h
files usually created by AppWizard.
Next we actually want to use the functions to do something useful. For this example I've created a sample project, and made two events associated to menu items. This shows how to use the callback functions with EDITSTREAM
.
How to read rich text into a CString
The function below defines a
CString
, then streams rich text into it. For the purposes of viewing, it will show the first 500 characters in a message box.
void CRichEgView::OnReadout()
{
CString sReadText;
EDITSTREAM es;
es.dwCookie = (DWORD)&sReadText;
es.pfnCallback = MEditStreamOutCallback;
GetRichEditCtrl().StreamOut(SF_RTF,es);
MessageBox(sReadText.Mid(0,500));
}
How to read rich text out of a Rich Edit View
The function below defines a string and sets it to some rich text (as shown in the sample project). It then streams the text in, which will in turn show up on the screen.
void CRichEgView::OnReadin()
{
CString sWriteText;
sWriteText="Rich text is shown here in sample project";
EDITSTREAM es;
es.dwCookie = (DWORD)&sWriteText;
es.pfnCallback = MEditStreamInCallback;
GetRichEditCtrl().StreamIn(SF_RTF,es);
}
This is basically all you need to deal with streaming rich text in and out. Using CFile
you will be able to store the rich text to a file for future use.