Неверное отображение отдельных символов или несовпадение кодовых страниц
Довольно часто в конференции возникает вопрос о том, что отдельные буквы русского языка отображаются неверно. Ниже приведены 2 строки символов. Первая - это русские буквы, а вторая - это то как они отображаются в программе.
абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
абвaде,жзийклмнопdстуфoцчoщъыьy_яAAAAДЕ"ЖЗEЙEEIIIIDСOOOOЦxOUUUЬY_Я
Если Вы нашли совпадение с Вашей проблемой, то эта статья для Вас.
Проблема эта носит название "несовпадение кодовых страниц". Первая строка в приведенном примере написана в кодовой странице 1251(Win Rus), а вторая получена конвертацией ее в кодовую страницу 1252(Win USA). Практически каждый программист на FoxPro пишущий не для англоязычных пользователей рано или поздно, но обязательно с ней сталкивается.
Причины возникновения этой ошибки можно разделить на несколько групп:
I - Нет каких-либо служебных файлов или библиотек
II - Не сделана нужная настройка среды FoxPro
III - У использованных файлов указана не та или вообще не указана кодовая страница
IV - Ошибки настройки операционной системы
Попробую разобрать причины возникновения этой ошибки по порядку.
I - Нет каких-либо служебных файлов или библиотек
До версии VFP5 включительно вместе с готовым EXE-файлом клентам необходимо было еще поставлять специальный служебный файл FOXPRO.INT
Этот файл указывал FoxPro как именно следует читать разные кодовые страницы. При его отсутствии FoxPro приходил в большое недоумение. Этот файл требуется класть рядом с готовым EXE. Причем именно "рядом". Включать его внутрь готового EXE - нельзя. Файл поставлялся вместе с FoxPro и лежал в его корневой директории.
Начиная с версии VFP6 надобность в этом файле отпала.
Можно вздохнуть с облегчением и выразить отдельную благодарность MicroSoft вообще и разработчикам VFP в частности. Останавливает меня только то, что была выпущена 7 версия FoxPro и по слухам аналогичные проблемы появились при создании дистрибутивов. Поскольку у меня нет 7 версии, то и не буду распространять слухи, подождем сервис паки и коментарии тех у кого он есть.
II - Не сделана нужная настройка среды FoxPro
Данная проблема связана с логикой работы FoxPro в отношении кодовых страниц. Дело в том, что по умолчанию, FoxPro не поддерживает автоматическую трансляцию символьных и мемо-полей. Более того, не поддерживается трансляция и откомпилированных текстовых файлов (FXP, TXT).
Если ваш проект был создан в системе с той же кодовой страницей, что и у клиента, то вы и не заметите разницы. Поскольку если автоматическая трансляция в FoxPro не была включена, то FoxPro будет предполагать, что все данные следует отображать в текущей кодовой странице системы. Исключением в этом смысле является VFP7 - тут разница будет заметной (с MicroSoft - не соскучишся).
Включить автоматическую трансляцию символьных данных можно одним единственным способом. Для этого требуется создать обычный текстовый файл с именем CONFIG.FPW и вписать в него следующую строчку
CODEPAGE=1251
Эта строка имеет 2 смысла:
-) Сам факт наличия ключевого слова "CODEPAGE" для FoxPro является признаком того, что следует включить автоматическую трансляцию кодовых страниц.
-) Значение правой части указывает в какой кодовой странице следует читать текстовые данные, если признак кодовой страницы явно не указан. А также, в какой кодовой странице следует создавать новые файлы, если кодовая страница не указана явно.
В руководстве по FoxPro рекомендуют писать строку
CODEPAGE=AUTO
Однако, проблема заключается в том, что если ваш проект предполагает создание новых файлов, то при указании ключевого слова AUTO, вместо номера кодовой страницы все эти новые файлы будут создаваться в текущей кодовой странице системы. А она может быть отлична от 1251.
Строго говоря, как уже было сказано, наличие этой настройки в большинстве случаев не обязательно. Однако, ее отсутсвие будет заметно если:
-) Вы работаете со старыми DOS таблицами в 866 кодовой странице
-) У клиентов в системе текущей кодовой страницей не является 1251
-) Вы работаете в VFP7
Остановлюсь немного на последнем пункте. Если до выхода 7 версии предполагалось, что при отсутствии явного указания на автоматическую трансляцию кодовых страниц следует брать кодовую страницу системы, то в откомпилированном EXE файле версии VFP7 по видимому предполагается, что надо брать кодовую страницу 1252 вне зависимости от кодовой страницы системы.
В отличии от файла FOXPRO.INT, файл CONFIG.FPW можно включать в проект и не поставлять отдельно от готового EXE. Следует только помнить, что настройки файла конфигурации устанавливаются один раз при запуске среды FoxPro. Это значит, что после запуска среды FoxPro никакие изменения в файле конфигурации не приведут к изменению настроек среды FoxPro. Необходимо будет перезагрузить FoxPro.
Подключить файл конфигурации на этапе разработки можно таким образом:
"C:Program FilesMicrosoft Visual StudioVfp98VFP6.EXE" -C"C:MyProjectsProject1config.fpw"
Ключ "-C" указывает, что следом за ним стоит имя файла конфигурации, который следует использовать при запуске FoxPro. Строго говоря, в данном случае имя файла конфигурации может быть абсолютно любым, но лучше придерживаться принятых наименований. Идеальным вариантом является создание ярлыка на рабочем столе, для запуска своего проекта.
Для готового EXE-файла достаточно просто положить файл CONFIG.FPW в ту же директорию, где находится и сам EXE-файл.
Подробнее о других способах использования файла конфигурации и различных настройках, которые можно сделать через него, читайте в руководстве к FoxPro.
Для наиболее любознательных:
-)Можно сделать настройку кодовой страницы и в системном реестре Windows. Для этого следует в
HKEY_CURRENT_USERSoftwareMicrosoftVisualFoxPro6.0Options
Создать дополнительный строковый параметр CodePage и присвоить ему значение 1251.
-)Отменить автоконвертацию некоторых полей таблицы можно используя настройку SET NOCPTRANS. Это имеет смысл для полей типа Binary, где конвертация все-равно ничего не даст.
III - У использованных файлов указана не та или вообще не указана кодовая страница
Причины установки неверной кодовой страницы может быть 2:
-) При создании файла не было файла конфигурации CONFIG.FPW со строкой CODEPAGE=1251. В этом случае все новые файлы будут созданы в кодовой странице операционной системы.
-) Файлы, использованные в проекте были скопированы из других источников. Например, все файлы стандартных примеров Solution.pjx и TasTrade.pjx созданы в кодовой странице 1252.
Посмотреть кодовые страницы всех файлов включенных в проект можно через пункт главного меню Project->Project Info->закладка Files
Изменить кодовую страницу текстовых файлов (TXT,PRG,QPR) можно там же, щелкнув правой клавишей мыши на нужном файле и выбрав в появившемся меню пункт CodePage.
Прочие файлы, входящие в проект (формы, классы, отчеты) по своей сути являются обычными DBF-таблицами. Для изменения их кодовых страниц вместе с FoxPro поставляется специальная программа CPZERO.PRG. Эта программа расположена в (корневая директория FoxPro)TOOLSCPZERO
Для изменения кодовых страниц следует дать команду
DO CPZERO.PRG WITH "MyForm.SCX",1251
DO CPZERO.PRG WITH "MyClass.VCX",1251
DO CPZERO.PRG WITH "MyMenu.MNX",1251
DO CPZERO.PRG WITH "MyProject.PJX",1251
DO CPZERO.PRG WITH "MyBase.DBC",1251
В данном случае, указывать расширение файлов необходимо.
Отдельно, следует сказать о поддержке таблиц, созданных в FoxPro for DOS. В те далекие времена (уж лет 5 тому) кодовая страница или вообще не использовалась или использовалась 866 кодовая страница.
В файлах созданных в FPD2.0 по умолчанию кодовая страница вообще не указывалась. Для таких файлов следует устанавливать кодовую страницу 866. На работу старых DOS-приложений это никак не повлияет, но в VFP информация будет отображаться как надо.
Если в вашем проекте используются таблицы в 866 кодовой странице, то наличие файла конфигурации CONFIG.FPW со строкой CODEPAGE=1251 становится просто необходимым.
Для проверки текущей кодовой страницы DBF-таблиц можно воспользоваться функцией CPDBF()
IV - Ошибки настройки операционной системы
Ну вот, дошли до любимых всеми программистами ошибок настроек операционной системы. Как правило, о них вспоминают или в первую или в последнюю очередь. Это ошибки связаны с тем, что по умолчанию операционная система в некоторых случаях считает, что отдельные объекты проекта или весь проект написан в кодовой странице 1252.
Для исправления этого недоразумения проще всего велеть системе несмотря на то, что она считает что что-то имеет кодовую страницу 1252 обрабатывать это что-то как имеющую кодовую страницу 1251. Т.е. надо влезть в системный реестр и поменять все ссылки с 1252 на 1251. К сожалению, я не могу указать полный перечень адресов, где такая замена необходима. Единственный обязательный адрес это:
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNlsCodePage]
"1252"="c_1251.nls"
Эта ошибка характерна для отображения данных в ActiveX компонентах, если проект был создан в Win9x, а готовый EXE запускается в среде WinNT, WinXP или Win2000
Вот, кажется, и все. Буду рад любым замечаниям и дополнениям.