2009-11-23 6 views
8

У меня возникли проблемы с получением элемента управления RichEdit для отображения текста в формате Unicode RTF. Мое приложение - Unicode, поэтому все строки - строки wchar_t.
Если я создаю элемент управления как «RichEdit20A», я могу использовать, например. SetWindowText, и текст отображается с правильным форматированием. Если я создам элемент управления как «RichEdit20W», то с помощью SetWindowText будет отображаться текст дословно, т. Е. Отображается весь RTF-код. То же самое происходит, если я использую параметр EM_SETTEXTEX, указав кодовую страницу 1200, которую MSDN говорит мне, используется для обозначения unicode.
Я попытался использовать функцию StreamIn, но это, похоже, работает, если я передаю текст ASCII. Если я поточу в широкоформатных сетях, тогда я получаю пустой текст в элементе управления. Я использую флаги SF_RTF | SF_UNICODE, а MSDN намекает, что эта комбинация не может быть разрешена.Текст Unicode RTF в RichEdit

А что делать? Есть ли способ получить широкие диаграммы в RichEdit без потери интерпретации RTF или мне нужно его закодировать? Я думал о попытке UTF-8, или, возможно, использовать средства кодирования в RTF, но я не уверен, что лучший выбор.

ответ

10

Я должен был сделать это недавно и заметил те же самые наблюдения, которые вы делаете.

Кажется, что, несмотря на то, что MSDN почти предполагает, парсер «RTF» будет работать только с 8-битными кодировками. Итак, в итоге я использовал UTF-8, который представляет собой 8-битную кодировку, но все же может представлять весь спектр символов Юникода. Вы можете получить UTF-8 из PWSTR через WideCharToMultiByte():

PWSTR WideString = /* Some string... */; 
DWORD WideLength = wcslen(WideString) + 1; 
PSTR Utf8; 
DWORD Length; 
INT ReturnedLength; 

// A utf8 representation shouldn't be longer than 4 times the size 
// of the utf16 one. 
Length = WideLength * 4; 
Utf8 = malloc(Length); 
if (!Utf8) { /* TODO: handle failure */ } 

ReturnedLength = WideCharToMultiByte(CP_UTF8, 
            0, 
            WideString, 
            WideLength-1, 
            Utf8, 
            Length-1, 
            NULL, 
            NULL); 
if (ReturnedLength) 
{ 
    // Need to zero terminate... 
    Utf8[ReturnedLength] = 0; 
} 
else { /* TODO: handle failure */ } 

После того как вы его в UTF-8, вы можете сделать:

SETTEXTEX TextInfo = {0}; 

TextInfo.flags = ST_SELECTION; 
TextInfo.codepage = CP_UTF8; 

SendMessage(hRichText, EM_SETTEXTEX, (WPARAM)&TextInfo, (LPARAM)Utf8); 

И конечно же (я оставил это из первоначально, но в то время как я быть явно ...):

free(Utf8); 
+0

Работает отлично. Большое спасибо! – 2009-11-23 12:06:12

1

RTF является ASCII, любой Charactor из ASCII будет кодироваться с использованием последовательности. RTF 1.9.1 specification (March 2008)

+0

Спецификация формата файла может сказать это, но вы можете получить элемент управления RichEdit для загрузки RTF с любой многобайтовой кодировкой, включая CP_UTF8, как показано в моем ответе. – asveikau

1

Посмотрите на \ Унах буквальный в спецификации РТФА поэтому вы должны преобразовать широкую строку в строку символов Юникода, как \ u902? \ U300? \ U888? http://www.biblioscape.com/rtf15_spec.htm#Heading9 Номера в этом случае представляют десятичный код символов, а знак вопроса - символ, который заменит символ юникода в случае, если RichEdit не поддерживает unicode (RichEdit v1.0).

Например, для строки unicode L "TIME" данные rtf будут "\ u84? \ U73? \ U77? \ U69?"

+0

Его одно из решений, которое я успешно проверил, но не очень удобно. В этом случае строка rtf, например, «{\\ rtf1 bla bla \\ u931?}" (Синтаксис языка C++ используется для кодирования символов обратной косой черты), может быть закодирована в UTF-16 и будет корректно отображаться. При кодировании в UTF-16 напрямую (без управляющего слова \ uN), то есть «{\\ rtf1 bla bla Σ}", греческая буквенная сигма (код 0x03A3) будет отображаться как фунт £ (код 0xA3). – truthseeker

Смежные вопросы