Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 06.04.2021, 11:01
anna_sidorova anna_sidorova вне форума
Прохожий
 
Регистрация: 06.04.2021
Сообщения: 3
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Крякозябры вместо русских символов в Windows 10 - при опции Использовать Юникод

Здравствуйте!



Есть программный код на Delphi 7, нормально работает под Windows XP/Vista/7/8/8.1 и до определенных пор на Windows 10. Работает практически при любых языковых настройках - т. к. для борьбы с крякозябрами на англоязычных XP/7 использовала

SetThreadLocale(1049)
RUSSIAN_CHARSET - в кодировке компонентов, шрифт Arial вместо стандартного MS Sans Serif
и прочие ухищрения, что нашла в Сети - таким образом, добилась того, что всё нормально работает практически под любой Windows - при любых языковых настройках (даже если англоязычная Windows и основной язык - французский)

Однако, в последних версиях Windows 10 в языковых настройках появилась опция

"Бета-версия: Использовать Юникод (UTC-8) для поддержки языка во всем мире"/"Use Unicode UTF-8 for worldwide language support" - которая в некоторых случаях включена по умолчанию (кроме того, после её отключения - чтобы изменения вступили в силу - компьютер нужно перезагружать). Если эта опция включена - в программе вместо русских букв отображаются крякозябры и никакие ухищрения не помогают это исправить - кроме отключения данной галочки. Мне нужно - чтобы программа нормально отображала русские буквы - независимо от состояния данной галочки.

Как я понимаю (возможно, ошибаюсь) - нужно как-то перехватывать WinAPI-метод из Kernel32.dll GetACP. В нормальном состоянии эта функция должна возвращать 1251. Она и возвращает 1251 в том числе на Windows 10 - при отключении этой галочки. При включении галочки данная функция возвращает 65001 и программа отображается с крякозябрами.

Что пробовала:

1) Перехват функции GetACP - с помощью сплайсинга. Запускаю программу под отладчиком, нахожу адрес процедуры GetACP - в начало этого кода ставлю jmp на свою, правильную функцию, которая возвращает требуемое значение 1251.

Результат такой - всё хорошо, функция GetACP теперь возвращает правильное значение 1251 (вместо 65001) - однако, в программе вообще ничего не меняется. Всё равно всё отображается с крякозябрами.

2) Пыталась использовать недокументированную функцию

SetCPGlobal(1251);

После этого GetACP возвращает правильное значение. Проблема только в том, что работает эта недокументированная функция только на Windows XP - но на XP и без неё всё нормально работает. На Windows 7 и Windows 10 - при попытке использовать данную функцию - при запуске программы выходит сообщение

Точка входа в процедуру SetCPGlobal не найдена в библиотеке Kernel32.dll

и программа завершает свою работу

3) Пыталась найти - где же функция GetACP получает значение 65001 - чтобы прописать по этому адресу 1251 (как говорят на форумах, это адрес переменной gAnsiCodePage в модуле KernelBase.dll). Нашла адрес - область, откуда берётся это значение, там как раз записано значение 65001. Перезаписываю данную область памяти в значение 1251 с помощью ассемблерной вставки - после этого функция GetACP возвращает значение 1251. На Windows 7:

..............................
MyGetACP := GetProcAddressInDll('KernelBase.dll', 'GetACP');
z := ReadMemoryDword(1+integer(Addr(MyGetACP)));
WriteMemoryDword(z, 1251); //rewrite value of variable - where keeping GetACP
ShowMessage('GetACP: '+inttostr(GetACP)) //на Windows 7 работает
..............................

На Windows 10 же (где и требуется решить вопрос с крякозябрами) получается совсем по-другому. Как только пытаюсь перезаписать значение данной ячейки в 1251 - тут же появляется ошибка

Exception EAccessViolation in module KernelBase.dll at 000F69ED. Access violation at address 76D269ED in module 'KernelBase.dll'. Read of address 00000002.

и программа вылетает. При этом перезапись ячейки памяти делаю как полагается - перед перезаписью устанавливаю признак PAGE_EXECUTE_READWRITE для перезаписываемой области памяти: VirtualProtect(pointer(a), 16, PAGE_EXECUTE_READWRITE, OldProtect)

Пробовала в качестве экспериментов записывать в эту ячейку значения 1252, 65001 (то есть исходное значение) и даже 9999 - всё отрабатывает нормально (но потом в ходе работы программы возникают ошибки). Если же записать 1251 - программа вылетает сразу.


Возникает вопрос - что делать, чтобы программа работала на Windows 10 без крякозябр вместо русских букв при включенной опции "Бета-версия: Использовать Юникод (UTC-8) для поддержки языка во всем мире". Варианты перейти с Delphi 7 на другую, более новую версию - не предлагать (очень много старого кода придётся переписывать, который при переписывании может начать глючить и т. д.) Варианты с TntComponents и JEDI тоже не подойдут - т. к. программа содержит гигантское количество старого программного кода - где используются стандартные компоненты TLabel, TButton, TEdit - даже если новый код писать на JEDI - надо чтобы старый код и старые формы работали без крякозябр.

