Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Локализация приложения(исп. ресурсов) 
:(
    Опции темы
devmstr
Дата 28.1.2006, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 28.4.2004
Где: Ukraine

Репутация: нет
Всего: 11



Как мне казалось, тема это должна была подниматся наверное сотню раз, но поиск по слову "локализация" ничего конкретного не дал.
Насколько я знаю можно сделать несколько файлов ресурсов и подгружать тот, который содержит нудный язык. Но как это сделать?
Да и наверно лучше сделать один файл со всеми ресурсами(в смысле диалогами и т.д.)
и отдельно наклипать ресурсов с StringTable из которых уже и будут подгружатся Captions и строки ошибок. Данный способ хоть и более трудоемкий в начале, но мне кажется может уберечь от доп. работы в будущем, если прийдется менять какой-то диалог.
Я в правильном направлении двигаюсь, или я ошибаюсь, насчет технологии локализации???
Если в правильном, то как мне выбирать какой ресурс подгружать? Как выбрать ресурс?


--------------------
Think different ©Steve Jobs 
user posted image
PM MAIL WWW   Вверх
Fixin
Дата 28.1.2006, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



смутно догадываюсь, что ты хочешь распределить ресурсы в нескольких файлах по языкам и загружать их в зависимости от "локального" положения?

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

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

Вобщем, если чего, то разъясняй smile
PM MAIL ICQ   Вверх
devmstr
Дата 29.1.2006, 07:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 28.4.2004
Где: Ukraine

Репутация: нет
Всего: 11



Цитата(Fixin @ 28.1.2006, 20:51 Найти цитируемый пост)

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

Была такая идея, но хотелось попробовать данный способ.
Текстовый файл, это конечно хорошо, только я не хотел таскать за собой отдельные файлы...


--------------------
Think different ©Steve Jobs 
user posted image
PM MAIL WWW   Вверх
Fixin
Дата 29.1.2006, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



а в чем тогда проблема? сохраняй все в ресурсах.
PM MAIL ICQ   Вверх
Dem_max
Дата 16.7.2008, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



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

Будем исходить из того что все сообщения храняться в ресурсах, имеются 2 языка английский и русский. 
STRINGTABLE
LANGUAGE 0, 0
{
1000, "Cannot create file %s"
1001, "Cannot open file %s"
}


Вопрос что делать потом ? загружать Строки в текстовые переменные через LoadString, а потом уже работать с текстовыми переменными.

Возникает второй вопрос, как не перезапуская приложение можно сменить язык в нем, чтоб у всех кмпонентах поменялся язык отображения ? при условии что я перед этим загружу в текстовые переменные новый язык ? Реализацию MFC не предлагать, интересует метод для полностью API приложения.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
voov
Дата 16.7.2008, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Патамушта мы пилоты
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 29.11.2007

Репутация: нет
Всего: 8



Меня тоже интересует данный вопрос. Присоединяюсь к автору.
PM MAIL   Вверх
Dem_max
Дата 4.8.2008, 05:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



Смысл смены языка на лету примерно такой, хоть он мне и не нравиться,  создается класс туда во время создания кнопок, контролов и т.д помещяется хэндл этого контрола, и другая инфа,  этой функцией AddItem(......), когда нужно переключить язык вызывается Translate(int LangID).
Код

Language.h
//--------------------------------------------------------------
#include <vector.h>
#ifndef LANGUAGE_H
#define LANGUAGE_H
#define MAX_TXT         260

   enum ITEM_TYPE
   {
      STATIC,
      BUTTON,
      COMBOBOX,
      LISTBOX,
      TABCONTROL,
      MENUITEN
   };

class TGUITranslator
{

   typedef struct tagCONTROL_DATA
   {
      HWND hWndCtrl;
      ITEM_TYPE CtrlType;
      UINT CtrlStringID;
      WPARAM wParam;
      LPARAM lParam;
   } CONTROL_DATA, *PCONTROL_DATA;

   vector <PCONTROL_DATA> vControl;
   int ItemCount;
   TCHAR *strText;

public:

   TGUITranslator(){ItemCount = 0;}
   ~TGUITranslator(){vControl.clear(); ItemCount = 0;}
   virtual BOOL AddItem(ITEM_TYPE ItemType, HWND hWnd, UINT CtrlStringID, WPARAM wParam = 0, LPARAM lParam = 0);
   virtual BOOL Translate(int LangID);
   virtual BOOL GetTextItem(UINT CtrlID, int LangID, LPTSTR str);

protected:
   BOOL TranslateStatic(HINSTANCE hInstance, HWND pWnd, UINT CtrlStringID);
   BOOL TranslateButton(HINSTANCE hInstance, HWND pWnd, UINT CtrlStringID);
   //BOOL TranslateComboBox(HWND pWnd, UINT nStringId, WPARAM wParam);
   //BOOL TranslateListBox (HWND pWnd, UINT nStringId, WPARAM wParam);
   //BOOL TranslateListCtrl(HWND pWnd, UINT nStringId, WPARAM wParam, LPARAM lParam);
};
#endif
//-------------------------------------------------------------

Language.cpp
//--------------------------------------------------------------
#include <windows.h>
#include <vector.h>
#include <tchar.h>
#include "Language.h"



BOOL TGUITranslator::AddItem(ITEM_TYPE ItemType, HWND hWnd, UINT CtrlStringID, WPARAM wParam, LPARAM lParam)
{

   PCONTROL_DATA pCtrlData = new CONTROL_DATA;

   pCtrlData->CtrlType = ItemType;
   pCtrlData->wParam = wParam;
   pCtrlData->lParam = lParam;
   pCtrlData->hWndCtrl = hWnd;
   pCtrlData->CtrlStringID = CtrlStringID;

   vControl.push_back(pCtrlData);

   ItemCount++;
   return 0;
}

BOOL TGUITranslator::GetTextItem(UINT CtrlID, int LangID, LPTSTR str)
{
   UINT StrID = CtrlID + 10000 + LangID*1000;
   HINSTANCE hInstance = GetModuleHandle(NULL);
   LoadString(hInstance, StrID, str, MAX_TXT);
   return 0;
}

BOOL TGUITranslator::Translate(int LangID)
{
   PCONTROL_DATA pCtrlData = new CONTROL_DATA;

   HINSTANCE hInstance = GetModuleHandle(NULL);
   for (int i = 0; i < ItemCount; i++ )
   {
      pCtrlData = vControl[i];
      UINT StrID = pCtrlData->CtrlStringID + 10000 + LangID*1000;
      TCHAR *Txt_Message;
      Txt_Message = new TCHAR[50];
      wsprintf(Txt_Message, _T("StrID  %d"), StrID);
      delete Txt_Message;
      switch(pCtrlData->CtrlType)
      {
         case STATIC: TranslateStatic(hInstance, pCtrlData->hWndCtrl, StrID); break;
         case BUTTON: TranslateButton(hInstance, pCtrlData->hWndCtrl, StrID); break;
       /*
      case eComboBox:
          return TranslateComboBox(pCtrlData->pWnd, pCtrlData->nStringId, pCtrlData->wParam);
      case eListBox:
          return TranslateListBox(pCtrlData->pWnd, pCtrlData->nStringId, pCtrlData->wParam);
      case eListCtrl:
          return TranslateListCtrl(pCtrlData->pWnd, pCtrlData->nStringId, pCtrlData->wParam, pCtrlData->lParam);
      */
      }
   }
   //delete pCtrlData;
   return 0;
}

BOOL TGUITranslator::TranslateStatic(HINSTANCE hInstance, HWND hWnd, UINT CtrlStringID)
{
    strText = new TCHAR[MAX_TXT];
    LoadString(hInstance, CtrlStringID, strText, MAX_TXT);
    SetWindowText(hWnd, strText);
    delete strText;
    return TRUE;
}

BOOL TGUITranslator::TranslateButton(HINSTANCE hInstance, HWND hWnd, UINT CtrlStringID)
{
    strText = new TCHAR[MAX_TXT];
    LoadString(hInstance, CtrlStringID, strText, MAX_TXT);
    SetWindowText(hWnd, strText);
    delete strText;
    return TRUE;
}
//-----------------------------------------------------------------------


Посчитал что это не для меня, поскольку всетаки у меня приложение состоит из диалоговых окон то они запускаясь сами устанавливают нужный текст
Код

void CreateHashDialog(void)
{

   hWndDlgHash = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_HASH), hWndTabControl, (DLGPROC)DlgProc);

   // Вот тут задаю текст контролам 
   SetCtrlText(GetDlgItem(hWndDlgHash, IDC_USE_HASH), IDC_USE_HASH, Lang);
   SetCtrlText(GetDlgItem(hWndDlgHash, IDS_DATA_TEXT), IDS_DATA_TEXT, Lang);
   SetCtrlText(GetDlgItem(hWndDlgHash, IDS_METOD_TEXT), IDS_METOD_TEXT, Lang);
   SetCtrlText(GetDlgItem(hWndDlgHash, IDS_HASH_TEXT), IDS_HASH_TEXT, Lang);

}


