Динамическое переключение языка интерфейса в MFC-приложениях
От: Илья Зарецкий Россия http://zarezky.spb.ru/
Дата: 09.06.04 02:56
Оценка: 75 (4)
Статья:
Динамическое переключение языка интерфейса в MFC-приложениях
Автор(ы): Илья Зарецкий
Дата: 23.10.2004
Статья рассказывает о реализации механизма переключения языка пользовательского интерфейса в приложениях, разрабатываемых с использованием библиотеки MFC.


Авторы:
Илья Зарецкий

Аннотация:
Статья рассказывает о реализации механизма переключения языка пользовательского интерфейса в приложениях, разрабатываемых с использованием библиотеки MFC.
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Динамическое переключение языка интерфейса в MFC-приложе
От: Nikeware http://www.nikeware.com
Дата: 02.11.04 00:10
Оценка: 1 (1)
Здравствуйте, Илья Зарецкий, Вы писали:

ИЗ>Статья рассказывает о реализации механизма переключения языка пользовательского интерфейса в приложениях, разрабатываемых с использованием библиотеки MFC.

Хорошая статья. Спасибо!

Сам этой схемой пользуюсь уже больше года в своей программе. Посему могу сказать каковы минусы и плюсы. То что локализация сделана не по убогому принципу INI файлов — это несомненный плюс, который дает возможность избежать проблем с такими вещами как разница в ширине исходного и переведенного текста, например в том же диалоге. За примером ходить далеко не надо — немецкий язык тому яркое подтверждение Половина строк просто потом невлазит. Естественно, что наличие самого темлейта диалога в ресурсах языковой dll решает проблему. Просто взяли и растянули диалог и выправили контролы на нем. Если еще например взять языки в которых текст читается справа-налево — тоже проблем вообщем-то нет. В ресурсах направление и layout можно подправить. Вообщем гораздо лучше, чем INI, правда?

Но есть и обратная сторона медали Проблема начинается при росте программы от версии к версии. "Руками" отслеживать все изменения в этих библиотеках очень сложно. Фактически приходится переписывать ее заново. И если замена (или отсутствие) в новой версии очередной строки в ресурсах дело не столь щипитильное, то отсутствие какого-либо контрола на диалоге (в новой версии он есть, и что самое главное есть код в приложении, который предпологает его наличие, а в старой версии его нет) делает программу неработоспособной на предыдущей версии ресурсов. И если полное отсутствие диалога в новых ресурсах спасает тем, что по умолчанию подгрузится default из самого приложения, то какое-либо несоответствие приводит к плачевным последствиям. Вывод — неизменной единицей в ресурсах является уже не просто строка, а целый диалог, меню и т.д., что само по себе усложняет процесс сопровождения.

Best regards,
Николай

"To merge or not to merge?"
www.visual-comparer.com
Re: Динамическое переключение языка интерфейса в MFC-приложе
От: _nn_ www.nemerleweb.com
Дата: 16.06.04 10:26
Оценка:
Здравствуйте, Илья Зарецкий, Вы писали:

ИЗ>Статья:



ИЗ>Авторы:

ИЗ> Илья Зарецкий

ИЗ>Аннотация:

ИЗ>Статья рассказывает о реализации механизма переключения языка пользовательского интерфейса в приложениях, разрабатываемых с использованием библиотеки MFC.

Немного не понятно зачем нужны библиотеки с поддержкой MFC (MFC extension DLL) ?
Чем хуже будут обычные библиотеки ресурсов ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Динамическое переключение языка интерфейса в MFC-прил
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 16.06.04 10:30
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Немного не понятно зачем нужны библиотеки с поддержкой MFC (MFC extension DLL) ?


Тем, что в случае использования MFC extension DLL библиотека сама выполняет поиск ресурсов по всем загруженным модулям, избавляя нас от явных вызовов SetResourceHandle().
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[3]: Динамическое переключение языка интерфейса в MFC-прил
От: _nn_ www.nemerleweb.com
Дата: 16.06.04 10:33
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, _nn_, Вы писали:


__>>Немного не понятно зачем нужны библиотеки с поддержкой MFC (MFC extension DLL) ?


SDB>Тем, что в случае использования MFC extension DLL библиотека сама выполняет поиск ресурсов по всем загруженным модулям, избавляя нас от явных вызовов SetResourceHandle().


Зато в случае ресурсов вообще не нужно выполнять никакого кода со стороны библиотеки (DLL).
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Динамическое переключение языка интерфейса в MFC-прил
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 16.06.04 10:38
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, SchweinDeBurg, Вы писали:


SDB>>Здравствуйте, _nn_, Вы писали:


__>>>Немного не понятно зачем нужны библиотеки с поддержкой MFC (MFC extension DLL) ?


SDB>>Тем, что в случае использования MFC extension DLL библиотека сама выполняет поиск ресурсов по всем загруженным модулям, избавляя нас от явных вызовов SetResourceHandle().


__>Зато в случае ресурсов вообще не нужно выполнять никакого кода со стороны библиотеки (DLL).


Так и здесь никого кода со стороны extension DLL не выполняется (кроме простенькой однократной инициализации при загрузке). Под "библиотекой" я в предыдущем посте подразумевал MFC.
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[5]: Динамическое переключение языка интерфейса в MFC-прил
От: _nn_ www.nemerleweb.com
Дата: 16.06.04 13:51
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, _nn_, Вы писали:


__>>Здравствуйте, SchweinDeBurg, Вы писали:


SDB>>>Здравствуйте, _nn_, Вы писали:


__>>>>Немного не понятно зачем нужны библиотеки с поддержкой MFC (MFC extension DLL) ?


SDB>>>Тем, что в случае использования MFC extension DLL библиотека сама выполняет поиск ресурсов по всем загруженным модулям, избавляя нас от явных вызовов SetResourceHandle().