Как правильно перехватить GetACP, чтобы она всегда возвращала значение 1251? Как заставить программу работать без крякозябр? Дело ведь в GetACP - туда надо копать или в чем можем быть дело?



С уважением, Сидорова А. П.

Последний раз редактировалось anna_sidorova, 06.04.2021 в 11:03.
Ответить с цитированием
  #2  
Старый 06.04.2021, 23:00
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,003
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А попробовать скомпилить на более новой версии Delphi, которая изначально поддерживает юникод, нельзя? Просто в рамках эксперимента...

ЗЫ. Можно бесплатно скачать Community Edition с сайта Абракадабры, это аналог Professional.
Ответить с цитированием
  #3  
Старый 06.04.2021, 23:33
anna_sidorova anna_sidorova вне форума
Прохожий
 
Регистрация: 06.04.2021
Сообщения: 3
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
А попробовать скомпилить на более новой версии Delphi, которая изначально поддерживает юникод, нельзя? Просто в рамках эксперимента...

ЗЫ. Можно бесплатно скачать Community Edition с сайта Абракадабры, это аналог Professional.

Похоже, придётся, хотя очень не хочется. Сначала думаю с Delphi 7 перейти на Delphi 2010 (первая из Unicode-версия, не считая 2009 - но 2009 судя по тому, что пишут в Сети - очень глючная). А потом уже, возможно переходить на XE10 или просто остаться на Delphi 2010. Сразу перейти на XE10 не получается - даже не компилируется, на XE8 после долгих мучений удалось скомпилировать еще в 2017 - но увидев количество глюков испугалась и решила остаться на Delphi 7. Хотелось бы, конечно, вообще остаться на Delphi 7 - т. к. полагаю, что даже переход на 2010 чреват большим количеством глюков, недовольств пользователей и бессонных ночей ...
Ответить с цитированием
  #4  
Старый 06.04.2021, 23:49
Vladimr Vladimr вне форума
Прохожий
 
Регистрация: 17.03.2021
Сообщения: 41
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

А пробовали вариант изменить язык не Юникод приложений через панель управления на русский (Панель управления->Региональные стандарты->Дополнительно->Язык программ не поддерживающий Юникод)?

Если и этот вариант не помог, то можно попробовать сменить кодировку через реестр.

Так как в правилах форума явно не указан запрет на ссылки внешних сайтов, то на свой страх и возможность получить предупреждение, дам вам ссылку на статью https://remontka.pro/fix-cyrillic-windows-10/ . Вдруг вам поможет.
Ответить с цитированием
  #5  
Старый 07.04.2021, 00:29
anna_sidorova anna_sidorova вне форума
Прохожий
 
Регистрация: 06.04.2021
Сообщения: 3
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Vladimr
А пробовали вариант изменить язык не Юникод приложений через панель управления на русский (Панель управления->Региональные стандарты->Дополнительно->Язык программ не поддерживающий Юникод)?

Если и этот вариант не помог, то можно попробовать сменить кодировку через реестр.

Так как в правилах форума явно не указан запрет на ссылки внешних сайтов, то на свой страх и возможность получить предупреждение, дам вам ссылку на статью https://remontka.pro/fix-cyrillic-windows-10/ . Вдруг вам поможет.

Вероятно, Вы не поняли вопрос. В описании вопроса как раз и указано - что при изменении галочки указанным способом всё работает. Через реестр тоже работает (если написать REG-файл). В обоих случаях для вступления изменений в силу требуется перезагрузка компьютера.

Но задача именно в том - чтобы программа работала корректно без изменения системных настроек. И тем более более без необходимости перезагрузки компьютера. Чтобы пользователь с Windows, в котором проблемная галочка включена - устанавливал программу, запускал и видел нормальный текст вместо крякозябр.
Ответить с цитированием
  #6  
Старый 07.04.2021, 23:24
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,003
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от anna_sidorova
Похоже, придётся, хотя очень не хочется. Сначала думаю с Delphi 7 перейти на Delphi 2010 (первая из Unicode-версия, не считая 2009 - но 2009 судя по тому, что пишут в Сети - очень глючная). А потом уже, возможно переходить на XE10 или просто остаться на Delphi 2010. Сразу перейти на XE10 не получается - даже не компилируется, на XE8 после долгих мучений удалось скомпилировать еще в 2017 - но увидев количество глюков испугалась и решила остаться на Delphi 7. Хотелось бы, конечно, вообще остаться на Delphi 7 - т. к. полагаю, что даже переход на 2010 чреват большим количеством глюков, недовольств пользователей и бессонных ночей ...

Бери последнюю (ну не самую, а ту, которая Comunity Ed), там, вроде, особо глюков не замечено (есть, конечно, но не критично/редко встречается).
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:20.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter