InfoMix.Ru - У нас можно найти бесплатные программы для Windows, психологические тесты, проверенную халяву, рефераты, Photoshop Top Secret и многое другое!

Сериал Герои (Heroes) 2 сезона
Сериал Герои (Heroes) 2 сезона - Когда полное затмение погружает планету во тьму, профессор-генетик в Индии, взволнованный исчезновением отца, открывает секретную теорию - о людях со сверхсилой, живущих среди нас.
Молодой мечтатель пытается убедить своего брата-политика, в том, что может летать. Участница школьной команды поддержки узнает, что ей невозможно нанести какую-либо физическую травму.
Талантливый художник, чья наркотическая зависимость разрушает его жизнь и его отношения с девушкой, может изображать на своих картинах будущее. В Лос-Анджелесе бывший полицейский-неудачник умеет читать мысли людей, что выводит его на след неуловимого серийного убийцы. В Японии у молодого человека открывается способность останавливать время одной лишь силой воли. Художник-провидец нарисовал картину ядерного взрыва Нью-Йорка, и теперь, всем им предстоит спасти мир от глобального катаклизма...
Цена: 357.00р. / 15.02$ Доставка бесплатно!
Перейти на страницу с более подробным описанием...

Обзоры
Магазин DVD дисков
 Видео на DVD
 Хентай
 Клипы
 Клубничка
 Сериалы
 Лучшее из интернета
 Дополнения к играм
 Тематические сборники
 Операционные системы
 Дистрибутивы
 Софт

 Скачать прайс

Добавь в закладки!

Разыскиваем авторов!
Разыскиваем авторов!

Уважаемые авторы, Вы имеете потрясающую возможность публиковать свои статьи, рефераты, анонсы бесплатного софта, интересные новости и многое другое у нас на портале!

Подробности тут...

Посетителей сегодня


Поддержка многоязычного интерфейса

Подчас бывает актуально встроить в разрабатываемую программу поддержку нескольких языков. Существует множество средств и компонентов для осуществления подобных задач. У всех этих средств один недостаток - они слишком сложны и тяжеловесны. Предлагаем рассмотреть, как можно обеспечить поддержку многоязычности используя более простой и прозрачный метод.

Автор:
Контакт:
Источник:
Просмотров: 330
Сервис: версия для печати | обсудить в форуме | расказать другу | html/bb код | в rss



Подчас бывает актуально встроить в разрабатываемую программу поддержку нескольких языков. Существует множество средств и компонентов для осуществления подобных задач. У всех этих средств один недостаток - они слишком сложны и тяжеловесны. Предлагаем рассмотреть, как можно обеспечить поддержку многоязычности используя более простой и прозрачный метод.

Первое, что нужно выяснить - это язык, на котором разрабатывать интерфейс первоначально. Есть веские причины за то, чтобы использовать для этого именно тот язык, на котором написана эта статья. Дело в том, что русский язык менее лаконичен других европейских языков. При переводе на английский или немецкий 90% фраз будет компактнее и интерфейс вашей программы искажен не будет.

Для поддержки нескольких языков предлагается следующий простой подход. Интерфейс оформляется на родном языке - русском. Для всех остальных языков составляется словарь в виде:


Строка на языке 1=Строка на языке 2
Строка на языке 1=Строка на языке 2

Например:

Файл=File
Выход=Exit
Отмена=Cancel

И так для всех ресурсов приложения. Словарь поместим в отдельный текстовый файл.

Далее, нам необходимо для каждого текстового свойства любого компонента приложения поискать перевод в нашем словаре. Здесь не обойтись без Delphi RTTI. Через Component.ClassInfo получим ссылку на информацию типа, а затем GetTypeData(TypeInf) даст нам указатель на структуру с его описанием.

TypeInf := Component.ClassInfo;
AName := TypeInf^.name; 
TypeData := GetTypeData(TypeInf); 
NumProps := TypeData^.PropCount; 

Далее проходимся по всем свойствам данного (классового) типа:

GetMem(PropList, NumProps * sizeof(pointer));

