2.0版本的富文本RICHEDIT20A的一些总结
最近在修改即时通讯模块相关问题的时候,发现1.0版本的富文本控件CRichEditCtrl有一些bug和问题,比如选中文字时背景色是黑色;当输入白色文字时,选中后不显示文字等。所以决定使用2.0版本的富文本控件,但是远没有刚开始想的那么简单,遇到很多有疑惑的问题,下面就简单的总结一下。
1、使用2.0版本的富文本控件的准备工作
如何在程序中使用2.0版本的富文本控件呢?方法如下:
方法一:(msdn上的做法,适用于用VC.NET及以后版本创建的工程)
To update rich edit controls in existing Visual C++ applications to version 2.0,
open the .RC file as text, change the class name of each rich edit control from "RICHEDIT" to "RichEdit20a".
Then replace the call to AfxInitRichEdit with AfxInitRichEdit2.
方法二:(以VC6对话框为例)--(我的是VC6的工程,所以使用这种方法)
(1) 在CxxxApp中增加一成员变量 HMODULE m_hMod;
(2) 在CxxxApp::InitInstance()中添加一句m_hMod = LoadLibrary(_T("riched20.dll")),加载2.0版本的dll库;
在CxxxApp::ExitInstance()中添加一句FreeLibrary(m_hMod),即在程序退出时,释放dll库;
(3) 以已有的富文本控件的ID,搜索到.rc文件中的相关内容,将richedit控件的类名由"RICHEDIT" 修改成 "RICHEDIT20A",如下所示:
注意:在将"RICHEDIT" 替换成 "RICHEDIT20A"时,一定要所有的地方都替换掉,否则运行时在显示相关窗口时会出现ASSERT(::IsWindow(m_hWnd))错误。原因是程序载入的2.0版本的富文本控件,如果继续使用1.0版本,将会导致所在的窗口创建失败,从而在显示窗口的时候出现assert错误,比如程序会在下面的代码错报错(CInfoDlg对话框中使用到richedit,资源中忘记将"RICHEDIT" 替换成 "RICHEDIT20A"):
2、在现有内容尾部追加新字符
要在现有内容结尾处追加新字符,则要先调用SetSel选中最末尾处,然后调用ReplaceSel将新内容加上去。richedit 1.0是按多字节进行处理的,要在richedit 1.0控件中添加新字符,可以用一下的方法:
richedit 2.0则包括RICHEDIT20A和RICHEDIT20W版本,前者是ANSI版本的,后者是宽字节版本。根据工程是否是UNICODE来选择使用哪个版本,本文主要讨论RICHEDIT20A版本的问题(因为我们的工程是非UNICODE的)。对于RICHEDIT20A,要添加新内容就不能使用上面的代码了,GetWindowTextLength()获得的是字节数,而RICHEDIT20A在计算字符位置时,是将一个汉字看成一个字符的,所以要使用上面的代码就不对了,应该使用下面的代码:
RICHEDIT20A在计算字符位置时,将一个汉字看成一个字符,这个规则很重要,在很多地方需要注意。在下面添加超链接时会用到;在发送截图时,截图是以文件传输的方式发到对端的,对于接收端在收到聊天消息时,先用一个预设图片显示到richedit中,带截图文件接收完成后再找到对应的预设图片位置用实际图片将预设图片替换掉,这里面也牵涉到位置计算问题。
3、在RICHEDIT20A中添加自定义超链接
之前这个问题折腾了我很长一段时间,一度以为RICHEDIT20A不能添加自定义超链接。因为不知道RICHEDIT20A在计算字符位置时,将一个汉字看成一个字符这个原则,一直使用CWnd的GetWindowTextLength接口来计算字符位置,导致添加链接失败。
(未完待续...)