Четверг, 30.01.2025, 18:56
AMAR Inc.
Приветствую Вас Гость | RSS
Главная Программирование Регистрация Вход
Меню сайта

Категории каталога
Разные статьи [48]
Система [62]

Главная » Статьи » Delphi » Разные статьи

Многоязычный интерфейс приложений в Delphi
   Наверняка, вам хоть раз в жизни приходилось разрабатывать многоязычное приложение. В таком случае, обычно, один язык встраивается в приложение, как правило, английский, а потом пользователю предоставляется возможность выбрать язык интерфейса программы.

   Для этих целей существует много коммерческих и бесплатных компонент-переводчиков, однако использовать их довольно неудобно, поскольку, необходимо помещать копию компонента на каждую форму приложения. Я предлагаю совершенно другой подход, а именно - использовать модуль-переводчик, который будет переводить все формы приложения. При достаточно высокой скорости перевода интерфейса, размер программы увеличиться всего на 3Кб (именно столько <весит> модуль).

   Алгоритм работы такой: функция TranslateForm обходит все компоненты формы и переводит их на указанный язык, используя для этого специальный словарь. Словарь имеет формат Ini-файла, поэтому, как и для всех остальных Ini-файлов, для этого файла существует ограничение размера - не более 64 Кб, если я, конечно, не ошибаюсь. Решить эту проблему можно достаточно просто - использовать несколько словарей для разных языков.

   Приведу раздел объявления нашего модуля (interface):
 
interface
uses SysUtils, Classes, Controls, Forms, Dialogs, Quickrpt, ... ;
function Translate(Text : string; Lang : string; Dict : TIniFile):string;
procedure TranslateForm(Form : TForm; Lang : string; DictFileName : string);

   Процедура TranslateForm, как я уже писал, обходит все компоненты формы, а функция Trasnlate - выполняет перевод. Переводятся текстовые свойства компонент, например, Caption и Hint. При вызове функции нужно указать следующие параметры:
   Form : TForm; Lang : string; DictFileName : string

   Параметр Form определяет форму, которую нужно перевести. Параметр Lang - это язык на который нужно перевести свойство компонента. Тот язык, с которым работает программа в данный момент, будем называть ключевым. Подразумевается, что в данный момент (до перевода) программа работает с ключевым языком, потому что поиск (перевод) слов будет произведен с использованием ключевого языка. Чтобы было понятнее, приведу пример словаря:
 
[Rus]
File=Файл
Open=Открыть
Translate=Перевести
Application=Приложение
New=Создать
Open=Открыть
Text=Текст
Save=Сохранить
Save As...=Сохранить как...
Print=Печать
Print Setup=Параметры печати
Exit=Выход
Edit=Правка
Cut=Вырезать
Copy=Копировать
Paste=Вставить
Undo=Отмена
View=Вид
Status bar=Панель состояния
Tool bar=Панель инструментов
Tools=Сервис
Settings=Параметры
...

   Для перевода интерфейса приложения с английского на русский язык нужно вызвать процедуру TrasnlateForm так:
TranslateForm(Form1, 'Rus', 'trans.dic');

   При этом ключевым языком считается английский (см. секцию Rus в примере 2). Аналогично можно создать секцию Eng и использовать русский язык в качестве ключевого.

   Для того, чтобы перевести все формы приложения используйте следующие операторы:
for i:=0 to Screen.FormCount-1 do
  TranslateForm(Screen.Forms[i],'Rus','trans.dic');

   Если вы хотите изменить язык приложения во время его запуска, отредактируйте файл проекта так:
for i:=0 to Screen.FormCount-1 do
  TranslateForm(Screen.Forms[i],'Rus','trans.dic');
  Application.Run;

   То есть перевод форм нужно выполнить до выполнения метода Application.Run;

   Теперь рассмотрим весь исходный код модуля-переводчика:
 
unit trans;
interface
uses SysUtils, Classes, Controls, Forms, Dialogs, Quickrpt, QRCtrls, StdCtrls, Buttons, ComCtrls, ExtCtrls, DBCtrls, DB, DBGrids, Menus, Grids, Mask, IniFiles;

function Translate(Text : string; Lang : string; Dict : TIniFile):string;
procedure TranslateForm(Form : TForm; Lang : string; DictFileName : string);

implementation

{ Непосредственный перевод текста }
function Translate(Text : string; Lang : string; Dict : TIniFile):string;
var s : string;
begin
  Result:=Text;
  S:=Dict.ReadString(Lang, Text, '');
  if S='' then Dict.WriteString(Lang, Text, '');
  if S<>'' then Result:=S;
end;

procedure TranslateForm(Form : TForm; Lang : string; DictFileName : string);
var Dict : TIniFile;
      I,J : Integer;
     Obj : TObject;