__>>Зато в случае ресурсов вообще не нужно выполнять никакого кода со стороны библиотеки (DLL).


SDB>Так и здесь никого кода со стороны extension DLL не выполняется (кроме простенькой однократной инициализации при загрузке).

Вот эту инициализацию можно исключить полностью, вдобавок это сделает возможным использование DLL в программах написанных без MFC без проблем.
SDB>Под "библиотекой" я в предыдущем посте подразумевал MFC.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Динамическое переключение языка интерфейса в MFC-прил
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 16.06.04 15:04
Оценка:
Здравствуйте, _nn_, Вы писали:

SDB>>Так и здесь никого кода со стороны extension DLL не выполняется (кроме простенькой однократной инициализации при загрузке).

__>Вот эту инициализацию можно исключить полностью, вдобавок это сделает возможным использование DLL в программах написанных без MFC без проблем.

Безусловно. Но код инициализации пишется один раз (или вообще генерится Колдуном), а вызов SetResourceHandle() (с запоминанием предыдущего дескриптора и его последующим восстановлением) придется выполнять многократно — если часть ресурсов (общая для всех языков) содержится в основном исполняемом модуле.
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[7]: P.S. - предложение
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 16.06.04 15:11
Оценка:
Думаю, что нашу с Вами дискуссию можно закрыть (по крайней мере — публичную), поскольку предложенный мной в стаье способ ориентирован в первую и главную очередь именно на приложения, создаваемые с использованием MFC (а Вы, как мы оба знаем — большой поклонник WTL ). При желании продолжить — мы друг у друга в контактах...
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[8]: P.S. - предложение
От: Carc Россия https://vk.com/gosha_mazov
Дата: 03.09.04 20:34
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Думаю, что нашу с Вами дискуссию можно закрыть (по крайней мере — публичную), поскольку предложенный мной в стаье способ ориентирован в первую и главную очередь именно на приложения, создаваемые с использованием MFC (а Вы, как мы оба знаем — большой поклонник WTL ). При желании продолжить — мы друг у друга в контактах...

Честно говоря возникло несколько проблем:
описание VC6, MDI-проект MFC 6, пробовал на вин98
1) насколько я уловил из Круглински MFC extension позволяет следующее
если загружена библиотека расгирения, ресурс одназначно будет грузиться из длл (без SetResourceHandle и зависимостей от языка текущего)
такого у меня не произошло
2) без явного вызова SetResourceHandle исполняемый модуль упорно грузил из себя
3) setlocale — не помогала в решении задачи
4) код смены меню, никуда не годиться для CMDIFrameWnd, получалось белиберда — но это решаемо, просто не до копал.

Что хотел бы:
основной модуль содержит все ресурсы (к примеру русские), а вот некая длл (extension или resource only) содержит на другом языке. В присутствии длл программа локализована (ищет автоматом, или как то можно указать в опциях — не принципиально), в отсуствуии работает только на том, который есть в исполняемом файле.
Именно это в общем то и не получилось, все в конце концов сводилось к явному вызову SetResourceHandle
Aml Pages Home
Re[9]: P.S. - предложение
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 08.09.04 04:28
Оценка:
Здравствуйте, Carc, Вы писали:

C>Честно говоря возникло несколько проблем:

C>описание VC6, MDI-проект MFC 6, пробовал на вин98

Прошу прощения за поздний ответ — проглядел Ваш пост, поскольку топик слишком быстро уехал вниз.

Давайте начнем вот с чего: пример, прилагающийся к статье, работает на Вашей системе правильно?

C>1) насколько я уловил из Круглински MFC extension позволяет следующее

C>если загружена библиотека расгирения, ресурс одназначно будет грузиться из длл C>(без SetResourceHandle и зависимостей от языка текущего)

Нет, это не так. Позволю себе маленькую цитату:

...ядро MFC при явной (например, CMenu::LoadMenu) или неявной (например, CDialog::DoModal) загрузке любого ресурса ищет его не только в том модуле, дескриптор которого возвращает функция AfxGetResourceHandle, но и во всех extension DLLs, загруженных в адресное пространство процесса.


При этом поиск ресурса по цепочке загруженных extension DLLs осуществляется только в том случае, если требуемый ресурс не был найден в исполняемом модуле. Замечу, что это утверждение имеет несколько упрощенный характер и справедливо в том случае, если после запуска приложения мы не вызывали явно функцию AfxSetResourceHandle(). Если быть точным до конца, то

When looking for a resource, most of the standard MFC implementations that load resources look first at the current resource module (AfxGetResourceHandle) and if not found walk the list of CDynLinkLibrary objects attempting to load the requested resource.


C>такого у меня не произошло

C>2) без явного вызова SetResourceHandle исполняемый модуль упорно грузил из себя
C>3) setlocale — не помогала в решении задачи

Что естественно — см. выше.

C>4) код смены меню, никуда не годиться для CMDIFrameWnd, получалось белиберда — но это решаемо, просто не до копал.


Согласен, для MDI понадобится доработка, займусь.
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[10]: P.S. - предложение
От: Carc Россия https://vk.com/gosha_mazov
Дата: 08.09.04 17:42
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, Carc, Вы писали:


C>>Честно говоря возникло несколько проблем:

C>>описание VC6, MDI-проект MFC 6, пробовал на вин98

SDB>Прошу прощения за поздний ответ — проглядел Ваш пост, поскольку топик слишком быстро уехал вниз.


SDB>Давайте начнем вот с чего: пример, прилагающийся к статье, работает на Вашей системе правильно?

хм... пример то общем то простой, и есстественно разибираясь, просто начал применять... проверю!

C>>1) насколько я уловил из Круглински MFC extension позволяет следующее

C>>если загружена библиотека расгирения, ресурс одназначно будет грузиться из длл C>(без SetResourceHandle и зависимостей от языка текущего)

SDB>Нет, это не так. Позволю себе маленькую цитату:


SDB>

SDB>...ядро MFC при явной (например, CMenu::LoadMenu) или неявной (например, CDialog::DoModal) загрузке любого ресурса ищет его не только в том модуле, дескриптор которого возвращает функция AfxGetResourceHandle, но и во всех extension DLLs, загруженных в адресное пространство процесса.


SDB>При этом поиск ресурса по цепочке загруженных extension DLLs осуществляется только в том случае, если требуемый ресурс не был найден в исполняемом модуле. Замечу, что это утверждение имеет несколько упрощенный характер и справедливо в том случае, если после запуска приложения мы не вызывали явно функцию AfxSetResourceHandle(). Если быть точным до конца, то


SDB>

SDB>When looking for a resource, most of the standard MFC implementations that load resources look first at the current resource module (AfxGetResourceHandle) and if not found walk the list of CDynLinkLibrary objects attempting to load the requested resource.


C>>такого у меня не произошло

C>>2) без явного вызова SetResourceHandle исполняемый модуль упорно грузил из себя
C>>3) setlocale — не помогала в решении задачи

SDB>Что естественно — см. выше.

Окей! Уточню дома у Круглински с точностью до цитаты.

C>>4) код смены меню, никуда не годиться для CMDIFrameWnd, получалось белиберда — но это решаемо, просто не до копал.


SDB>Согласен, для MDI понадобится доработка, займусь.

Ну это то в целом не проблема, я думаю разобраться не сложно. Просто руки не дошли.
Спасибо за ответ.
Aml Pages Home
Re[2]: Динамическое переключение языка интерфейса в MFC-прил
От: Carc Россия https://vk.com/gosha_mazov
Дата: 02.11.04 20:07
Оценка:
Здравствуйте, Nikeware, Вы писали:

N>Здравствуйте, Илья Зарецкий, Вы писали:


ИЗ>>Статья рассказывает о реализации механизма переключения языка пользовательского интерфейса в приложениях, разрабатываемых с использованием библиотеки MFC.

N>Хорошая статья. Спасибо!

N>Сам этой схемой пользуюсь уже больше года в своей программе. Посему могу сказать каковы минусы и плюсы. То что локализация сделана не по убогому принципу INI файлов — это несомненный плюс, который дает возможность избежать проблем с такими вещами как разница в ширине исходного и переведенного текста, например в том же диалоге. За примером ходить далеко не надо — немецкий язык тому яркое подтверждение Половина строк просто потом невлазит. Естественно, что наличие самого темлейта диалога в ресурсах языковой dll решает проблему. Просто взяли и растянули диалог и выправили контролы на нем. Если еще например взять языки в которых текст читается справа-налево — тоже проблем вообщем-то нет. В ресурсах направление и layout можно подправить. Вообщем гораздо лучше, чем INI, правда?


N>Но есть и обратная сторона медали Проблема начинается при росте программы от версии к версии. "Руками" отслеживать все изменения в этих библиотеках очень сложно. Фактически приходится переписывать ее заново. И если замена (или отсутствие) в новой версии очередной строки в ресурсах дело не столь щипитильное, то отсутствие какого-либо контрола на диалоге (в новой версии он есть, и что самое главное есть код в приложении, который предпологает его наличие, а в старой версии его нет) делает программу неработоспособной на предыдущей версии ресурсов. И если полное отсутствие диалога в новых ресурсах спасает тем, что по умолчанию подгрузится default из самого приложения, то какое-либо несоответствие приводит к плачевным последствиям. Вывод — неизменной единицей в ресурсах является уже не просто строка, а целый диалог, меню и т.д., что само по себе усложняет процесс сопровождения.

Рехех.... ну может тогда не такой уж убогий "принцип ини-файлов"?

А какие-нить идеи были как бороться с отсутствием контрола на диалоге (а код есть), я в общем то ничего толкового и не придумал так!?! Ну конечно можно контролировать все GetDlgItem и т.д., но все равно не выход, очень замусоривается код, причем даже не столько проверками, сколько сообщения что мол ошибка.
Да и не всегда понятно, какое решение лучше — позволить программе дохромать (ну если не удалось найти контрол через GetDlgItem то просто не выполнять с ним никаких действий), или же все таки дать программе с треском рухнуть — зато юзермессадж на эту тему гарантирован, и тогда ошибка будет исправлена...

N>Best regards,

N>Николай
Aml Pages Home
Re[3]: Динамическое переключение языка интерфейса в MFC-прил
От: Nikeware http://www.nikeware.com
Дата: 05.11.04 00:20
Оценка:
Здравствуйте, Carc, Вы писали:

C>Рехех.... ну может тогда не такой уж убогий "принцип ини-файлов"?

Универсальных средств не бывает. И у каждого есть свои плюсы и минусы. Вышеизложенный способ намного гибче и предоставляет гораздо больше возможностей. INI еще нужно "протащить" через весь код, занимаясь переводом каждой формы на лету, а это дополнительный код(!). Здесь же достаточно загрузки ресурсов в одном единственном месте кода при старте программы. Дальше просто "забыли" и все.

C>А какие-нить идеи были как бороться с отсутствием контрола на диалоге (а код есть), я в общем то ничего толкового и не придумал так!?! Ну конечно можно контролировать все GetDlgItem и т.д., но все равно не выход, очень замусоривается код, причем даже не столько проверками, сколько сообщения что мол ошибка.

C>Да и не всегда понятно, какое решение лучше — позволить программе дохромать (ну если не удалось найти контрол через GetDlgItem то просто не выполнять с ним никаких действий), или же все таки дать программе с треском рухнуть — зато юзермессадж на эту тему гарантирован, и тогда ошибка будет исправлена...
У меня есть одно прекрасное средство, которым я всегда пользуюсь — ASSERT() называется Оно Вам нужно, "контролировать все GetDlgItem"? Это называется, создадим себе проблем, а потом будем с ними бороться. Зачем писать совершенно ненужный код, который правит подобные ошибки. Это лишнее. Проще недопускать подобных ситуаций. А вот чтобы их не допускать, хотелось бы иметь некое средство (программу), которое позволяло бы управлять и синхронизировать ресурсы с учетом многоязыковой поддержки. Хотелось то всего лишь, чтобы:
— было понятие проекта с такой еденицей, как исходный оригинальный ресурсный файл (dll, rc), желательно даже с пониманием dsp проектов;
— было создание на основе оригинального ресурса других ресурсных едениц (трансляций), которые и будут являться теми самыми переводами;
— программа могла при изменении оригинального ресурса (вышла новая/очередная версия программы) показывать изменения и позволять синхронизировать эти изменения с ресурсами-трансляциями. Мечтаю видеть окно, разделенно пополам, в одной части диалог/форма старой версии в другом тот, что сейчас изменился в оригинальном ресурсе и драг-анд-дроп. Взял и из нового перетащил недостающее в старый. Такое же и для меню и всего остально, что можно по такому принципу представить.

При таком подходе достаточно один раз пройтись по переводам, сделать синхронизацию, отослать на доперевод трансляции авторам и пересобрать заново ресурсы.

На диссертацию не тянет, но на идею для шаровары само то

Best regards,
Николай

"To merge or not to merge?"
www.visual-comparer.com
Re[3]: Динамическое переключение языка интерфейса в MFC-прил
От: Аноним  
Дата: 05.11.04 06:50
Оценка:
>Рехех.... ну может тогда не
> такой уж убогий "принцип ини-файлов"?

Как человек, использующий ини-файлы в аналогичном приложении, подтверждаю — "золотой пули" здесь нет (хотя ини все-таки не такие уж и убогие ) Каждый подход имеет свои плюсы и минусы. Более того, я все-больше убеждаюсь что перевод должны делать специалисты, а не пользователи, а первые вполне могут справится с более сложным окружением для перевода.
Re[4]: Динамическое переключение языка интерфейса в MFC-прил
От: Carc Россия https://vk.com/gosha_mazov
Дата: 05.11.04 19:15
Оценка:
Здравствуйте, Nikeware, Вы писали:

N>Здравствуйте, Carc, Вы писали:


C>>Рехех.... ну может тогда не такой уж убогий "принцип ини-файлов"?

N>Универсальных средств не бывает. И у каждого есть свои плюсы и минусы. Вышеизложенный способ намного гибче и предоставляет гораздо больше возможностей. INI еще нужно "протащить" через весь код, занимаясь переводом каждой формы на лету, а это дополнительный код(!). Здесь же достаточно загрузки ресурсов в одном единственном месте кода при старте программы. Дальше просто "забыли" и все.
Была идея да руки не дошли — API Hooking — перехватывать загрузку ресурса и грузить их из ини (к примеру, может это вообще быть какой-нить xml) а если во внешнем файле (ини, xml) не найден ресурс — тогда уж грузить из ресурсов файла.

C>>А какие-нить идеи были как бороться с отсутствием контрола на диалоге (а код есть), я в общем то ничего толкового и не придумал так!?! Ну конечно можно контролировать все GetDlgItem и т.д., но все равно не выход, очень замусоривается код, причем даже не столько проверками, сколько сообщения что мол ошибка.

C>>Да и не всегда понятно, какое решение лучше — позволить программе дохромать (ну если не удалось найти контрол через GetDlgItem то просто не выполнять с ним никаких действий), или же все таки дать программе с треском рухнуть — зато юзермессадж на эту тему гарантирован, и тогда ошибка будет исправлена...
N>У меня есть одно прекрасное средство, которым я всегда пользуюсь — ASSERT() называется Оно Вам
Речь не о том: ASSERT то работает в Debug c моей версией ресурсов, а проблема появится в Release c библиотекой ресурсов которую могет быть Вася Пупкин писал... и там или есть или нету контрола X...., а ситуация более чем реальная, когда приложение модифицируется достаточно часто. Вот к примеру в том же Windows Commander четко видно, что он локализует иногда не все (т.е. явно что видимо ресурсы от старой версии) — но все же хоть что-то. "Еду как могу". Имхо это лучше, все таки он не падает из за ошибки Васи Пупкина — тем более что пользователь не умрет от того что-то то лишнее в диалоге.

нужно, "контролировать все GetDlgItem"? Это называется, создадим себе проблем, а потом будем с ними бороться. Зачем писать совершенно ненужный код, который правит подобные ошибки. Это лишнее. Проще недопускать подобных ситуаций. А вот чтобы их не допускать, хотелось бы иметь некое средство (программу), которое позволяло бы управлять и синхронизировать ресурсы с учетом многоязыковой поддержки. Хотелось то всего лишь, чтобы:
N>- было понятие проекта с такой еденицей, как исходный оригинальный ресурсный файл (dll, rc), желательно даже с пониманием dsp проектов;
N>- было создание на основе оригинального ресурса других ресурсных едениц (трансляций), которые и будут являться теми самыми переводами;
N>- программа могла при изменении оригинального ресурса (вышла новая/очередная версия программы) показывать изменения и позволять синхронизировать эти изменения с ресурсами-трансляциями. Мечтаю видеть окно, разделенно пополам, в одной части диалог/форма старой версии в другом тот, что сейчас изменился в оригинальном ресурсе и драг-анд-дроп. Взял и из нового перетащил недостающее в старый. Такое же и для меню и всего остально, что можно по такому принципу представить.

