Delphi 7 - Почему Windows 7 изменяет кодирование символов во времени выполнения?

У меня есть Дельфи 7 форм:

Form

и мой код:

Code

когда я выполняю эту форму в Windows 7, я вижу:

Windows7Form

Во время проектирования форма имела буквы полировки в первой маркировке, но она не имеет их во времени выполнения. Это смотрит хорошо на Vista или Windows XP. Когда я установил подпись второй маркировки в коде, все хорошо работает, и символы правильно кодируются.

Сначала 5 кодов вершины маркируют на Windows 7: 65 97 69 101 83

Сначала 5 кодов вершины маркируют на Windows Vista / XP: 165 185 202 234 140

Сначала 5 кодов нижней части маркируют в каждой системе: 165 185 202 234 140

Кодирование изменений Windows 7, почему? Мои параметры настройки системы, кажется, в порядке. Мне установили надлежащий язык для non-unicode приложений в панели управления.

Править

Эта проблема не только связана с маркировками на формах, но также и с FastReport (где переключение на EASTERN_CHARSET разрешает проблему), или с доступом к Microsoft Excel через COM-интерфейс.

6
задан Glorfindel 10 July 2019 в 04:04
поделиться

4 ответа

Ответы на этот вопрос решают мою проблему:

GetThreadLocale возвращает значение, отличное от GetUserDefaultLCID?

Одно решение:

Мы обнаружили странную вещь: переключение на другие региональные настройки через панель управления и последующее переключение обратно в NZ решает проблему. Мне было бы любопытно узнать, разрешит ли один и тот же обходной путь вы, просто чтобы убедиться, что мы наблюдаем одно и то же явление.

и второй:

initialization
  SetThreadLocale(LOCALE_USER_DEFAULT);
  GetFormatSettings;

Оба решения работают отлично, и проблема с приложением исчезает .

1
ответ дан 17 December 2019 в 04:44
поделиться

Проверьте свойство Font.Charset метки. Хотя я не знаю, как он был изменен (он был предварительно создан для какого-то мастера?), Но он может иметь другой язык, чем системный.

0
ответ дан 17 December 2019 в 04:44
поделиться

Я воспроизвел поведение Delphi 2010 в win XP.

procedure Button1Click(Sender : TObject);
begin
  ShowMessage(AnsiString(Label1.Caption));
end;

В этой ситуации преобразование Label1.Caption в AnsiString выполняется с помощью WideCharToMultiByte (Windows API).

API содержит следующее примечание:

Кодовые страницы ANSI могут быть разными на разных компьютерах или могут быть изменены для одного компьютера, что приведет к повреждение данных. Для получения наиболее согласованных результатов приложения должны использовать Unicode, например UTF-8 или UTF-16, вместо страницы с определенным кодом , за исключением устаревших стандарты или форматы данных не позволяют использовать Unicode. Если использование Unicode невозможно, приложения должны пометить поток данных соответствующим именем кодировки , если это разрешено протоколами. Файлы HTML и XML допускают тегирование, а текстовые файлы - нет.

Итак, я могу предположить, что разница в поведении проистекает из того факта, что у вашей версии Windows 7 активная кодовая страница отличается от кодовой страницы на ваших станциях Vista / XP.

Мне все еще нужно найти, как получить активную кодовую страницу в системе ... Скорее всего, она определена в региональных настройках на панели управления. Но мне все еще нужно это проверить ...

2
ответ дан 17 December 2019 в 04:44
поделиться

Вы столкнулись с тем, что я считаю «ошибкой» в методах TWriter.WriteString и TWriter.ReadString. Эти два метода используются внутри Delphi для перемещения TLabel.Caption из реального живого объекта во время разработки в файл DFM, а затем обратно в живой объект во время выполнения.

Если вы посмотрите на код для упомянутых двух подпрограмм, вы заметите (я в шоке, я полагаю), что фактический материал, который поступает в поток, конвертируется в Unicode с использованием кодовой страницы операционной системы по умолчанию! Это нормально, пока кодовая страница, используемая на машине разработки, точно соответствует кодовой странице, используемой на тестовой машине, и они, вероятно, не совпадают, и, скорее всего, вы получаете ошибку. Обратите внимание, что EASTEUROPEAN_CHARSET, который вы устанавливаете для Caption в форме, не имеет абсолютно никакого значения, потому что метод TWriter.WriteString не знает об этом!

У меня есть отчет об ошибке по этой проблеме на QC, он был там много лет ... Они, вероятно, думают, что это «задумано», но я не думаю, что это очень хороший дизайн.

Я бы рекомендовал быстрое переключение на Delphi 2010. Я разработчик Delphi из Румынии, и у меня было много-много проблем с подобными вещами, но теперь все это в прошлом, потому что Delphi 2010 - это UNICODE, поэтому мне больше не нужно беспокоиться о преобразовании кодовых страниц.

Если вы не можете переключиться на Delphi 2010, вы можете «взломать» файл Classes.pas и изменить подпрограмму TReader.ReadString, чтобы преобразование всегда выполнялось с ВАШЕЙ кодовой страницей, а не с системной по умолчанию.

2
ответ дан 17 December 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: