| Chernov | 
| Отправлено: 18.08.2006, 15:37 | 
 
 
 | 
 
 
  
Ученик-кочегар 
 
Группа: Участник 
Сообщений: 13 
  
  
 | 
 Ничего подобного не нашел, и написал сам. Вдруг кому надо. 
В эту функцию передается указатель на форму, например this из CreateForm 
| CODE  |   
void TranslateF(TForm * Form) 
{ 
 if(Form) 
 { 
   Form->Position=poScreenCenter;//Позиционирование окна на центр экрана 
   AnsiString cap=Form->Caption; 
   int cou=Form->ComponentCount; 
   for(int i=0;i<cou;i++)   //По всем компонентам на форме 
   {
  
     if(Form->Components[i]->ClassNameIs("TLabel")) 
     ((TLabel *)(Form->Components[i]))->Caption=Trans(cap,((TLabel *)(Form->Components[i]))->Caption);
  
     if(Form->Components[i]->ClassNameIs("TButton")) 
     ((TButton *)(Form->Components[i]))->Caption=Trans(cap,((TButton *)(Form->Components[i]))->Caption); 
   } 
 } 
} 
 |  
 
  
Эта функция возвращает перевод слова в зависимости от указанного файла словаря. Здесь берется из реестра. Словарь это обычный ini файл. 
конструкция такая 
[Название формы] 
Название кнопки=перевод 
Если названия формы не существует берет из словаря 
[General] 
| CODE  |   
AnsiString Trans(AnsiString cap,AnsiString word) 
{ 
TRegistry * fReg = new TRegistry(KEY_READ); 
fReg->OpenKey("\\Software\\vasale", true); 
AnsiString fn=fReg->ReadString("TranslateFile");   //INI-файл в котором храниться перевод 
AnsiString res=word; 
if (word.Length()>0) 
{ 
 TIniFile * IniFile=new TIniFile(fn); 
 res=IniFile->ReadString("General",word,res);   //Сперва просматривает раздел General 
 if (cap.Length()>0) 
 res=IniFile->ReadString(cap,word,res); //Перевод по разделу, зависимому от заголовка формы 
 delete IniFile; 
} 
return res; 
}  |  
 
  
припер ini-файла: 
| CODE  |   
[General] 
New=Nuevo 
Groups=Grupos 
Select direction=Seleccione Destino 
Touroperators=Touroperadores 
Hotels=Hoteles 
Places in Hotels=Cupo en Hoteles 
Rates=Cambio 
Trips=Vuelos 
Transfers=Transfers 
Сalculate package=Calculo del paquete 
Users=Usuarios 
Print Policy=Imprimir Poliza 
OK=OK 
Password=Contraseca |  
  
Это перевод на испанский. Не знаю на сколько точный.
 | 
 
  | 
 
| AVC | 
| Отправлено: 18.08.2006, 16:19 | 
 
 
 | 
 
  
Ветеран 
 
Группа: Модератор 
Сообщений: 1583 
  
  
 | 
 Пара замечаний. 
1. Если вы думаете, что обходите все компоненты формы, то вы заблуждаетесь (пример TPanel). 
2. Проверяя на ClassName вы находите объекты данного класса, но не их наследников (это самое существенное для данного кода отличие от dynamic cast)
  
Мой пример: так проставляются стили всем нужным компонентам формы 
| CODE  |   
extern bool __fastcall SetStyleForm (TForm* ); 
extern bool __fastcall SetStyleDBGrid (TDBGrid* ); 
extern bool __fastcall SetStyleDrawGrid (TDrawGrid* ); 
extern bool __fastcall SetStyleDBEdit (TDBEdit* ); 
extern bool __fastcall SetStyleDBMemo (TDBMemo* ); 
extern bool __fastcall SetStyleEdit (TEdit* ); 
extern bool __fastcall SetStyleMemo (TMemo* ); 
extern bool __fastcall SetStyleMemo (TRichEdit* ); 
extern bool __fastcall SetStyleMaskEdit (TMaskEdit* ); 
extern bool __fastcall SetStyleDBText (TDBText* ); 
extern bool __fastcall SetStylePanelBmp (TPanelBmp* ); 
extern bool __fastcall SetStylePanel (TPanel* ); 
extern bool __fastcall SetStyleLabelS (TLabelS* ); 
extern bool __fastcall SetStyleLabel (TLabel* ); 
extern bool __fastcall SetStyleButton (TButton* ); 
extern bool __fastcall SetStyleBitBtn (TBitBtn* ); 
extern bool __fastcall SetStyleStatusBar (TStatusBar* ); 
extern bool __fastcall SetStyleTileBmp (TTileBmp* );
  