N>При таком подходе достаточно один раз пройтись по переводам, сделать синхронизацию, отослать на доперевод трансляции авторам и пересобрать заново ресурсы.


N>На диссертацию не тянет, но на идею для шаровары само то

Угу, я бы тоже хотел такое увидеть — но все что я видел честно говоря вызывало ощущение — Шлеп, хлоп и поехали. "Так и я могу" &#169 Промокашка.
Написать конечно можно попробовать, но там одной "черной" работы немало, поэтому в одиночку мне кажется это сложновато сделать. А собственно 99.9 того чего не хватало мне в этих чудах, Вы описали. Но видимо писать все же придется


N>Best regards,

N>Николай
Aml Pages Home
Re[5]: Динамическое переключение языка интерфейса в MFC-прил
От: Nikeware http://www.nikeware.com
Дата: 05.11.04 23:27
Оценка:
Здравствуйте, Carc, Вы писали:

C>Была идея да руки не дошли — API Hooking — перехватывать загрузку ресурса и грузить их из ини (к примеру, может это вообще быть какой-нить xml) а если во внешнем файле (ини, xml) не найден ресурс — тогда уж грузить из ресурсов файла.

Повторюсь — в обсуждаемом способе ничего изобретать не нужно, уже все есть.
Попутно вспомнил. А что Вы будете с Юникодом делать? Я сколько видел Ini, там все сплошь ANSI

C>Речь не о том: ASSERT то работает в Debug c моей версией ресурсов, а проблема появится в Release c библиотекой ресурсов которую могет быть Вася Пупкин писал... и там или есть или нету контрола X...., а ситуация более чем реальная, когда приложение модифицируется достаточно часто. Вот к примеру в том же Windows Commander четко видно, что он локализует иногда не все (т.е. явно что видимо ресурсы от старой версии) — но все же хоть что-то. "Еду как могу". Имхо это лучше, все таки он не падает из за ошибки Васи Пупкина — тем более что пользователь не умрет от того что-то то лишнее в диалоге.

"Вам шашешки или ехать?" (с) Эдак можно допрограммироватьтся и получить монстра на 99,9% процентов состоящего из кода, который сам себя правит от вмешательства извне. Терминатор-2 внатуре Должна быть разумная граница. Для меня это ASSERT и если какой-то Пупкин залез и без прочтения инструкции "наложил" в коде, то "ССЗБ". На сайте для этого все есть(должно быть) — инструкция по применению + инструмент. Я об инструменте и веду речь. Сейчас они отсутствуют (я не видел во всяком случае нормальных). Были бы нормальные инструменты, работащие в рамках данной парадигмы, было бы все нормально. Если хотите, рассматривайте любую программу как некий ограничитель действий пользователя Давая пользователю делать только то, что разрешено в определенный момент времени, вы тем самым программируете логику программы и тем самым получаете ожидаемый результат. Как пример, БД. Если бы все лазили без ведома в файлы базы данных напрямую (для лучшего понимания представим что это просто текстовые файлы), то был бы полный капец. Поэтому и пишется нечто, называемое СИСТЕМОЙ УПРАВЛЕНИЯ БД (в обсуждаемом контексте — Система Ограничения Доступа по вполне определенной логике). Просто нужно заставить Васю играть по правилам Поверьте, это легче, чем сидет и думать, где он в этот раз "наложит".

C>Угу, я бы тоже хотел такое увидеть — но все что я видел честно говоря вызывало ощущение — Шлеп, хлоп и поехали. "Так и я могу" &#169 Промокашка.

Если Вы видите "Так и я могу", то точно так уже не напишите, как минимум чуть лучше

C>Написать конечно можно попробовать, но там одной "черной" работы немало, поэтому в одиночку мне кажется это сложновато сделать. А собственно 99.9 того чего не хватало мне в этих чудах, Вы описали. Но видимо писать все же придется

Вас пугают сложности? "Нам расколоть его поможет... !" (с)

Best regards,
Николай

"To merge or not to merge?"
www.visual-comparer.com
Re[6]: Динамическое переключение языка интерфейса в MFC-прил
От: Carc Россия https://vk.com/gosha_mazov
Дата: 06.11.04 05:33
Оценка:
Здравствуйте, Nikeware, Вы писали:

N>Здравствуйте, Carc, Вы писали:


C>>Была идея да руки не дошли — API Hooking — перехватывать загрузку ресурса и грузить их из ини (к примеру, может это вообще быть какой-нить xml) а если во внешнем файле (ини, xml) не найден ресурс — тогда уж грузить из ресурсов файла.

N> Повторюсь — в обсуждаемом способе ничего изобретать не нужно, уже все есть.
N>Попутно вспомнил. А что Вы будете с Юникодом делать? Я сколько видел Ini, там все сплошь ANSI
ну к промеру ини, может быть и вообще что-то иное... тут я просто не подумал

C>>Речь не о том: ASSERT то работает в Debug c моей версией ресурсов, а проблема появится в Release c библиотекой ресурсов которую могет быть Вася Пупкин писал... и там или есть или нету контрола X...., а ситуация более чем реальная, когда приложение модифицируется достаточно часто. Вот к примеру в том же Windows Commander четко видно, что он локализует иногда не все (т.е. явно что видимо ресурсы от старой версии) — но все же хоть что-то. "Еду как могу". Имхо это лучше, все таки он не падает из за ошибки Васи Пупкина — тем более что пользователь не умрет от того что-то то лишнее в диалоге.

