Ранее Реймонд Чен писал о том, Как общие элементы управления конвертируют строки между ANSI и Unicode?, отвечая на вопрос в его suggestion box:
В контексте ansi (не unicode) приложения: как общие элементы управления (к примеру, listview) решают, какую использовать кодовую страницу для перевода многобайтовых строк в widestring?Хотя я редко, если вообще когда-нибудь, не соглашусь с чем-то, что исходит из лагеря команды Оболочки, конкретно в этом случае я знаю два конкретных исключения из правила CP_ACP, которое вы обычно видите, хотя эти отличия могут иметь мало общего с кодом Shell / comctl32, так что Реймонд может быть прав в своей области :-)
Мне пришлось отлаживать ansi приложение, которое показывало испорченные строки на системе с традиционным китайским, потому что шрифт диалога привёл к тому, что listview использовал иную кодовую страницу, нежели системную ACP, при переводи multibyte в widechar.
Вот два других поведения, с которыми я встречался в различных версиях общих элементов управления:
- Использование кодовой страницы потока (CP_THREAD_ACP)1.
- Использование кодовой страницы, ассоциированной с набором символов шрифта, выбранного в контекст устройства.
Насчёт второго случая у меня есть больше информации, поскольку мне приходилось отлаживать его несколько раз - в общем говоря, текст не всегда конвертировался в Unicode; и ANSI-текст отправлялся в GDI с DC, содержащим установленный шрифт, использующий другую кодовую страницу, отличную от CP_ACP. Тогда GDI будет выполнять свою работу по отрисовке текста и делать при этом свой выбор, как будто его об этом просили - в своей странной и не всегда понятной манере.
Как правило, каждй раз, когда команда GDI пытается залезть в область NLS, результаты получаются предсказуемыми - бажный код, всегда. Отсюда мы имеем проблемы вроде тех, что я указал здесь. Между этой проблемой и проблемой, обсуждаемой здесь и здесь, ясно одно: ребятам из GDI следует подумать, не зайти ли им в гости к команде NLS и не натянуть ли им всем трусы.
Просто шучу, но вы знаете, что я имел в виду.
Для общих элементов управления же, когда я работал над MSLU, я встречался со случаями, когда мне приходилось использовать код вроде такого, чтобы всё работало:
function CpgFromHdc(dc: HDC): UINT; var chs: Cardinal; csi: TCharsetInfo; begin chs := GetTextCharset(dc); if TranslateCharsetInfo(chs, csi, TCI_SRCCHARSET) then Result := csi.ciACP else Result := g_acp; end;Так что, в любом случае, правило с CP_ACP должно быть единственным, но в Windows есть слишком много кусков кода, которые думают, что они лучше знают, что использовать...
С другой стороны, как и я - UNICODE! :-)
1 - Теперь вы знаете, что я чуствую насчёт этого, если вы читали Ничто не пахнет хуже локали потока, чем кодовая страница потока. Я думаю, что я тогда достаточно прямолинейно сказал.
This blog brought to you by ਸ਼ (U+0a36, aka GURMUKHI LETTER SHA)
Комментариев нет:
Отправить комментарий
Можно использовать некоторые HTML-теги, например:
<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>
Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.
Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.
Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.
Примечание. Отправлять комментарии могут только участники этого блога.