//--------------------------------------------------------------------------- 
// Обход всех подчиненных объектов и расстановка стилей 
//---------------------------------------------------------------------------
  
PACKAGE void __fastcall SetStyle (TObject *obj) 
{ 
TControl *control = dynamic_cast<TControl*>(obj); 
if (!control) return;
  
if (SetStyleLabelS (dynamic_cast<TLabelS*> (control)) ); 
else if (SetStyleLabel (dynamic_cast<TLabel*> (control)) );
  
else if (SetStyleMaskEdit (dynamic_cast<TMaskEdit*> (control)) ); 
else if (SetStyleDBEdit (dynamic_cast<TDBEdit*> (control)) ); 
else if (SetStyleDBMemo (dynamic_cast<TDBMemo*> (control)) ); 
else if (SetStyleDBText (dynamic_cast<TDBText*> (control)) ); 
else if (SetStyleMemo (dynamic_cast<TMemo*> (control)) ); 
else if (SetStyleMemo (dynamic_cast<TRichEdit*> (control)) ); 
else if (SetStyleEdit (dynamic_cast<TEdit*> (control)) );
  
else if (SetStyleDBGrid (dynamic_cast<TDBGrid*> (control)) ); 
else if (SetStyleDrawGrid (dynamic_cast<TDrawGrid*> (control)) );
  
else if (SetStyleBitBtn (dynamic_cast<TBitBtn*> (control)) ); 
else if (SetStyleButton (dynamic_cast<TButton*> (control)) );
  
else if (SetStyleStatusBar (dynamic_cast<TStatusBar*>(control)) );
  
else if (SetStylePanelBmp (dynamic_cast<TPanelBmp*> (control)) ); 
else if (SetStylePanel (dynamic_cast<TPanel*> (control)) );
  
else if (SetStyleTileBmp (dynamic_cast<TTileBmp*> (control)) );
  
else if (SetStyleForm (dynamic_cast<TForm*> (control)) ); 
else ;
  
TWinControl *wcontrol = dynamic_cast<TWinControl*>(control); 
if (!wcontrol) return;
  
for (int i = 0; i < wcontrol->ControlCount; i++) 
SetStyle (wcontrol->Controls[i]);
  
}
  
//---------------------------------------------------------------------------
  
