RTF Stream 2

This article details my fast rich text streaming to and from CRichEditViews. It's not easy to understand but it is fast. If you're looking for streaming that doesn't require critical speed try my other article Painless streaming with CRichEditView.

The first thing you need to define is your stream cookie. This passes the data you're streaming to the callback functions StreamIn and StreamOut.

class StreamCookie{
public:
StreamCookie()
{
iPos=0;
iSize=0;
}
int iPos;
int iSize;
CString sData;
CStringArray saData;
};

This class should be declared in the header of the CRichEditView derived class. You should be able to copy-paste the code directly into the top of the header file.

Next you need to define the two callback functions to do the streaming. The following two lines should appear above the StreamCookie definition.

DWORD __stdcall MEditStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);

DWORD __stdcall MEditStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);

Ok, now we've got everything declared at least we can move onto the declarations of the callback functions. First, let's look at the stream in function. I should note both the stream in and stream out functions should be pasted into the CRichEditView derived CPP file.

DWORD __stdcall MEditStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
StreamCookie *streamCookie = (StreamCookie*)dwCookie;

if (cb > streamCookie->sData.GetLength()-streamCookie->iPos)
cb = streamCookie->sData.GetLength()-streamCookie->iPos;

for (int i=0;i<cb;i++) {
*(pbBuff+i) = streamCookie->sData.GetAt(i+streamCookie->iPos);
}

*pcb = cb;

streamCookie->iPos += cb;

return 0;
}

Seem straight forward enough? Let's have a look at the stream out function..

DWORD __stdcall MEditStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
StreamCookie *streamCookie = (StreamCookie*)dwCookie;

char *szAdd = new char[cb+1];

for (int i=0;i<cb;i++) {
szAdd[i] = *(pbBuff+i);
}
szAdd[cb]=0;

streamCookie->saData.Add(szAdd);

*pcb = cb;

delete[] szAdd;

return 0;
}

Now we've got everything declared we can start using them.. First let's try streaming some rich text into the view. This code would be placed in CRichEditView wherever you want to stream the text.

EDITSTREAM es;
StreamCookie *streamCookie = new StreamCookie;
streamCookie->sData = "This is my rich text";

es.dwCookie = (DWORD)streamCookie;
es.pfnCallback = MEditStreamInCallback;
rich.StreamIn(SF_RTF,es);

Now's let try streaming some text out.

EDITSTREAM es;
StreamCookie *streamCookie = new StreamCookie;

es.dwCookie = (DWORD)streamCookie;
es.pfnCallback = MEditStreamOutCallback;
rich.StreamOut(SF_RTF,es);

int iSize=0;
for (int i=0;i<streamCookie->saData.GetSize();i++) {
iSize += streamCookie->saData.GetAt(i).GetLength();
}

char *pszData = new char[iSize+1];
int iIndex=0;

// Copy each element of the CStringArray to a linear char array
for (int iElem=0;iElem<streamCookie->saData.GetSize();iElem++) {
CString sThis = streamCookie->saData.GetAt(iElem);
for (int iChar=0;iChar<sThis.GetLength();iChar++) {
*(pszData+iIndex) = sThis.GetAt(iChar);
iIndex++;
}
}

You then have pszData containing your stream. This can be converted to a CString if you prefer in the usual way.

So, I hope that's all you need to know. If you want any advice then by all means contact me. I'll do my best to answer questions.

I encourage you to make a link to this site from yours. I found it impossible to track down fast streaming routines, which is the end is why I had to spend time making my own. I'm hoping by making it available others can find it useful and save their own time.


Was this useful? (5 = best)  1   2   3   4   5