Локализация интерфейса в приложениях Windows
Дата: 29 апреля 2009 года
Довольно часто возникает необходимость в разработке пользовательского интерфейса приложения с поддержкой разных национальных языков. Каждый производитель <многонационального> программного продукта по-своему решает эту задачу. Например, корпорация Microsoft просто выпускает отдельную локальную версию продукта для каждого поддерживаемого языка. Другие производители обычно в состав программного продукта включают набор файлов, содержащих текстовые сообщения для разных языков, а пользователь потом сам выбирает для работы приложения тот язык, который ему больше подходит.
Я могу предложить свой оригинальный вариант создания приложения с поддержкой многоязычного интерфейса без дополнительного набора отдельных файлов под каждый язык. Данное решение реально применяется в крупном проекте, в котором присутствует около сотни разных визуальных форм в виде диалоговых панелей, а так же меню и стандартные окна сообщений.
По какому принципу работает моё решение?
Само приложение разрабатывается под какой-то один конкретный язык, например английский. Разработанная мной библиотека функций содержит специальный код, который при запуске программы с определённым параметром в командной строке, перебирает все ресурсы приложения, содержащие текст, и записывает текстовые строки в один INI-файл с указанием идентификатора ресурса для каждой строки. Далее этот INI-файл редактируется, и текст каждой строки заменяется соответствующим текстом в переводе на другой язык. Далее приложение запускается и считывает из INI-файла текстовые строки для каждого элемента интерфейса. Таким образом, оригинальный текст элементов интерфейса меняется на тот текст, который записан в INI-файле.
Так выглядит оригинал приложения с англоязычным интерфейсом...
А это то же приложение, но в русскоязычной локализации...
Чтобы переключиться с одного языка на другой, необходимо через меню вызвать соответствующее окно диалога и выбрать нужный язык из числа представленных в списке.
При этом в INI-файле одновременно может содержаться несколько наборов текстовых строк для разных языков, а в меню главного окна программы добавляется пункт, который позволяет пользователю переключиться на один из нескольких языков, представленных в INI-файле.
Так выглядит описание текстовых ресурсов в INI-файле для английского языка:
[ENG:IDR_MAINFRAME] ID_FILE_NEW=&New Ctrl+N ID_FILE_OPEN=&Open... Ctrl+O ID_FILE_SAVE=&Save Ctrl+S ID_FILE_SAVE_AS=Save &As... ID_FILE_MRU_FILE1=Recent File $0:7=Localization ID_RESINI_CREATE=Create or Update ID_RESINI_ADDLANGUAGE=Add language... ID_RESINI_CHOICELANGUAGE=Select language... ID_APP_EXIT=E&xit ID_EDIT_UNDO=&Undo Ctrl+Z ID_EDIT_CUT=Cu&t Ctrl+X ID_EDIT_COPY=&Copy Ctrl+C ID_EDIT_PASTE=&Paste Ctrl+V ID_VIEW_TOOLBAR=&Toolbar ID_VIEW_STATUS_BAR=&Status Bar ID_APP_ABOUT=&About Localize... MAINMENU=&File;&Edit;&View;&Help $2:3=SubMenu $2:3:0=One ID_ONE_ITEM1=Item 1 ID_ONE_ITEM2=Item 2 ID_ONE_ITEM3=Item 3 ID_SUBMENU_TWO=Two ID_SUBMENU_THREE=Three $2:3:1=Two ID_TWO_ITEM4=Item 4 ID_TWO_ITEM5=Item 5 ID_TWO_ITEM6=Item 6 $2:3:2=Three ID_THREE_ITEM7=Item 7 ID_THREE_ITEM8=Item 8 ID_THREE_ITEM9=Item 9 [ENG:IDD_ABOUTBOX] CAPTION=About Localize IDC_STATIC_VERSION=Localize Version 1.0 IDC_STATIC_COPYRIGHT=Copyright (C) 2008 IDOK=OK [ENG:IDD_LOCALIZE_FORM] IDC_STATIC_TODO=TODO: Place form controls on thisdialog. IDC_BUTTON_FIRST=First IDC_BUTTON_SECOND=Second IDC_STATIC_GROUP=Edit group IDC_COPYRIGHT=Copyright (c) Vitaliy Rychkov IDC_BITMAP_BUTTON=IDB_BITMAP_EN А это описание тех же ресурсов, но для русского языка: [RUS:IDR_MAINFRAME] ID_FILE_NEW=&Создать Ctrl+N ID_FILE_OPEN=&Открыть... Ctrl+O ID_FILE_SAVE=&Сохранить Ctrl+S ID_FILE_SAVE_AS=Сохранить &как... ID_FILE_MRU_FILE1=Recent File $0:7=INI-файл ресурсов ID_RESINI_CREATE=Создать или обновить ID_RESINI_ADDLANGUAGE=Добавить локализацию... ID_RESINI_CHOICELANGUAGE=Выбор языка... ID_APP_EXIT=В&ыход ID_EDIT_UNDO=&Вставить Ctrl+Z ID_EDIT_CUT=Вы&резать Ctrl+X ID_EDIT_COPY=&Копирование Ctrl+C ID_EDIT_PASTE=&Вставка Ctrl+V ID_VIEW_TOOLBAR=&Панель инструментов ID_VIEW_STATUS_BAR=&Строка состояния ID_APP_ABOUT=&О программе... MAINMENU=&Файл;&Правка;&Вид;&Справка $2:3=Подменю $2:3:0=Один ID_ONE_ITEM1=Позиция 1 ID_ONE_ITEM2=Позиция 2 ID_ONE_ITEM3=Позиция 3 $2:3:1=Два ID_TWO_ITEM4=Позиция 4 ID_TWO_ITEM5=Позиция 5 ID_TWO_ITEM6=Позиция 6 $2:3:2=Три ID_THREE_ITEM7=Позиция 7 ID_THREE_ITEM8=Позиция 8 ID_THREE_ITEM9=Позиция 9 [RUS:IDD_ABOUTBOX] CAPTION=О программе IDC_STATIC_VERSION=Локализация версия 1.0 IDC_STATIC_COPYRIGHT=Разработка (C) 2008 IDOK=OK [RUS:IDD_LOCALIZE_FORM] IDC_STATIC_TODO=СЮДА: Разместить элементы формы на этом диалоге. IDC_BUTTON_FIRST=Первая IDC_BUTTON_SECOND=Вторая IDC_STATIC_GROUP=Группа редактирования IDC_COPYRIGHT=Автор (c) Виталий Рычков IDC_BITMAP_BUTTON=IDB_BITMAP_RU
Если данный INI-файл отсутствует в каталоге запуска программы, то программа использует тот интерфейс, который находится у неё в ресурсах, т.е. выглядит таким образом, как она была создана в оригинале.
Среди функций библиотеки по локализации приложения имеется функция загрузки строки из INI-файла с учётом выбранного языка. Тогда текст сообщения в окне диалога будет представлен на том языке, который выбран текущим.
Имеется так же возможность добавить в INI-файл другой язык (локализацию) из списка, представленного операционной системой Windows:
Для страниц свойств есть специальная функция, которая меняет текст закладок с учётом выбранного языка.
Примерно так будет выглядеть интерфейс приложения на белорусском языке:
Демонстрационный пример приложения можно загрузить отсюда: Localize.zip.
Оставить комментарий
Комментарии
А если хранить в ресурсах несколько вариантов для разных языков. ОС сама может выбирать нужные.
Такой вариант подходит для статических данных, которые не меняются в течение длительного времени. Например: название месяцев, дней недели, названия континентов, океанов, морей. Если же обычные меню и диалоговые окна для отдельно взятой программы размножить на несколько языков, то такой проект потом невозможно будет сопровождать. Каждое изменение нужно будет многократно дублировать в разных ресурсах. Это будет самым худшим вариантом.
это bmp 16х16x16 - изображение флага. Просто заметил что картинки RUEN грузятся из ресурса программы, а по идее должны быть автономны.
зы. А в виде dll не планируется?
Виталий Рычков:
Действительно, в данном случае рисунок грузится из ресурсов самого приложения.
Здесь получается некоторое расхождение с текстовыми ресурсами.
Можно конечно при выборе другого языка указывать путь к файлу с нужным рисунком,
но тогда получается, что кроме текстового INI-файла, вместе с приложением будут находиться множество файлов с разными графическими рисунками,
с чем многие разработчики просто не согласятся.
Вариант с отдельной DLL мне тоже не очень нравится, хотя конечно стоит продумать и такой способ, как дополнительную возможность.
Разумный выход в данной ситуации я вижу таким: минимизировать зависимость графических образов от выбранного языка.
Т.е. не нужно для каждого языка рисовать отдельную картинку, а сделать так, чтобы рисунок отражал более общие для разных языковых групп сущности,
например: латиница/кириллица, направление текста (слева направо или справа налево), знак валюты, часовой пояс или континент...
Когда выбор образа рисунка ограничен двумя-тремя вариантами, тогда его можно спокойно встраивать внутрь самого приложения.
000800000000000000000000000000000000000000000000000000080000080000000808000800
00000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00F
FFF0000FFFFFF00DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD000000000000000
00999999999999990099999999999999009999999999999900CCCCCCCCCCCCCC00CCCCCCCCCCCC
CC00CCCCCCCCCCCCCC00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF000000000000
00000DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
это bmp 16х16x16 - изображение флага. Просто заметил что картинки RU\EN грузятся из ресурса программы, а по идее должны быть автономны.
зы. А в виде dll не планируется?