N>"Вам шашешки или ехать?" (с) Эдак можно допрограммироватьтся и получить монстра на 99,9% процентов состоящего из кода, который сам себя правит от вмешательства извне. Терминатор-2 внатуре Должна быть разумная граница. Для меня это ASSERT и если какой-то Пупкин залез и без прочтения инструкции "наложил" в коде, то "ССЗБ". На сайте для этого все есть(должно быть) — инструкция по применению + инструмент. Я об инструменте и веду речь. Сейчас они отсутствуют (я не видел во всяком случае нормальных). Были бы нормальные инструменты, работащие в рамках данной парадигмы, было бы все нормально. Если хотите, рассматривайте любую программу как некий ограничитель действий пользователя Давая пользователю делать только то, что разрешено в определенный момент времени, вы тем самым программируете логику программы и тем самым получаете ожидаемый результат. Как пример, БД. Если бы все лазили без ведома в файлы базы данных напрямую (для лучшего понимания представим что это просто текстовые файлы), то был бы полный капец. Поэтому и пишется нечто, называемое СИСТЕМОЙ УПРАВЛЕНИЯ БД (в обсуждаемом контексте — Система Ограничения Доступа по вполне определенной логике). Просто нужно заставить Васю играть по правилам Поверьте, это легче, чем сидет и думать, где он в этот раз "наложит".
пожалуй Вы правы, всем не угодишь

C>>Угу, я бы тоже хотел такое увидеть — но все что я видел честно говоря вызывало ощущение — Шлеп, хлоп и поехали. "Так и я могу" &#169 Промокашка.

N>Если Вы видите "Так и я могу", то точно так уже не напишите, как минимум чуть лучше
ну я надеюсь, ей богу сколько видел чего-только не было, и в эксель толкаем, и интерфейс красивый. Одна проблема — не едут лыжи. Имхо все эта "экселевщина" ни к чем, это можно приделать и потом. А вот движок нада делать умный.

C>>Написать конечно можно попробовать, но там одной "черной" работы немало, поэтому в одиночку мне кажется это сложновато сделать. А собственно 99.9 того чего не хватало мне в этих чудах, Вы описали. Но видимо писать все же придется

N>Вас пугают сложности? "Нам расколоть его поможет... !" (с)
Меня пугают не сложности как раз, а скорее время... и то что такой проект в одиночку никогда не закончить. А сами сложности, так это же прекрасно мозги поразмять.

N>Best regards,

N>Николай
Aml Pages Home
Re[4]: Динамическое переключение языка интерфейса в MFC-прил
От: Аноним  
Дата: 24.11.04 09:30
Оценка:
Здравствуйте, Nikeware, Вы писали:

C>>Рехех.... ну может тогда не такой уж убогий "принцип ини-файлов"?


N>Универсальных средств не бывает. И у каждого есть свои плюсы и минусы. Вышеизложенный способ намного гибче и предоставляет гораздо больше возможностей. INI еще нужно "протащить" через весь код, занимаясь переводом каждой формы на лету, а это дополнительный код(!). Здесь же достаточно загрузки ресурсов в одном единственном месте кода при старте программы. Дальше просто "забыли" и все.


Отлично, при старте приложения мы может его локализовать. А как быть с динамическим переключением языка, про которое идет речь в статье и на тему которого приведен пример? Я сам пользуюсь убогими ини-файлами и сейчас рассматриваю вопрос о том, стоит ли сменить подход к локазизации.
Итак, вопрос: У меня есть dialog-based приложение с кучей загруженных контролов и дочерних диалогов. В примере к статье при смене языка происходит перезагрузка меню. Соответственно мне на лету придется перезагрузить все диалоги, правильно?

Если я не прав, то, пожалуйста, поясните механизм по которому произойдет смена языка на загруженных диалогах.
Re[5]: Динамическое переключение языка интерфейса в MFC-прил
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 24.11.04 09:36
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А> Итак, вопрос: У меня есть dialog-based приложение с кучей загруженных контролов и дочерних диалогов. В примере к статье при смене языка происходит перезагрузка меню. Соответственно мне на лету придется перезагрузить все диалоги, правильно?