Вот функции для установки текста находящегося в ресурсах и взятие текста из ресурсов (String Table)
Код

//---------------------------------------------------------------------------
BOOL SetCtrlText(HWND hWnd, UINT CtrlID, int LangID)
{
    UINT CtrlStringID = CtrlID + 10000 + LangID*1000;
    TCHAR *strText = new TCHAR[MAX_TXT];
    LoadString(hInstance, CtrlStringID, strText, MAX_TXT);
    SetWindowText(hWnd, strText);
    delete strText;
    return TRUE;
}
//---------------------------------------------------------------------------
BOOL GetCtrlText(UINT CtrlID, int LangID, LPTSTR strText)
{
   UINT CtrlStringID = CtrlID + 10000 + LangID*1000;
   LoadString(hInstance, CtrlStringID, strText, MAX_TXT);
   return TRUE;
}


String Table имеет такой формат для 2 языков, различия между языками в 1000, номер строки рассчитывается так UINT CtrlStringID = CtrlID + 10000 + LangID*1000;
Код

STRINGTABLE
LANGUAGE 25, 1
{
10101, "Выход"
10102, "Свернуть"
10103, "Настройки"

11101, "Exit"
11102, "Hide"
11103, "Settings"
}



Для диалогов которые не закрывается, делается функция SwitchLang которая занимается переключением языка на ходу, при этом в этих диалогах не задается текст контролов, а при завершения создания диалога вызывается функция сменить язык.
Код

