Страница 1 из 2
Хвалёный Уникод не работает
Добавлено: 11 авг 2009, 16:38
programisto
Текст в Уникоде отображается в Комбобоксе и Ричедите неправильно. Combobox съедает значки над буквами, а Richedit заменяет нетривиальные буквы вопросительными значками. Английские буквы отображаются правильно. TextOutW отображает весь текст правильно.
Re: Хвалёный Уникод не работает
Добавлено: 11 авг 2009, 17:58
Decoder
Наверно caм что-то делаешь неправильно.
Re: Хвалёный Уникод не работает
Добавлено: 11 авг 2009, 19:36
Eugie
Чтобы контролы правильно отрисовывали Unicode-строки, должны выполняться несколько условий:
- версия ОС должна поддерживать Unicode (для современных версий Windows выполняется автоматически);
- само приложение должно быть скомпилировано с поддержкой Unicode (это важно, т.к. почти все функции WinAPI, принимающие строки в качестве параметров, существуют в 2 версиях - ANSI и WideChar(Unicode) - вот почему, кстати, TextOutW работает нормально);
- шрифт контрола должен поддерживать соответствующий набор символов. Например, по умолчанию часто используется растровый MS Sans Serif - естественно, не стоит ждать, что он корректно отобразит иероглифы

Re: Хвалёный Уникод не работает
Добавлено: 11 авг 2009, 19:48
programisto
Decoder писал(а):Наверно caм что-то делаешь неправильно.
Вот и хочу знать, что я делаю неправильно.
Пишу командой SendMessageW.
Что ещё нужно для счастья?
Re: Хвалёный Уникод не работает
Добавлено: 11 авг 2009, 20:01
Eugie
Re: Хвалёный Уникод не работает
Добавлено: 11 авг 2009, 20:07
programisto
Eugie писал(а):Чтобы контролы правильно отрисовывали Unicode-строки, должны выполняться несколько условий:
- версия ОС должна поддерживать Unicode (для современных версий Windows выполняется автоматически);
- само приложение должно быть скомпилировано с поддержкой Unicode (это важно, т.к. почти все функции WinAPI, принимающие строки в качестве параметров, существуют в 2 версиях - ANSI и WideChar(Unicode) - вот почему, кстати, TextOutW работает нормально);
- шрифт контрола должен поддерживать соответствующий набор символов. Например, по умолчанию часто используется растровый MS Sans Serif - естественно, не стоит ждать, что он корректно отобразит иероглифы
Работаю в Висте.
Программа на Ассемблере. Пользуюсь правильной функцией для вывода -
SendMessageW.
А почему Sans Sherif не отобразит иероглифы? Для Sans Sherif Уникод другой?
Иероглифы мне рисовать и не нужно, только несколько европейских
кодировок да кириллицу.
Как сменить фонт? Я пытался в комбобоксе применять следующие эвиваленты команд C:
hDC = GetDC(hComboBox);
SelectObject(hDC, hFont);
Причём hFont применялся в других объектах и работает правильно (в том числе правильно пишет Уникод). Но в комбобоксе ничего не изменилось - ни фонт, ни отображение Уникода.
Re: Хвалёный Уникод не работает
Добавлено: 12 авг 2009, 00:29
WinMain
Как сменить фонт? Я пытался в комбобоксе применять следующие эвиваленты команд C:
hDC = GetDC(hComboBox);
SelectObject(hDC, hFont);
Это неправильно.
Передавать окну значение hFont нужно через сообщение WM_SETFONT.
SelectObject(hDC, hFont); нужно применять лишь в том случае, когда ты сам выполняешь отрисовку данного контрола в обработчике сообщения WM_PAINT.
Re: Хвалёный Уникод не работает
Добавлено: 12 авг 2009, 08:58
Decoder
Здесь ещё играет роль кодировка самой строки.
Если в С++ написать код:
то компилятор сам преобразует данную строку в кодировку UNICODE.
Если строка изначально была представлена как массив однобайтовых символов, то её нужно будет преобразовать в UNICODE с помощью функции MultibyteToWideChar. Причём исходная строка должна быть записана в кодировке Windows-1251, а не в кодировке OEM (DOS-866). Вполне возможно что исходный текст программы был набран в кодировке OEM (если код писался не в Visual Studio, а в другом редакторе).
Re: Хвалёный Уникод не работает
Добавлено: 12 авг 2009, 11:38
Eugie
А почему Sans Sherif не отобразит иероглифы? Для Sans Sherif Уникод другой?
Дело в том, что растровые шрифты не поддерживают Unicode. Они разработаны для 8-битной кодировки символов, поэтому никак не могут отображать полный набор Unicode. Грубо говоря, растровый шрифт - это набор битмапов для какого-то конкретного набора символов (character set), причем не более 255. Современные шрифты TrueType и OpenType - это скорее программа на спец. языке, каждый символ представляет что-то типа метафайла для отрисовщика. Такая технология позволяет "красиво" масштабировать шрифт, вращать и т.д. - короче, делает его device independent. И главное, в контескте вашего вопроса, снимает ограничение на размер набора символов. Но из практических соображений даже TT/OT шрифты не поддерживает полный набор символов Unicode. Запустите замечательную программу "Таблица символов" и поиграйтесь с параметрами Набор символов и Группировка - увидите сами.
Если вам достаточно только кириллицы и расширенного набора латиницы с диакритическми знаками, вам подойдет практически любой TT/OT шрифт.
Как сменить фонт?
Собственно,
WinMain ответил. Могу только добавить, что если контролы лежат на диалоговом окне, для которого установлены стили DS_SETFONT либо DS_SHELLFONT, оно само рассылает сообщение WM_SETFONT дочерним окнам, используя шрифт, указанный в секции FONT шаблона диалога (обычно это системный растровый шрифт). В этом случае нужно устанавливать нужный шрифт для контрола в обработчике сообщения WM_INITDIALOG.
Еще совет: не пытайтесь самостоятельно обрабатывать WM_PAINT для стандартных контролов. Не буду объяснять почему, просто поверьте на слово

Re: Хвалёный Уникод не работает
Добавлено: 12 авг 2009, 12:23
programisto
Прочитал первую ссылку. Заменил класс "RichEdit20A" на "RichEdit20W" - ничего не изменилось.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Decoder писал(а):Здесь ещё играет роль кодировка самой строки.
Если в С++ написать код:
то компилятор сам преобразует данную строку в кодировку UNICODE.
Если строка изначально была представлена как массив однобайтовых символов, то её нужно будет преобразовать в UNICODE с помощью функции MultibyteToWideChar. Причём исходная строка должна быть записана в кодировке Windows-1251, а не в кодировке OEM (DOS-866). Вполне возможно что исходный текст программы был набран в кодировке OEM (если код писался не в Visual Studio, а в другом редакторе).
Я явно преобразовывал при помощи MultibyteToWideChar. Переводилось правильно, так как TextOutW выводит правильно. Программа новая, не набиралась в ДОСе.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
WinMain писал(а):Это неправильно.
Передавать окну значение hFont нужно через сообщение WM_SETFONT.
SelectObject(hDC, hFont); нужно применять лишь в том случае, когда ты сам выполняешь отрисовку данного контрола в обработчике сообщения WM_PAINT.
WM_SETFONT правильно устанавливает фонт. Однако выводится Уникод всё равно неправильно, съедает значок над буквой. Тот же фонт при помощи TextOutW выводится правильно.