实战经验:CRichEditCtrl的使用方法

实战经验:CRichEditCtrl的使用方法

作者:BlogUpdater |  时间:2017-04-26 |  浏览:1307 |  评论已关闭 条评论

RichEditCtrl是一款富文本编辑器控件,相对于CEdit来说,其功能更加强大。另外,它自带RTF格式文本的解析功能。今天就总结一下我在使用这款控件的一些经验。

1. 关于RichEditCtrl的版本
随着Windows每次版本的发布,RichEditCtrl的版本也在不断升级。从最初的1.0版本一直到目前最新的4.1版本。以下版本历史来自的MSDN:
Rich Edit version                             DLL                                     Window Class
1.0                                           Riched32.dll                          RICHEDIT_CLASS
2.0                                          Riched20.dll                          RICHEDIT_CLASS
3.0                                          Riched20.dll                          RICHEDIT_CLASS
4.1                                           Msftedit.dll                            MSFTEDIT_CLASS
这里需要注意的是,1.0版本对应的DLL文件是Riched32.dll,2.0和3.0对应的DLL文件是Riched20.dll,最新的4.1对应的DLL是Msftedit.dll。另外,1.0~3.0对应的Window Class名称没有变,这样,应用程序就可以无缝使用各个版本而无需修改代码。对于各个DLL文件,我们可以在system32目录下找到它们。

2. 关于RichEditCtrl的初始化
在MFC应用程序中使用RichEditCtrl控件之前,必须要在InitInstance中初始化该控件,如下所示:

if (!AfxInitRichEdit2())
{
    throw(_T("Init rich edit control failed"));
}

这里的AfxInitRichEdit2将尝试加载Riched20.dll这个DLL,并返回加载是否成功的结果。如果想使用1.0版本,还有对应的AfxInitRichEdit可供调用。

3. 如何载入内容到RichEditCtrl控件
RichEditCtrl控件有个方法StreamIn,我们可以使用这个方法将我们需要显示在控件的内容渲染到控件上。该函数原型如下:
long StreamIn(int nFormat, EDITSTREAM& es);

该方法的工作原理:调用方需要提供一个回调函数指针,该回调函数周期性的拷贝文本内容到控件缓冲区,直到文本内容全部拷贝完毕。
以下代码演示了该回调函数的使用:

BOOL CMyDialog::OnInitDialog()
{
    EDITSTREAM es;
    es.dwError = 0;
    es.pfnCallback = (EDITSTREAMCALLBACK)StreamInCallBack;
    es.dwCookie = (DWORD)&paramObject;
    if(type == "RTF")
    {
        m_richEditCtrl.StreamIn(SF_RTF, es);
    }
    else if (type == "TXT")
    {
        m_richEditCtrl.StreamIn(SF_TEXT, es);
    }
    else
    {
        throw(_T("Unsupported document type"));
    }
}

回调函数如下:

DWORD CALLBACK CMyDialog::StreamInCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
	ParamObject * pObject = (ParamObject *)dwCookie;
	*pcb = 0;

	if (pObject->start < 0 )
	{
		return (0); 
	}
	if( 0 == cb ) 
	{ 
		return(0); 
	}

	LONG maxReadSize = cb;
	LONG readSize = cb; 
	if (pCookie->lSize < cb)
	{
		maxReadSize = static_cast<LONG>(pObject->dataSize);
	}
	if (maxReadSize <= 0) 
	{ 
		return 0; 
	} 
	readSize = maxReadSize; 
	if ((pObject->dataSize - pObject->start) < readSize)
	{
		readSize = static_cast<LONG>(pObject->dataSize - pObject->start);
	}

	if (readSize > 0)
	{
		BYTE * readBuf = pObject->m_pThis->m_pFileDataBuf;
		readBuf += pObject->start;
		pObject->start += readSize;
		memcpy(pbBuff, readBuf, readSize);
	}
	*pcb = readSize;

	return 0;
}

4. 如何使用最新版4.1的控件
在默认情况下,我们从VS工具箱拖出来的控件为2.0版本。那么如何使用最新的4.1版本呢?
首先,我们需要在CWinApp的InitInstance中加载4.1对应的DLL:Msftedit.dll,示例代码如下

m_hLibRichEditControl = LoadLibrary(_T("msftedit.dll"));

别忘了在ExitInstance中释放该Lib,示例代码如下:

if (m_hLibRichEditControl != NULL)
{
	FreeLibrary(m_hLibRichEditControl);
	m_hLibRichEditControl = NULL;
}

然后,打开rc文件,进入文本编辑模式,将”RichEdit20W”改为”RichEdit50W”,保存后编译工程,就可以通过Spy++查看控件已经升级到4.1版本了.

今天总结了关于CRichEditCtrl的一些开发经验,详细的使用方法,请大家参考MSDN中的相关内容。

标签:

评论已关闭。