Если эти диалоги видны на экране — да. Точнее, придется прибить диалоги, перегрузить DLL с ресурсами, а потом эти диалоги пересоздать.
[ posted via RSDN@Home 1.1.4 beta 3 r233 ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[5]: Динамическое переключение языка интерфейса в MFC-прил
От: Nikolaz Германия www.nikeware.com
Дата: 24.11.04 10:27
Оценка:
Здравствуйте, Аноним, Вы писали:


А> Отлично, при старте приложения мы может его локализовать. А как быть с динамическим переключением языка, про которое идет речь в статье и на тему которого приведен пример? Я сам пользуюсь убогими ини-файлами и сейчас рассматриваю вопрос о том, стоит ли сменить подход к локазизации.

А> Итак, вопрос: У меня есть dialog-based приложение с кучей загруженных контролов и дочерних диалогов. В примере к статье при смене языка происходит перезагрузка меню. Соответственно мне на лету придется перезагрузить все диалоги, правильно?

А> Если я не прав, то, пожалуйста, поясните механизм по которому произойдет смена языка на загруженных диалогах.

Вот ответьте мне честно (положа правую руку на левое сердце ) — неужели это так жизненно необходимо — переключение языка на "лету"? Вы что, по триста раз на день переключаете язык в приложении, что не можете смирится с необходимостью перезапустить приложение при смене языка? Или это продиктовано функциональностью программы? Это конечно выглядит клево, но в 99,99% случаях совершенно бессмысленно.

Умолкаю, потому как судя по теме это уже offtop

С наилучшими,
Николай
Re: Динамическое переключение языка интерфейса в MFC-приложе
От: Аноним  
Дата: 12.05.05 12:34
Оценка:
Здравствуйте,

я что-то не так понимаю, или в чём проблема:
При переключении языка на русский само меню переводится,
а содержание диалога "О программе" остается в виде вопросительных знаков...
Да и само слово заголовок диалога "О программе" выглядит как "? ?????????"

Оп.система: WindowsXP

Что не так?
Re[2]: Динамическое переключение языка интерфейса в MFC-прил
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 12.05.05 12:41
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>я что-то не так понимаю, или в чём проблема:

А>При переключении языка на русский само меню переводится,
А>а содержание диалога "О программе" остается в виде вопросительных знаков...
А>Да и само слово заголовок диалога "О программе" выглядит как "? ?????????"

Только что скачал с сайта демо-проект, откомпилил и запустил — все ОК. Windows XP Pro Eng SP2.
[ posted via RSDN@Home 1.1.4 beta 7 r448, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[3]: Динамическое переключение языка интерфейса в MFC-прил
От: Аноним  
Дата: 12.05.05 12:51
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, <Аноним>, Вы писали:


А>>я что-то не так понимаю, или в чём проблема:

А>>При переключении языка на русский само меню переводится,
А>>а содержание диалога "О программе" остается в виде вопросительных знаков...
А>>Да и само слово заголовок диалога "О программе" выглядит как "? ?????????"

SDB>Только что скачал с сайта демо-проект, откомпилил и запустил — все ОК. Windows XP Pro Eng SP2.


У меня та же оп. система со всеми ServicePack'ами. Всё на английском, виндовс-меню "All Programms" и т.д. — поэтому русский текст и в ресурсах не отображается. Но сам факт, что при выполнении программы само меню на русском, говорит о том, что это в принципе возможно. Хотел сначала скриншот привесить, но и так в принципе ведь понятно...
Так чего не хватает?
Re[4]: Динамическое переключение языка интерфейса в MFC-прил
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 12.05.05 13:06
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Так чего не хватает?


А Default language for non-unicode programs установлен в русский?
[ posted via RSDN@Home 1.1.4 beta 7 r448, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[5]: Динамическое переключение языка интерфейса в MFC-прил
От: Аноним  
Дата: 12.05.05 13:16
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, <Аноним>, Вы писали:


А>>Так чего не хватает?


SDB>А Default language for non-unicode programs установлен в русский?


Думаю что нет. Не совсем понимаю, о чем идёт речь и как это сделать
(а соответсвенно, этого не знает и среднестатистический пользователь!!!)
Re[6]: Динамическое переключение языка интерфейса в MFC-прил
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 12.05.05 13:28
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Думаю что нет. Не совсем понимаю, о чем идёт речь и как это сделать


Control Panel -> Regional and Language Options -> Advanvced

А>(а соответсвенно, этого не знает и среднестатистический пользователь!!!)


На NT/2000/XP обычно ставятся юникодные сборки приложений, в которых подобная проблема не возникает. (Просто добавьте еще две сборочные конфигурации, аналогичные существующим, но содержащие две дополнительные директивы препроцессора "UNICODE" и "_UNICODE", а точкой входа для компоновщика укажите wWinMainCRTStartup.)
[ posted via RSDN@Home 1.1.4 beta 7 r448, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[7]: Динамическое переключение языка интерфейса в MFC-прил
От: Аноним  
Дата: 12.05.05 13:48
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, <Аноним>, Вы писали:


А>>Думаю что нет. Не совсем понимаю, о чем идёт речь и как это сделать


SDB>Control Panel -> Regional and Language Options -> Advanvced


Примерно так я это себе и представлял, спасибо. Но это не решение. Особенно,
если оп. система будет локализированной, напрмер немецкой всё с теми же умляутами,
которые превратятся в "ё" или того хуже...

А>>(а соответсвенно, этого не знает и среднестатистический пользователь!!!)


SDB>На NT/2000/XP обычно ставятся юникодные сборки приложений, в которых подобная проблема не возникает. (Просто добавьте еще две сборочные конфигурации, аналогичные существующим, но содержащие две дополнительные директивы препроцессора "UNICODE" и "_UNICODE", а точкой входа для компоновщика укажите wWinMainCRTStartup.)


Но если в Вашем варианте мы всё равно компилируем отдельные версии dll, нужели нельзя обойтись без
"UNICODE" и "_UNICODE" ? Почему же с меню никаких проблем не возникает?? Не понимаю.
Re[8]: Динамическое переключение языка интерфейса в MFC-прил
От: Аноним  
Дата: 12.05.05 15:19
Оценка:
Для чего нужно указывать UNICODE для самого приложения, или же для dll?
Пробовал для dll- Не получается!!!
Было бы меньше ограничений, если бы можно было бы скомпилировать только dll-
само приложение могло бы быть запущенным с английским интерфейсом и под win98,
а unicode-dll подгружалась бы только для русского интерфейса...
Или так и не получится?

ЗЫ: А нельзя ли дополнить демо-проект таким образом, чтобы русский в любом случае отображался?
А то будут еще вопросы
Re[9]: Динамическое переключение языка интерфейса в MFC-прил
От: Аноним  
Дата: 22.05.05 19:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Для чего нужно указывать UNICODE для самого приложения, или же для dll?

А>Пробовал для dll- Не получается!!!
А>Было бы меньше ограничений, если бы можно было бы скомпилировать только dll-
А>само приложение могло бы быть запущенным с английским интерфейсом и под win98,
А>а unicode-dll подгружалась бы только для русского интерфейса...
А>Или так и не получится?

А>ЗЫ: А нельзя ли дополнить демо-проект таким образом, чтобы русский в любом случае отображался?

А>А то будут еще вопросы

Отвечаю сам себе:

1) Нужно указывать ОДИНАКОВЫЕ параметры препроцессора UNICODE,_UNICODE как для dll, так и для основного приложения AfxPolyglot
2) Очень важно!!! В ресурсах шрифт поменять с FONT 8, "Tahoma" на FONT 8, "MS Shell Dlg", если не сделать, русских букв не видать
3) wWinMainCRTStartup указывается только для сборки AfxPolyglot, не для библиотек!!!
4) Плюс всего этого дела- ресурсы в библиотеках остаются не в UNICODE и могут быть напрямую редактированы в редакторе!