try
  GetPropInfos(TypeInf, PropList);

  for i := 0 to NumProps-1 do
  begin
    PropName := PropList^[i]^.name;

    PropTypeInf := PropList^[i]^.PropType^;
    PropInfo := PropList^[i];


    case PropTypeInf^.Kind of
      tkString, tkLString: //... это то, что нам нужно
        if PropName <> 'Name' then { Переводить свойство Name не следует }
        begin
          { Получение значения свойства и поиск перевода в словаре }
          StringPropValue := GetStrProp(Component, PropInfo);
          SetStrProp(Component, PropInfo, TranslateString(StringPropValue));
        end;
...
...

Отдельный случай - списки TStrings и коллекции типа TTReeNodes и TListItems. Их придется обработать персонально.

tkClass:
begin
  PropObject := GetObjectProp(Component, PropInfo{, TPersistent});

  if Assigned(PropObject)then
  begin
    { Для дочерних свойств-классов вызов просмотра свойств }
    if (PropObject is TPersistent) then
      UpdateComponent(PropObject as TPersistent);

    { Индивидуальный подход к некоторым классам }
    if (PropObject is TStrings) then
    begin
      for j := 0 to (PropObject as TStrings).Count-1 do
        TStrings(PropObject)[j] := TranslateString(TStrings(PropObject)[j]);
    end;
    if (PropObject is TTreeNodes) then
    begin
      for j := 0 to (PropObject as TTreeNodes).Count-1 do
        TTreeNodes(PropObject).Item[j].Text :=
        TranslateString(TTreeNodes(PropObject).Item[j].Text);
    end;
    if (PropObject is TListItems) then
    begin
      for j := 0 to (PropObject as TListItems).Count-1 do
        TListItems(PropObject).Item[j].Caption
        := TranslateString(TListItems(PropObject).Item[j].Caption);
    end;
{ Здесь можно добавить обработку остальных классов }
end; 

end;

Объединяя все написанное, получим компонент для перевода строковых ресурсов.

unit glLanguageLoader;

interface
{$I glDEF.INC}

uses
  Windows, Messages, SysUtils, Classes, Graphics,
  Controls, Forms, Dialogs, comctrls, grids;

type
  TLanguageLoaderOptions = set of (lofTrimSpaces);
  {опция удаления начальных и завершающих пробелов}

  TglLanguageLoader = class(TComponent)
  private
    sl: TStringList;
    FOptions: TLanguageLoaderOptions;
    function TranslateString(sString: string): string;
  protected
    procedure UpdateComponent(Component: TPersistent); virtual;
  public
    {main function}
    procedure LoadLanguage(Component: TComponent; FileName: string);
  published
    property Options: TLanguageLoaderOptions read FOptions write FOptions;
  end;

  procedure LoadLanguage(Component: TComponent; FileName: string;
  Options: TLanguageLoaderOptions);
  procedure register;

implementation

uses
  TypInfo, dsgnintf;

procedure register;
begin
  RegisterComponents('Gl Components', [TglLanguageLoader]);
end;

{Ф-ия для загрузки словаря без предварительного создания компонента}
procedure LoadLanguage(Component: TComponent; FileName: string;
Options: TLanguageLoaderOptions);
var
  LanguageLoader: TglLanguageLoader;
begin
  LanguageLoader := TglLanguageLoader.Create(nil);
  try
    LanguageLoader.LoadLanguage(Component, FileName);
  finally
    LanguageLoader.Free;
  end;
end;

{ TglLanguageLoader }

{ Загрузка словаря, обход указанного компонента и }
{ всех его дочерних компонентов }
procedure TglLanguageLoader.LoadLanguage(Component: TComponent; FileName: string);

  procedure UpdateAllComponents(Component: TComponent);
  var
    i: integer;
  begin
    { обработка своцств компонента }
    UpdateComponent(Component);
    for i := 0 to Component.ComponentCount-1 do
      UpdateAllComponents(Component.Components[i]);
  end;

begin
  sl := TStringList.Create;
  try
    { Загрузка словаря из заданного файла }
    sl.LoadFromFile(FileName);
    sl.Sorted := true;
    UpdateAllComponents(Component);
  finally
    sl.Free;
  end;
end;

{ Проход по всем свойствам компонента }
{ Для всех строковых свойств - загрузка перевода из сооваря }
procedure TglLanguageLoader.UpdateComponent(Component: TPersistent);
var
  PropInfo: PPropInfo;
  TypeInf, PropTypeInf: PTypeInfo;
  TypeData: PTypeData;
  i, j: integer;
  AName, PropName, StringPropValue: string;
  PropList: PPropList;
  NumProps: word;
  PropObject: TObject;
begin
  { Playing with RTTI }
  TypeInf := Component.ClassInfo;
  AName := TypeInf^.name;
  TypeData := GetTypeData(TypeInf);
  NumProps := TypeData^.PropCount;

  GetMem(PropList, NumProps*sizeof(pointer));

  try
    GetPropInfos(TypeInf, PropList);

    for i := 0 to NumProps-1 do
    begin
      PropName := PropList^[i]^.name;

      PropTypeInf := PropList^[i]^.PropType^;
      PropInfo := PropList^[i];


      case PropTypeInf^.Kind of
        tkString, tkLString:
          if PropName <> 'Name' then { Переводить свойство Name не следует }
          begin
            { Получение значения свойства и поиск перевода в словаре }
            StringPropValue := GetStrProp( Component, PropInfo );
            SetStrProp( Component, PropInfo, TranslateString(StringPropValue) );
          end;
        tkClass:
        begin
          PropObject := GetObjectProp(Component, PropInfo{, TPersistent});
          if Assigned(PropObject)then
          begin
            { Для дочерних свойств-классов вызов просмотра свойств }
            if (PropObject is TPersistent) then
              UpdateComponent(PropObject as TPersistent);

            { Индивидуальный подход к некоторым классам }
            if (PropObject is TStrings) then
            begin
              for j := 0 to (PropObject as TStrings).Count-1 do
                TStrings(PropObject)[j] := TranslateString(TStrings(PropObject)[j]);
            end;
            if (PropObject is TTreeNodes) then
            begin
              for j := 0 to (PropObject as TTreeNodes).Count-1 do
                TTreeNodes(PropObject).Item[j].Text :=
                TranslateString(TTreeNodes(PropObject).Item[j].Text);
            end;
            if (PropObject is TListItems) then
            begin
              for j := 0 to (PropObject as TListItems).Count-1 do
                TListItems(PropObject).Item[j].Caption :=
                TranslateString(TListItems(PropObject).Item[j].Caption);
            end;
            { Здесь можно добавить обработку остальных классов }
          end;
        end;
      end;
    end;
  finally
    FreeMem(PropList, NumProps*sizeof(pointer));
  end;
end;

{ Поиск перевода для заданной строки в словаре }
function TglLanguageLoader.TranslateString(sString: string): string;
begin
  if lofTrimSpaces in Options then
    sString := trim(sString);
  if sString = '' then
  begin
    Result := '';
    exit;
  end;
  if sl.IndexOfName(sString) <> -1 then
    Result := sl.Values[sString]
  else
    Result := sString;
end; 

end.

 

OS и Железо | 2008-01-13 

В начало библиотеки | В начало данного раздела | Скачать InfoDigest

другие статьи текущего раздела

комментарии
Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание!

Комментарии отсутствуют!


Оставить свой комментарий:

Как вас зовут:   
Текст комментария:
Необходимо ввести защитный код! (включите отображение картинок):

Наша рассылка
ПОДПИШИСЬ!
Подпишись на нашу убойную рассылку, и ты еженедельно будешь получать на e-mail самые интересные новости, тесты, опросы, анекдоты, прямые ссылки на лучший софт, обзоры "халявы", анонсы новых статей в нашей библиотеке, последних новинок нашего магазина, новых тем форума и многое-многое другое!

Архив рассылки
Подробнее/Подписка


Опрос

Вы используете лицензионное ПО?






Магазин DVD дисков
Доставка бесплатна!
Мы оплачиваем все расходы*, связанные с доставкой вашего заказа в нашем магазине DVD дисков!

как сделать заказ
как оплатить
о доставке

 

© 2009 Руководитель - Березин Юрий (ICQ: 7741822), Программирование - GoldStudio.ru
При перепечатке материалов ссылка на наш портал обязательна!