RichEdit读取rtf格式
2017-01-23 16:02
232 查看
接到需求,需要在播放器播放失败时显示播放失败的错误原因,引导用户自己解决,减轻客服压力,在看到产品设计挺长的原因说明后,考虑维护简单,避免使用xml配置中直接写死的方式来解决,分析从以下方式来解决
1.考虑过通过云配线上请求。
这样的好处是可以较为实时的更新错误原因的内容,使用户能够较实时得获取到最新的帮助信息,但是弊端是无法保留UI中的格式信息,且实现较为繁琐,在与产品沟通后,要求保留错误原因信息的格式信息
2.考虑txt自定义一套简单的格式结构。
能够保留格式,但是实现起来太复杂,并且当有全新的格式,样式时需要不断的添加新的结点信息。并且一套下来可能只有创建此语法的人来维护了。
3.使用图片来实现
能够保留格式信息,但是图片格式较大,并且当内容较多时,实现上下滚动困难。
4.使用html加浏览器控件来实现基本具体所有的优点,但是难以接受的是需要携带浏览器控件带来的臃肿。
经过权衡,最终考虑使用RTF文件配合RichEdit来实现
RTF文件跨平台,是一个相对来说许多的文本编辑器都支持。并且这样实现后用户在安装目录也可以自己打开查看。:
也称富文本格式(Rich Text Format, 一般简称为RTF),意为多文本格式是由微软公司开发的跨平台文档格式。大多数的文字处理软件都能读取和保存RTF文档。[1]
rtf是一种非常流行的文件结构,很多文字编辑器都支持它,vb等开发工具甚至还提供了richtxtbox的控件。 ——《百度百科》
RTF文件跨平台,是一个相对来说许多的文本编辑器都支持。并且这样实现后用户在安装目录也可以自己打开查看。
RicheEdit使用大全:
http://www.cppblog.com/wanghaiguang/archive/2013/08/21/202683.aspx
对比一下接口,输入输出主要有三种方式:
1) GetWindowText / SetWindowText(可以输入最多 64K 的正文)
2) EM_GETTEXTEX / EM_SETTEXTEX
3) StreamIn / StreamOut (主要用于RTF等格式输出)
具体的使用可以参照上面的使用大全和网上资料
Obviously,我们应该使用第三个接口,StreamIn. 先看看MFC中如何使用
RichEdit相关的定义
要设置 RichEdit 文本,需要给 RichEdit 简单的提供一个回调函数的地址,当一切准备好时, RichEdit 会调用回调函数,并将正文缓冲区的地址传递给它。回调函数会将要发送给 RichEdit 的数据填入缓冲区或者将缓冲区的数据读出,然后等待下一次调用直到操作完成。 范例程序是流入(设置正文)和流出(取出正文)两者的例子。
最后附一下非win32的示例:
需要注意的是,一个文件会分多次来读取,每次最多4096个字节。并且文件的关闭会在文件全部读取完成时调用。
这种实现适用于关于,版权声明,错误说明等大段文字的应用场景。
参考文献:http://www.ggdoc.com/cmljaHRleHRlZGl00/MzEwOGNhZTgxNzJkZWQ2MzBiMWNiNmQ20/
1.考虑过通过云配线上请求。
这样的好处是可以较为实时的更新错误原因的内容,使用户能够较实时得获取到最新的帮助信息,但是弊端是无法保留UI中的格式信息,且实现较为繁琐,在与产品沟通后,要求保留错误原因信息的格式信息
2.考虑txt自定义一套简单的格式结构。
能够保留格式,但是实现起来太复杂,并且当有全新的格式,样式时需要不断的添加新的结点信息。并且一套下来可能只有创建此语法的人来维护了。
3.使用图片来实现
能够保留格式信息,但是图片格式较大,并且当内容较多时,实现上下滚动困难。
4.使用html加浏览器控件来实现基本具体所有的优点,但是难以接受的是需要携带浏览器控件带来的臃肿。
经过权衡,最终考虑使用RTF文件配合RichEdit来实现
RTF文件跨平台,是一个相对来说许多的文本编辑器都支持。并且这样实现后用户在安装目录也可以自己打开查看。:
也称富文本格式(Rich Text Format, 一般简称为RTF),意为多文本格式是由微软公司开发的跨平台文档格式。大多数的文字处理软件都能读取和保存RTF文档。[1]
rtf是一种非常流行的文件结构,很多文字编辑器都支持它,vb等开发工具甚至还提供了richtxtbox的控件。 ——《百度百科》
RTF文件跨平台,是一个相对来说许多的文本编辑器都支持。并且这样实现后用户在安装目录也可以自己打开查看。
RicheEdit使用大全:
http://www.cppblog.com/wanghaiguang/archive/2013/08/21/202683.aspx
对比一下接口,输入输出主要有三种方式:
1) GetWindowText / SetWindowText(可以输入最多 64K 的正文)
2) EM_GETTEXTEX / EM_SETTEXTEX
3) StreamIn / StreamOut (主要用于RTF等格式输出)
具体的使用可以参照上面的使用大全和网上资料
Obviously,我们应该使用第三个接口,StreamIn. 先看看MFC中如何使用
static DWORD CALLBACK StreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) { CFile* pFile = (CFile*)dwCookie; *pcb = pFile->Read(pbBuff, cb); return 0; } void CRichEditInputRTFDlg::OnBnClickedOk() { CFileDialog dlg(TRUE, 0, 0, OFN_HIDEREADONLY, L"(*.rtf)|*.rtf||"); if (dlg.DoModal() != IDOK) return; CString sFilePath = dlg.GetPathName(); CFile cFile(sFilePath, CFile::modeRead); EDITSTREAM es; es.dwCookie = (DWORD)&cFile; es.pfnCallback = StreamInCallback; CRichEditCtrl* m_cRichEdit = (CRichEditCtrl*)GetDlgItem(IDC_RICHEDIT21); m_cRichEdit->StreamIn(SF_RTF, es); }
RichEdit相关的定义
typedef DWORD (CALLBACK *EDITSTREAMCALLBACK)(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb); typedef struct _editstream { DWORD_PTR dwCookie; // User value passed to callback as first parameter DWORD dwError; // Last error EDITSTREAMCALLBACK pfnCallback; } EDITSTREAM; // Stream formats. Flags are all in low word, since high word // gives possible codepage choice. #define SF_TEXT 0x0001 #define SF_RTF 0x0002 #define SF_RTFNOOBJS 0x0003 // Write only #define SF_TEXTIZED 0x0004 // Write only #define SF_UNICODE 0x0010 // Unicode file (UCS2 little endian) #define SF_USECODEPAGE 0x0020 // CodePage given by high word #define SF_NCRFORNONASCII 0x40 // Output \uN for nonASCII #define SFF_WRITEXTRAPAR 0x80 // Output \par at end
要设置 RichEdit 文本,需要给 RichEdit 简单的提供一个回调函数的地址,当一切准备好时, RichEdit 会调用回调函数,并将正文缓冲区的地址传递给它。回调函数会将要发送给 RichEdit 的数据填入缓冲区或者将缓冲区的数据读出,然后等待下一次调用直到操作完成。 范例程序是流入(设置正文)和流出(取出正文)两者的例子。
最后附一下非win32的示例:
std::wstring file = L"err_reason.rtf"; FILE* pFile = _tfopen(file.c_str(), L"rt"); EDITSTREAM es; es.dwCookie = (DWORD_PTR)pFile; es.pfnCallback = EditStreamCallBack; richReason->StreamIn(SF_RTF, es); fclose(pFile); static DWORD CALLBACK EditStreamCallBack( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) { FILE* pFile = (FILE*)dwCookie; *pcb = fread((void*)pbBuff, 1, cb, pFile); return 0; }
需要注意的是,一个文件会分多次来读取,每次最多4096个字节。并且文件的关闭会在文件全部读取完成时调用。
这种实现适用于关于,版权声明,错误说明等大段文字的应用场景。
参考文献:http://www.ggdoc.com/cmljaHRleHRlZGl00/MzEwOGNhZTgxNzJkZWQ2MzBiMWNiNmQ20/
相关文章推荐
- 生于斯,归于斯
- Android Gson 解析泛型报错
- elk源码安装
- Codeforces Round #388 (Div. 2)B Parallelogram is Back
- 单例模式之传递Context参数
- Java计算某天任意天数后是哪一天
- 聚合数据全国天气预报API--ajax 通过城市名取数据
- android动态背景色圆形头像
- Spring Boot WAR包运行原理分析
- maven详解之坐标与依赖
- TCP三次握手/四次挥手详解
- Android相机Camera基础知识
- 字符集
- 父子组件通信
- openwrt移植到pb44---第一章(遗留问题)
- 第十五节 Case Class与模式匹配(二)
- 在CentOS系统下,主要有两种方法设置自己安装的程序开机启动。
- 解决使用MSBuild编译项目没有拷贝间接引用的dll问题
- 相加和最大值 (sdut oj)
- HashMap的工作原理