【问题标题】:How to get text with RTF format from Rich Edit Win API?如何从 Rich Edit Win API 获取 RTF 格式的文本?
【发布时间】:2014-09-14 23:06:47
【问题描述】:

(对不起我疯狂的英语) 我想以 RTF 格式获取 Rich Edit 中的所有文本,而不是纯文本到变量。我尝试使用 EM_STREAMOUT 将 SendMessage() 直接写入富编辑到文件,但我无法将内容保存到特定变量,例如 LPWSTR。请记住,只有 Win API,而不是 MFC。感谢您的帮助!

【问题讨论】:

    标签: winapi rtf richedit


    【解决方案1】:

    您可以将变量传递给EM_STREAMOUT 回调,以便根据需要对其进行更新,例如:

    DWORD CALLBACK EditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
    {
        std::stringstream *rtf = (std::stringstream*) dwCookie;
        rtf->write((char*)pbBuff, cb);
        *pcb = cb;
        return 0;
    }
    

    .

    std::stringstream rtf;
    
    EDITSTREAM es = {0};
    es.dwCookie = (DWORD_PTR) &rtf;
    es.pfnCallback = &EditStreamOutCallback; 
    SendMessage(hRichEditWnd, EM_STREAMOUT, SF_RTF, (LPARAM)&es);
    
    // use rtf.str() as needed...
    

    更新:将 RTF 数据加载到 RichEdit 控件中,使用EM_STREAMIN,例如:

    DWORD CALLBACK EditStreamInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
    {
        std::stringstream *rtf = (std::stringstream*) dwCookie;
        *pcb = rtf->readsome((char*)pbBuff, cb);
        return 0;
    }
    

    .

    std::stringstream rtf("...");
    
    EDITSTREAM es = {0};
    es.dwCookie = (DWORD_PTR) &rtf;
    es.pfnCallback = &EditStreamInCallback; 
    SendMessage(hRichEditWnd, EM_STREAMIN, SF_RTF, (LPARAM)&es);
    

    【讨论】:

    • 感谢雷米的支持!
    • 嗨@Remy Lebeau!那么,关于将 rtf 插入 Rich Edit 吗?
    • +1 好作品。使用std::stringstream,这一切(进出)不是更容易吗?
    • 谢谢@Remy!我将“rtf”变量声明为全局变量。从 RichEdit 读取后,现在使用 'rtf' 加载到 RichEdit,我使用断点检查 'pbBuff' 的值: {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Tahoma;} {\f1\fswiss\fprq2\fcharset0 System;}} \viewkind4\uc1\pard\f0\fs20 而 'rtf' 是: {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Tahoma;}{\f1\fswiss\fprq2\fcharset0 System;}} \viewkind4\uc1\pard\f0\fs20 Hello World\b\f1\fs20\par} 为什么?
    • 回调可能会被调用多次以流式传输整个 RTF。 RTF 越大,回调可能被调用的次数就越多。
    【解决方案2】:

    使用EM_STREAMOUT 消息就是答案。

    这是我可以构建来演示的最简单的示例。这会将富编辑控件的内容保存到文件中。

    DWORD CALLBACK EditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
    {
        HANDLE hFile = (HANDLE)dwCookie;
        DWORD NumberOfBytesWritten;
        if (!WriteFile(hFile, pbBuff, cb, &NumberOfBytesWritten, NULL))
        {
            //handle errors
            return 1;
            // or perhaps return GetLastError();
        }
        *pcb = NumberOfBytesWritten;
        return 0;
    }
    
    void SaveRichTextToFile(HWND hWnd, LPCWSTR filename)
    {
        HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL,
            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
        {
            //handle errors
        }
        EDITSTREAM es = { 0 };
        es.dwCookie = (DWORD_PTR) hFile;
        es.pfnCallback = EditStreamOutCallback; 
        SendMessage(hWnd, EM_STREAMOUT, SF_RTF, (LPARAM)&es);
        CloseHandle(hFile);
        if (es.dwError != 0)
        {
            //handle errors
        }
    }
    

    【讨论】:

    • 谢谢大卫!但我需要存储到一个变量。无论如何,再次感谢!
    • 根本不清楚你想要什么。我以为你根本不知道如何使用 EM_STREAMOUT。我还假设您使用 C 进行编码。
    • 你是对的,大卫:D。我是 Win API 的新手。顺便问一下,你能帮我编辑上面的 Remy 的代码吗,如何将 [std::string rtf] 的值插入 Rich Edit 中?我知道我需要将“rtf”分配给“pbBuff”,对吗?但我不知道怎么做?我正在使用 Visual Studio 2008 编写 Win32 应用程序。谢谢!
    • 我能做到。但雷米也可以。
    • 是的,我自己先做,然后等雷米:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    相关资源
    最近更新 更多