RichEdit RTF格式文本的存储和读取 VC++

发布时间 2023-08-01 12:59:32作者: XGZ21

Rtf格式文本的读写,向控件发送 EM_STREAMIN 和 EM_STREAMOUT 消息,控件把格式文本显示或从把显示内容转化为格式文本。

接口是用户定义的回调函数,格式文本由参数DWORD_PTR dwCookie传递。

从控件读出RTF文本,参数用string 比较好,因为消息处理是根据文本的长度,多次调用回调函数,传出数据需要在回调函数中多次分配内存空间,
拼接字符串,直接用指针比较麻烦。每次重新分配似乎不太好。
用string 可以直接操作符+=,或append方法拼接字符串,

DWORD CALLBACK CXTREdit::EditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb)
{
    string* psEntry = (string*)dwCookie; //指向DWORD的指针, dwCookie 实际上是 &lpRTF
        
    //*psEntry += (char*)pbBuff;   //+= 和Append 应该都是内存拼接
    (*psEntry).append((char*)pbBuff); // += 和Append 应该都是内存拼接

    *pcb = strlen((char*)pbBuff);  //当前处理的数量 

    return 0;
}

int CXTREdit::GetRTF(string &sRtf)
{
    EDITSTREAM es = { (DWORD_PTR)&sRtf, 0, EditStreamOutCallback };

    int iAttrib = SF_RTF;
    SendMessage(m_hWndREdit, EM_STREAMOUT, (WPARAM)iAttrib, (LPARAM)&es);

    return sRtf.length();

}

 

把RTF写入控件进行显示,则直接传入指针即可,若显示完要释放字符串空间,则原来的指针不要被改了,传指针的值,不要传引用。
而在回调函数里,因为要分段处理,所以指针是要被修改的,所以回调函数中传指针的地址。

DWORD CALLBACK CXTREdit::EditStreamInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb)  //OK
{
    char** psEntry = (char**)dwCookie;  //传指针地址其实就是传 指针的指针

    LONG len = strlen(*psEntry);

    if (len > cb) len = cb;

    LONG i = 0;
    while ((i++) < len)  //cb最大是0xffc,处理时原来的指针移动需要保存,所以用指针的指针
    {
        *(pbBuff++)= *((*psEntry)++);  //改动的是被指的指针
    }
    *pcb = i;
return 0; } int CXTREdit::SetRTF(char* pRtf) { //pRtf指针是传值进来的,这里再传地址是指向pRtf字符串的新指针,不会改变pRtf原来的指针 EDITSTREAM es = { (DWORD)&pRtf, 0, EditStreamInCallback }; //把新指针的地址传进去,因为要在回调函数中移动 int iAttrib = SF_RTF; SendMessage(m_hWndREdit, EM_STREAMIN, (WPARAM)iAttrib, (LPARAM)&es); return strlen(pRtf);
}