bool __fastcall SetStyle__???__ (T??? *obj) 
{ 
if (!obj) return false; 
... 
return true;
  
//--------------------------------------------------------------------------- 
 |  
  
Возможный вызов SetStyle(Form1);
  
Извините за ложку дёгтя.  
  
Отредактировано AVC — 18/08/2006, 15:22  | 
 
  | 
 
| Shagg | 
| Отправлено: 19.08.2006, 07:22 | 
 
 
 | 
 
  
Дежурный стрелочник 
 
Группа: Участник 
Сообщений: 69 
  
  
 | 
 Рекурсивная функция, расставляющая кэпшны для всех контролов: 
| CODE  |  void __fastcall SetChildCaption(TWinControl *Parent) 
{ 
 TControl *Child; 
 int i; 
 for (i=0; i<Parent->ControlCount; i++) 
 { 
   Child = Parent->Controls[i]; 
   if (Child->ClassNameIs("TPanel")) 
   { 
     dynamic_cast<TPanel*>(Child)->Caption = IntToStr(i*i); 
     SetChildCaption(dynamic_cast<TWinControl*>(Child)); 
   } 
   else if (Child->ClassNameIs("TButton")) 
     dynamic_cast<TButton*>(Child)->Caption = IntToStr(i*i); 
   else if (Child->ClassNameIs("TEdit")) 
     dynamic_cast<TEdit*>(Child)->Text = IntToStr(i*i); 
   else if (Child->ClassNameIs("TLabel")) 
     dynamic_cast<TLabel*>(Child)->Caption = IntToStr(i*i); 
 } 
} |     | 
 
  | 
 
| Chernov | 
| Отправлено: 21.08.2006, 10:48 | 
 
 
 | 
 
 
  
Ученик-кочегар 
 
Группа: Участник 
Сообщений: 13 
  
  
 | 
 Спасибо. 
Я так и не понял, что такое dynamic cast, но переписал все следующим образом. 
| CODE  |   
void TranslateF(TForm * Form) 
{ 
 if(Form) 
 { 
   Form->Position=poScreenCenter;//Позиционирование окна на центр экрана 
   AnsiString cap=Form->Caption; 
   int cou=Form->ComponentCount; 
   for(int i=0;i<cou;i++)   //По всем компонентам на форме 
   { 
     TranslateComponent(cap,Form->Components[i]); 
   } 
 } 
}
 
  
void TranslateControl(AnsiString cap, TWinControl * Control) 
{ 
 if(Control) 
 { 
   int cou=Control->ControlCount; 
   for(int i=0;i<cou;i++)   //По всем компонентам на форме 
   { 
     if(Control->ClassNameIs("TPageControl"))TranslateComponent(cap,((TPageControl*)Control)->Controls[i]); 
   } 
 } 
}
  
void TranslateComponent(AnsiString cap, TComponent * Component) 
{ 
     if(Component->ClassNameIs("TLabel")) 
       ((TLabel *)(Component))->Caption=Trans(cap,((TLabel *)(Component))->Caption); 
     if(Component->ClassNameIs("TButton")) 
       ((TButton *)(Component))->Caption=Trans(cap,((TButton *)(Component))->Caption);
  
     if(Component->ClassNameIs("TTabSheet")) 
       ((TTabSheet *)(Component))->Caption=Trans(cap,((TTabSheet *)(Component))->Caption); 
     if(((TWinControl *)Component)->ControlCount) 
       TranslateControl(cap,(TWinControl *)(Component)); 
} 
 |  
  
И по аналогии с TPageControl c TPanel можно сделать и прочее прочее прочее
 | 
 
  | 
 
| AVC | 
| Отправлено: 21.08.2006, 11:26 | 
 
 
 | 
 
  
Ветеран 
 
Группа: Модератор 
Сообщений: 1583 
  
  
 | 
 | QUOTE  |   
Я так и не понял, что такое dynamic cast, но переписал все следующим образом. 
 |  
  
Грубо говоря это попытка проверки "а приводим ли данный указатель к данному типу?" во время выполнения приложения. В данном случае основное отличие от ClassNameIs заключается в том, что ClassNameIs проверяет только на соответствии самому последнему из потомков. На практике это означает следующее: 
Допустим я создал свой компонент на базе TLabel и назвал его TLabelS 
Так вот для ClassNameIs 
| CODE  |   
"TLabelS" -> true 
"TLabel"  -> false 
... 
"TComponent" -> false 
"TObject" -> false 
 |  
 
  
а для dynamic_cast (если считать NULL как false а не NULL как true) 
| CODE  |   
<TLabelS*> -> true 
<TLabel*>  -> true 
... 
<TComponent*> -> true 
<TObject*> -> true 
 |  
  
А это означает, что если для чего то мне нужно свойство наследуемое от TLabel, то выгоднее писать dynamic_cast и не забивать себе голову, что я могу создать для разных слусаев разных потомков от TLabel, потомков от потомков и т.д. В случае d_c код переделывать не придется, а в случае использования ClassNameIs придется при определении каждого нового потомка.
  
| QUOTE  |   
И по аналогии с TPageControl c TPanel можно сделать и прочее прочее прочее 
 |  
  
Зачем когда написав так можно вообще навсегда забыть о том что есть всякие Panel и прочее, прочее, прочее
  
TWinControl *wcontrol = dynamic_cast(control); 
if (!wcontrol) return;
  
for (int i = 0; i < wcontrol->ControlCount; i++) 
Функция_обрабатывающая_текущий_контрол (wcontrol->Controls[i]); 
 | 
 
  | 
 
  |