Что не получается, или я не понимаю, как — как сделать переключение языка для, к примеру, простого котрола CEdit?
Например, имеем следующее содержание Russian_Russia.rc :

...
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUT DIALOG DISCARDABLE 0, 0, 146, 90
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "О программе"
FONT 8, "MS Shell Dlg"
BEGIN
CTEXT "Тестовое приложение AfxPolyglot",IDC_STATIC,4,4,138,12,
SS_CENTERIMAGE
CTEXT "Авторские права © 2004\nИлья Зарецкий",IDC_STATIC,4,24,
138,18
DEFPUSHBUTTON "Закрыть",IDOK,98,70,44,16
EDITTEXT IDC_EDIT1,19,46,112,14,ES_AUTOHSCROLL
END
...

Как внести в этот CEdit (смотри строчку EDITTEXT IDC_EDIT1,19,46,112,14,ES_AUTOHSCROLL) русский текст?
Копия статьи...
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 12.06.05 19:18
Оценка:
...выложена по адресу http://zarezky.spb.ru/articles/mfc/dynamic_lang.html — на тот случай, если она понадобится ровно в ту минуту, когда сервер RSDN будут рихтовать.
[ posted via RSDN@Home 1.1.4 beta 7 r462, accompanied by The Doors — Unknown Soldier ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Динамическое переключение языка интерфейса в MFC-приложе
От: unb  
Дата: 28.04.06 10:27
Оценка:
Исправлено форматирование текста. — SchweinDeBurg

Здравствуйте, Илья Зарецкий, Вы писали:

ИЗ>Статья рассказывает о реализации механизма переключения языка пользовательского интерфейса в приложениях, разрабатываемых с использованием библиотеки MFC.


Столкнулся с такой проблемой:

в своей программе активно использую механизм идентификации типов MFC,так вот после того как освобождаю библиотеку в OnLanguage,он перестает работать,код:

...
      // загружаем новую и выгружаем старую языковую библиотеку
      CRuntimeClass* cr;
      HINSTANCE hPrevDll = m_hResDLL;
      m_hResDLL = ::LoadLibrary( strLocale.Tokenize( "_", startpos ) + _T(".dll") );
      if( NULL == m_hResDLL )
      {
          startpos = 0;
          AfxMessageBox( "Error loading " + strLocale.Tokenize( "_", startpos ) ,MB_OK|MB_ICONEXCLAMATION );
          ::FreeLibrary(m_hResDll);
          m_hResDLL = hPrevDll;
      }
      cr = GetRuntimeClass()->FromName("COpenForm");
      ::FreeLibrary(hPrevDll);
      cr = GetRuntimeClass()->FromName("COpenForm");
....

результат второго вызова FromName — 0.
Re[2]: Динамическое переключение языка интерфейса в MFC-прил
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 28.04.06 11:00
Оценка:
Здравствуйте, unb, Вы писали:

unb>
unb>      cr = GetRuntimeClass()->FromName("COpenForm");
unb>      ::FreeLibrary(hPrevDll);
unb>      cr = GetRuntimeClass()->FromName("COpenForm");
unb>

unb>результат второго вызова FromName — 0.

1. Судя по выделенном — Вы пользуетесь 7-й версией MFC. На ней, честно признаюсь, описанный в статье механизм не проверялася, все разрабатывалось под 6-кой, на которой я тогда сидел.

2. Внутрь второго вызова FromName() заходить пробовали? Что конкретно там обламывается?
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[3]: Динамическое переключение языка интерфейса в MFC-прил
От: unb  
Дата: 02.05.06 09:02
Оценка:
Исправлено форматирование текста. — SchweinDeBurg

Здравствуйте, SchweinDeBurg, Вы писали:

SDB>2. Внутрь второго вызова FromName() заходить пробовали? Что конкретно там обламывается?


Проблема видимо связана с механизмом работы MFC Extensions Dll,до загрузки библиотек классы ищутся в первом цикле (кототрый search app specific classes),после загрузки библиотеки в InitInstance,в первом цикле ничего не находится,зато почему то находится во втором.После освобождения библиотеки,нужный класс не находится ни в первом ни во втором цикле.

Код FromName:

CRuntimeClass* PASCAL CRuntimeClass::FromName(LPCSTR lpszClassName)
{
        CRuntimeClass* pClass;

    // search app specific classes
    AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
    AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
    for (pClass = pModuleState->m_classList; pClass != NULL;
        pClass = pClass->m_pNextClass)
    {
        if (lstrcmpA(lpszClassName, pClass->m_lpszClassName) == 0)
        {
            AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
            return pClass;
        }
    }
    AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
#ifdef _AFXDLL
    // search classes in shared DLLs
    AfxLockGlobals(CRIT_DYNLINKLIST);
    for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
        pDLL = pDLL->m_pNextDLL)
    {
        for (pClass = pDLL->m_classList; pClass != NULL;
            pClass = pClass->m_pNextClass)
        {
            if (lstrcmpA(lpszClassName, pClass->m_lpszClassName) == 0)
            {
                AfxUnlockGlobals(CRIT_DYNLINKLIST);
                return pClass;
            }
        }
    }
    AfxUnlockGlobals(CRIT_DYNLINKLIST);
#endif

    return NULL; // not found
}
[от модератора]
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 02.05.06 09:10
Оценка:
Убедительная просьба — использовать коды форматирования при вставке текстов программ.
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.