0

I am using CRichEditCtrl (RichEdit20A) to display rtf-text:

m_reText.SetWindowText(strRtfText);

The problem is that the control does not display a border around words in rtf-text like this:

{\rtf1
\box\brdrdot
Hello World
}

I also tried RichEdit5.0 in a way as it proposed here, but result is the same, border is not displayed. However, if I save the text in .rtf file and open it in MSWord or Libre/OpenOffice editor, the dotted border around text is displayed correctly:

enter image description here

Why does CRichEditControl hide the border in my case? Please help, I would appreciate any suggestions.

vtrz
  • 591
  • 1
  • 6
  • 12
  • 1
    `m_reText.SetWindowText(strRtfText);` will not work at all. It will just show the text as is `"{\rtf1\box\..."`. You have load the rtf text through edit stream. It still won't show some features like those borders. Microsoft Word uses a different engine, that's why it can show it. I think in RTF you can show tables, I don't remember. You might consider using HTML control, but that could run in to other problems. – Barmak Shemirani Oct 13 '17 at 07:34
  • Thanks a lot for answer. For me, loading by SetWindowText works fine, the control shows as much formatting as Wordpad, including tables. But exept those borders( – vtrz Oct 13 '17 at 08:34
  • "Microsoft Word uses a different engine" If so, why it is load RichEdit20W, as shown by spy++ for spell check dialog box in MSWord 2010 (and this box *shows* the borders around text)? – vtrz Oct 13 '17 at 09:29

1 Answers1

1

You can display tables and borders with rich edit. The following will show a box with solid borders:

str = L"{\\rtf1\
\\trowd\\trgaph72 \
\\clbrdrt\\brdrdot\\clbrdrl\\brdrdot\\clbrdrb\\brdrdot\\clbrdrr\\brdrdot \
\\cellx3000 TEXT\\intbl\\cell \
\\row\\pard\\par\
}";

If you run this in Microsoft Word it will show dotted lines like it's supposed to. RichEdit does not handle dotted borders like it's supposed to, or maybe it's expecting a different format. If you save the file from Word, it still doesn't show dotted lines.

If you don't need dotted lines then use these simpler examples to show boxes in RichEdit:

CString str;
str = L"{\\rtf1\
\\trowd\\trgaph72 \
\\cellx3000 TEXT\\intbl\\cell \
\\row\\pard\\par\
}";

str = L"\
{\\rtf1\\ansi\\deff0\
\\trowd\
\\cellx1000\
\\cellx2000\
\\cellx3000\
\\ TEXT1\\cell\
\\ TEXT2\\cell\
\\ TEXT3\\cell\
\\row\
}";

See also link

Note, CRichEditCtrl::SetWindowText will simply call ::SetWindowText WinAPI, it will set the string as plain text.

Use CRichEdit::StreamIn to set raw rtf string. In your case you are probably using your own class which overrides CRichEditCtrl::SetWindowText and runs the necessary streaming.


Try the following to get rtf string from Word's spell check RichEdit:
DWORD __stdcall rtfstreamget(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
    CStringA text;
    text.GetBufferSetLength(cb);
    CStringA *ptr = (CStringA*)dwCookie;
    for(int i = 0; i < cb; i++)
        text.SetAt(i, *(pbBuff + i));
    *ptr += text;
    *pcb = text.GetLength();
    text.ReleaseBuffer();
    return 0;
}

bool GetRTF(hWnd, CString &sW)
{
    CStringA sA;
    EDITSTREAM es{ 0 };
    es.dwCookie = (DWORD_PTR)&sA;
    es.pfnCallback = rtfstreamget;
    edit.StreamOut((CP_UTF8 << 16) | SF_USECODEPAGE | SF_RTF, es);
    SendMessage(hWnd, EM_STREAMOUT, 
            (CP_UTF8 << 16) | SF_USECODEPAGE | SF_RTF, (LPARAM)&es);
    sW = CA2W(sA, CP_UTF8);
    return es.dwError == 0;
}

CStringW s;
GetRTF(msword_spellcheck_hwindow, str);
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • Barmak, thank you for so detailed answer. "You can display tables and borders with rich edit." Yes, I know I can, but I dont want to pollute text with my own additions. Let me clarify a bit, I am writing an office addin, and what I want is to take a chunk of text from Word, present it to user through richedit control, and, after some modifications made by user, bring it back to Word. Something like spell check dialog in MSWord 2010. And it is a pity, that not all formatting can be safely transferred in such a way, as I understand from your answers. – vtrz Oct 14 '17 at 15:21
  • I don't know what you are describing. Maybe you can post a screenshot in your question that shows Word spell check. – Barmak Shemirani Oct 14 '17 at 15:35
  • I have added the screenshot to the question. – vtrz Oct 14 '17 at 16:05
  • 1
    Maybe Microsoft Word is adding custom draw to RichEdit, that would be a dead end for us, so to speak. Otherwise you could use `CRichEdit::StreamOut` on Word's Spellcheck `HWND` to steal the raw rtf string which is being used in Word. Maybe there is something special in that rtf string. Or copy/paste from Word's RichEdit window to WordPad. – Barmak Shemirani Oct 14 '17 at 23:28
  • Have tried copy-paste from Word to Wordpad - and Wordpad hides borders just like discussed CRichEditCtrl-based dialog. – vtrz Oct 15 '17 at 19:33
  • Find the `HWND` of MS spell check and use `GetRTF` (see updated answer) to get the rtf source. That's a long shot though. – Barmak Shemirani Oct 16 '17 at 22:22
  • The code returns an empty string in my case. [Here](https://stackoverflow.com/questions/21961826/winapi-em-streamout-crash) it is mentioned that EM_STREAMOUT won't work across a process boundary - may be than is the reason? On the other hand I have tried to get spellcheck's rtf via clipboard viewer, and it shows that original border tags are presented (though with a huge additional formatting). – vtrz Oct 24 '17 at 11:48
  • Sorry, my last suggestion was a waste of time. The two processes don't share the same memory so that was never going to work. I'll try to hack at this later see where it goes. – Barmak Shemirani Oct 25 '17 at 08:42