BOOL SwitchLang(void)
{
   Txt_Message = new TCHAR[MAX_TXT];
   Txt_Message1 = new TCHAR[MAX_TXT];
   TCHAR *txt = new TCHAR[MAX_TXT];

   SetCtrlText(GetDlgItem(hWndMain, IDB_CLOSE), IDB_CLOSE, Lang);
   SetCtrlText(GetDlgItem(hWndMain, IDB_TRAY), IDB_TRAY, Lang);

   TCITEM tcItem;
   ZeroMemory(&tcItem, sizeof(tcItem));
   tcItem.mask = TCIF_TEXT;

   for(int i = 0; i < 4; i++)
   {
      GetCtrlText(IDS_SETTINGS + i, Lang, Txt_Message);
      tcItem.pszText = Txt_Message;
      TabCtrl_SetItem(hWndTabControl, i, &tcItem);
   }

   if(hWndDlgMain)
   {
      SetCtrlText(GetDlgItem(hWndDlgMain, IDB_START_UDP), IDB_START_UDP, Lang);
      SetCtrlText(GetDlgItem(hWndDlgMain, IDB_STOP_UDP), IDB_STOP_UDP, Lang);

   }

   delete Txt_Message;
   delete Txt_Message1;
   delete txt;
   return TRUE;
}


Примерно так, более изящьного решения никто не подсказал.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0485 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.