begin
  { Открываем словарь. Перед вызовом функции Translate словарь должен быть открыт! }
  Dict:=TIniFile.Create(DictFileName);
  if not fileexists(DictFileName) then
    ShowMessage('No exists' + DictFileName);
  Form.Caption:=Translate(Form.Caption, Lang, Dict);
  Application.Title:=Translate(Application.Title, Lang, Dict);
  { Переводим компоненты формы}
  For I:=0 to Form.ComponentCount-1 do
  Begin
    Obj:=Form.Components[i];

    if Obj is TMenuItem then
    begin
      TMenuItem(Obj).Caption:=Translate(TMenuItem(Obj).Caption, Lang, Dict);
      TMenuItem(Obj).Hint:=Translate(TMenuItem(Obj).Hint, Lang, Dict);
    end;

    if Obj is TButton then
    begin
      TButton(Obj).Caption:=Translate(TButton(Obj).Caption, Lang, Dict);
      TButton(Obj).Hint:=Translate(TButton(Obj).Hint, Lang, Dict);
    end;

    if Obj is TBitBtn then
    begin
      TBitBtn(Obj).Caption:=Translate(TBitBtn(Obj).Caption, Lang, Dict);
      TBitBtn(Obj).Hint:=Translate(TBitBtn(Obj).Hint, Lang, Dict);
    end;

    if Obj is TSpeedButton then
    begin
      TSpeedButton(Obj).Caption:=Translate(TSpeedButton(Obj).Caption, Lang, Dict);
      TSpeedButton(Obj).Hint:=Translate(TSpeedButton(Obj).Hint, Lang, Dict);
    end;

    if Obj is TPanel then
    begin
      TPanel(Obj).Caption:=Translate(TPanel(Obj).Caption, Lang, Dict);
      TPanel(Obj).Hint:=Translate(TPanel(Obj).Hint, Lang, Dict);
    end;

    if Obj is TGroupBox then
    begin
      TGroupBox(Obj).Caption:=Translate(TGroupBox(Obj).Caption, Lang, Dict);
      TGroupBox(Obj).Hint:=Translate(TGroupBox(Obj).Hint, Lang, Dict);
    end;

    if Obj is TLabel then
    begin
      TLabel(Obj).Caption:=Translate(TLabel(Obj).Caption, Lang, Dict);
      TLabel(Obj).Hint:=Translate(TLabel(Obj).Hint, Lang, Dict);
    end;

    if Obj is TStaticText then
    begin
      TStaticText(Obj).Caption:=Translate(TStaticText(Obj).Caption, Lang, Dict);
      TStaticText(Obj).Hint:=Translate(TStaticText(Obj).Hint, Lang, Dict);
    end;

    if Obj is TQRLabel then
    begin
      TQRLabel(Obj).Caption:=Translate(TQRLabel(Obj).Caption, Lang, Dict);
      TQRLabel(Obj).Hint:=Translate(TQRLabel(Obj).Hint, Lang, Dict);
    end;

    if Obj is TEdit then
      TEdit(Obj).Hint:=Translate(TEdit(Obj).Hint, Lang, Dict);

    if Obj is TMaskEdit then
      TMaskEdit(Obj).Hint:=Translate(TMaskEdit(Obj).Hint, Lang, Dict);

    if Obj is TMemo then
      TMemo(Obj).Hint:=Translate(TMemo(Obj).Hint, Lang, Dict);

    if Obj is TRadioGroup then
    begin
      TRadioGroup(Obj).Caption:=Translate(TRadioGroup(Obj).Caption, Lang, Dict);
      TRadioGroup(Obj).Hint:=Translate(TRadioGroup(Obj).Hint, Lang, Dict);
      for J:=0 to TRadioGroup(Obj).Items.Count-1 do
        TRadioGroup(Obj).Items[j]:=Translate(TRadioGroup(Obj).Items[j], Lang, Dict);
    end;

    if Obj is TCheckBox then
    begin
      TCheckBox(Obj).Caption:=Translate(TCheckBox(Obj).Caption, Lang, Dict);
      TCheckBox(Obj).Hint:=Translate(TCheckBox(Obj).Hint, Lang, Dict);
    end;

    if Obj is TField then
      TField(Obj).DisplayLabel:=Translate(TField(Obj).DisplayLabel, Lang, Dict);

    if Obj is TTabSheet then
    begin
      TTabSheet(Obj).Caption:=Translate(TTabSheet(Obj).Caption, Lang, Dict);
      TTabSheet(Obj).Hint:=Translate(TTabSheet(Obj).Hint, Lang, Dict);
    end;

    if Obj is TOpenDialog then
      TOpenDialog(Obj).Title:=Translate(TOpenDialog(Obj).Title, Lang, Dict);

    if Obj is TSaveDialog then
      TSaveDialog(Obj).Title:=Translate(TSaveDialog(Obj).Title, Lang, Dict);

    if Obj is TPrintDialog then
      TPrintDialog(Obj).Title:=Translate(TPrintDialog(Obj).Title, Lang, Dict);

    if Obj is TPrinterSetupDialog then
      TPrinterSetupDialog(Obj).Title:=Translate(TPrinterSetupDialog(Obj).Title, Lang, Dict);

  End;
  { освобождаем память}
  Dict.Free;
end;
end.

   Естественно, перед использованием модуля его нужно добавить в оператор uses:
uses ..., trans;

Примечания

   1. Теперь нужно отметить особенность функции Translate. Если слова нет в словаре, она его автоматически добавляет. Потом вам только останется самому ввести перевод этого слова!

   2. Напомню, что поиск словаря, так как он является ini-файлом, по умолчанию производится в каталоге C:Windows (точнее, в каталоге, возвращаемом функцией GetWindowsDirectory), поэтому предварительно нужно поместить туда словарь или явно указать имя файла. При этом удобно использовать функцию ExtractFileDir так:
ExtractFileDir(Application.EXEName+'trans.dic')

   3. Исходный код модуля-переводчика может распространятся согласно положениям лицензии GPL, текст которой вы можете прочитать на моем сайте - http://dkws.narod.ru/.


Категория: Разные статьи | Добавил: amar-runyak (24.09.2007)
Просмотров: 1164 | Комментарии: 2 | Рейтинг: 0.0/0 |

Всего комментариев: 2
2 tuyzalkmn  
0
http://gew635.narod2.ru Movavi Video Suite 9 — это пакет программ чтобы работы с видео, DVD и аудио!

1 oeomrrea  
0
Рассылка рекламных сообщений на 165000 форумов 50$.Продвижение сайта интернет магазина
rekl243(собачечка) mail(тут точка) ru

Имя *:
Email *:
Код *:
Форма входа

Поиск

Друзья сайта

Статистика

Copyright AMAR Inc. © 2025