15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


QUESTION: Setting a CRichEditCtl with a CString with RTF

Daniel Rosengarten -- 70451.2212@compuserve.com
Friday, March 29, 1996

Can someone please explain (an example would be nice) how to set
a Rich Text Control from a CString that contains a complete Rich Text encoded
file (all the RTF codes).  It's VB4 counterpart is
RichTextBox1.textRTF=strMyRTFString.  
I am using MSVC 4.1 under windows 95. 
I have tried SetWindowText-it just shows all the text including the RTF codes.
I don't want to select each format change- that would take too long.  I think
the answer lies somewhere with CRichEditCtl::StreamIn, but I can't figure out
how to create the editstream and callback function.


Any help would be appreciated.
Daniel Rosengarten




Chet Murphy -- cmurphy@modelworks.com
Sunday, March 31, 1996

[Mini-digest: 2 responses]

Daniel Rosengarten wrote:
> 
> Can someone please explain (an example would be nice) how to set
> a Rich Text Control from a CString that contains a complete Rich Text encoded
> file (all the RTF codes).  It's VB4 counterpart is
> RichTextBox1.textRTF=strMyRTFString.
> I am using MSVC 4.1 under windows 95.
> I have tried SetWindowText-it just shows all the text including the RTF codes.
> I don't want to select each format change- that would take too long.  I think
> the answer lies somewhere with CRichEditCtl::StreamIn, but I can't figure out
> how to create the editstream and callback function.
> 
> Any help would be appreciated.
> Daniel Rosengarten

Daniel,

You need to use StreamIn.  Here is the code that I use to stream in RTF text.  SetBuffer is 
the main routine and SetBufferCallback is the callback used by ctrl.StreamIn

struct ExchangeBuffer {
	LPTSTR buffer;
	long currentOffset;
	long length;
};

DWORD CALLBACK SetBufferCallback(DWORD dwCookie, 
    LPBYTE pbBuff, LONG cb, LONG FAR *pcb)
{
	ExchangeBuffer* exchange = (ExchangeBuffer*)dwCookie;
	if (exchange->currentOffset + cb < exchange->length)
	{
		*pcb = cb;
		memcpy(pbBuff,&exchange->buffer[exchange->currentOffset],cb);
		exchange->currentOffset += cb;
	}
	else
	{
		*pcb = exchange->length - exchange->currentOffset;
		memcpy(pbBuff,&exchange->buffer[exchange->currentOffset],*pcb);
		exchange->currentOffset = exchange->length; 
	}

	return NULL; // Return null to continue
} 

void SetBuffer(CRichEditCtrl& ctrl, LPTSTR buffer, BOOL rtf, BOOL selection)
{
	EDITSTREAM es;

	long length = strlen(buffer);

	ExchangeBuffer exchangeBuffer;
	exchangeBuffer.buffer = buffer;
	exchangeBuffer.currentOffset = 0;
	exchangeBuffer.length = length;

	es.dwCookie = (DWORD)&exchangeBuffer; 
	es.dwError = NULL; 
	es.pfnCallback = SetBufferCallback; 

	if (!selection)
	{
		if (rtf)
			ctrl.StreamIn(SF_RTF, es);
		else
			ctrl.StreamIn(SF_TEXT, es);
	}
	else
	{
		if (rtf)
			ctrl.StreamIn(SF_RTF | SFF_SELECTION, es);
		else
			ctrl.StreamIn(SF_TEXT | SFF_SELECTION, es);
	}	
}

--Chet Murphy
ModelWorks Software
cmurphy@modelworks.com
http://www.modelworks.com/express

-----From: Rih Saad 



This Sample Code is what i wrote for handling RichEd in VC 2.2 i thing it should work for you
typedef struct __tagRtfStream
{
	LPCSTR    m_lpString;
	int 	 m_index;
	int		 m_Length;
} RtfStream;

DWORD CALLBACK RtfSetCallBack(DWORD dwCookie, LPBYTE pbBuffer, LONG cb, LONG *pcb);
void CRichEdView::SetRtfText(CString &Str,int Type /*=SF_RTF*/ )
{
	RtfStream Rtf;
	Rtf.m_lpString = (LPCSTR)Str;
	Rtf.m_index=0;
	Rtf.m_Length = Str.GetLength();
	EDITSTREAM es;
	es.dwCookie = (DWORD)&Rtf;
 
	SendMessage(WM_SETREDRAW, (WPARAM) FALSE);

	es.dwError = 0;
	es.pfnCallback = RtfSetCallBack;

	SendMessage(EM_STREAMIN,(WPARAM) Type,(LPARAM) &es);
	
	SendMessage(EM_SETMODIFY, (WPARAM) FALSE, 0);	
	SendMessage(WM_SETREDRAW, (WPARAM) TRUE, 0);
	InvalidateRect( NULL, TRUE);
	UpdateWindow();

}

DWORD CALLBACK RtfSetCallBack(DWORD dwCookie, LPBYTE pbBuffer, LONG cb, LONG *pcb)
{
	RtfStream *pRtf= (RtfStream *) dwCookie;

	if(pRtf == NULL)
		return (DWORD) E_FAIL;
	int HowMuch = (pRtf->m_Length-pRtf->m_index);
	if( HowMuch > cb  )
		HowMuch = cb;

	memcpy(pbBuffer,&pRtf->m_lpString[pRtf->m_index],HowMuch);
	*pcb = HowMuch;
	pRtf->m_index+=HowMuch;

	return NOERROR;
}

DWORD CALLBACK RtfGetCallBack(DWORD dwCookie, LPBYTE pbBuffer, LONG cb, LONG *pcb);
void CRichEdView::GetRtfText(CString &Str)
{
	RtfStream Rtf;
	// just make an assumption to allocate a buffer
	// i didn't find how to know the size of
	// the text it will get.
	Rtf.m_lpString = Str.GetBuffer(65000); 
	Rtf.m_index=0;
	Rtf.m_Length = 65000;
	EDITSTREAM es;

	es.dwCookie = (DWORD)&Rtf;
	es.dwError = 0;
	es.pfnCallback = RtfGetCallBack;

	LRESULT cc=SendMessage(EM_STREAMOUT,(WPARAM) SF_RTF,(LPARAM) &es);

	Str.ReleaseBuffer(cc);
	
	
}

DWORD CALLBACK RtfGetCallBack(DWORD dwCookie, LPBYTE pbBuffer, LONG cb, LONG *pcb)
{
	RtfStream *pRtf= (RtfStream *) dwCookie;

	if(pRtf == NULL)
		return (DWORD) E_FAIL;

	int HowMuch = (cbm_Length?cb:pRtf->m_Length);
	// you must handle this more robustly
	// or expand the buffer for each request
	ASSERT ( HowMuch+pRtf->m_Length < 65000 );
	memcpy((LPSTR)&pRtf->m_lpString[pRtf->m_index],pbBuffer,HowMuch);
	*pcb = HowMuch;
	pRtf->m_index+=HowMuch;

	return NOERROR;
}

Rih Saad
Wind Systeme.




| Вернуться в корень Архива |