Novo

Forum kao aplikacija na telefonu

Dodajte forum na početni ekran i koristite ga kao aplikaciju, sa menijem na dnu ekrana.

  • 24 odgovora
  • 6.941 pregleda

Najnovija ↓

Promena jezika celog programa 03.11.2011. u 19:02 · pre 182 meseca #1
Imam zadatak uraditi neku aplikaciju ali ta aplikacija da ima mogucnost promenu jezika (pr. Menu->Jezik->SR, MKD, EN). Jer moze neka solucija kako to da odradim, dali da ima neki ini fajl gde pise koji jezik treba da podigne (pri startovanje app) pa u zavisnost od toga od drugi ini fajl da ocitava svaki "caption" elementa unutar aplikacije. Pri prvo podizanje programa bi imo da izabere koji jezik zeli, onda svako drugo podizanje preograma pravicu sporedbu jezika pri zadnje otvaranje i zatvaranje applikacije...Valjda ovo nije najbolje resenje :) Ako ima neka bolja ideja. Hvala
Re: Promena jezika celog programa 03.11.2011. u 19:53 · pre 182 meseca #2
Jedan problem je gde čuvati informaciju o jeziku apikacije. Ovo je sitan problem. Može .ini fajl, može registry (moj omiljen), može čak i baza (ako u bazi već čuvaš i neke druge stvari).

Drugi problem je kako u birati različite jezike ako već imaš informaciju o jeziku. Ovo je malo veći problem. Prva stvar koja apsolutno olakšava rešenje problema je da aplikacija bude Unicode. Dalje, u Visual C++ okruženju (sa ili bez MFC-a) možeš da imaš takozvane resursne DLL-ove (resource DLL). Ovi DLL-ovi nemaju ni jednu funkciju, ali zato imaju string tabele, prozore, menije, ikone, i sve ostalo. Možeš za svaki jezik da napraviš jedan DLL, i na početku rada učitaš željeni DLL i ostatku programa kažeš da za sve što im treba od resursa vide u tom DLL-u.

Drugo rešenje bi bilo da imaš nekakav xml fajl za svaki jezik, i da u celom programu u letu radiš čitanje stringova iz odgovarajućeg fajla, i zamenu default teksta u prozorim i menijima. Morao bi u prozorima da zauzmeš više mesta za sve labele, za slučaj da na nekom jeziku neka labela zauzima više mesta. Ja nikad nisam ovako radio, ali tako je sad popularno u svetu.
Sviđa mi se1
Re: Promena jezika celog programa 03.11.2011. u 21:03 · pre 182 meseca #4
Ovaj kod (X Files sto je dao) je dosta dobar (bar tako se meni cini) podesi ti keybord, code page za zeljeni jezik i na sve elemente promeni napise...samo imam jedan nejasan deo koda

Code:

// MyStrings.rh                                                              
#define   IDS_CANCEL             27114 

// Strings.rc                                                            
#pragma code_page(1252) 
#include "MyStrings.rh" 

STRINGTABLE 
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 
BEGIN 
  IDS_CANCEL, "Cancel" 
END 

STRINGTABLE 
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT 
BEGIN 
  IDS_CANCEL, "Zrusit" 
END 


Sada nisam toliko uputen bar nisam to jos izucio/cuo :S MyString.rh je? (Samo fajl u koi definisem sve "objekte"? ili) Isto tako String.rc to je neki resource fajl ili? u njega ukljucim MyString...Ako moze samo malo objasnenja ili tekst negde da procitam sto je to ustvari. Hvala

@mihajlo
Kako birati, po default ce se startuje sa nekim jezikom, onda biras to sto tebi odgovara i opet stavis u rg...svako sledece startovanje samo gledas koi je jezik i spored toga citas i reg :D (ako si na to mislio) :D Hvala vam na brzom odgovoru
Re: Promena jezika celog programa 04.11.2011. u 07:45 · pre 182 meseca #6
Citat:
MyString.rh je?

MyString.rh je obican tekstualni fajl, u kome se definise identifikator stringa i jedinstveni broj.

Citat:
Isto tako String.rc to je neki resource fajl ili?

String.rc je klasican resursni fajl, koji u nasem primeru sadrzi uglavnom sadrzaj stringova, definisanih preko identifikatora. Ovaj fajl treba DODATI U PROJEKAT (Add to Project).


Pokušaću da ti uradim jedan test primer u vezi ovoga, samo da pronađem makar malo vremena...
Sviđa mi se1
Re: Promena jezika celog programa 04.11.2011. u 10:03 · pre 182 meseca #7
--- RSTRINGS.RH (tekstualni fajl, sam ga kreiras) ---
Code:

#define IDS_FORM1    10000
#define IDS_BUTTON1  10001 
#define IDS_LABEL1   10002


--- RSTRINGS.RC (tekstualni fajl, sam ga kreiras i DODAJES u projekat) ---
Code:

#pragma code_page(1252)
#include "RStrings.RH"

STRINGTABLE
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
BEGIN
  IDS_FORM1,   "My form"
  IDS_BUTTON1, "My button"
  IDS_LABEL1,  "My label"
END

STRINGTABLE
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
BEGIN
  IDS_FORM1,   "Moja forma"
  IDS_BUTTON1, "Moj taster"
  IDS_LABEL1,  "Moj natpis"
END


--- PROJECT1.INI (tekstualni fajl za cuvanje informacije o izabranom jeziku, ne moras da pravis, bice autokreiran) ---
Code:

[Language]
ID=1


--- UNIT1.H (ovo je generisano u IDE-u, uz izmene koje sam uoci)---
Code:

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <IniFiles.hpp>

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TButton *Button1;
        TLabel *Label1;
        void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
        TIniFile *pIniFile;
        int IDLanguage;
        void PromeniJezik();

public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
        __fastcall ~TForm1();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif



--- UNIT1.CPP ---
Code:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "RStrings.RH"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
    try
    {
        pIniFile = new TIniFile( ChangeFileExt( ParamStr(0), ".ini" ) );
        IDLanguage = pIniFile->ReadInteger( "Language", "ID", 0 );
    }
    catch ( const Exception &e )
    {
        IDLanguage = 0;
    }

    if ( pIniFile )
        delete pIniFile;

    PromeniJezik();
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
    try
    {
        pIniFile = new TIniFile( ChangeFileExt( ParamStr(0), ".ini" ) );
        pIniFile->WriteInteger( "Language", "ID", IDLanguage );
    }
    catch ( const Exception &e )
    {
        // ...
    }
    if ( pIniFile )
        delete pIniFile;

}
//---------------------------------------------------------------------------
static const TFontCharset CodepageToCharset( unsigned int cp )
{
   CHARSETINFO csi;

   if ( (cp == 0) || (!TranslateCharsetInfo( (unsigned long *)cp, &csi, TCI_SRCCODEPAGE )) )
   {
     return OEM_CHARSET;
   }
   return (TFontCharset)csi.ciCharset;
}
//---------------------------------------------------------------------------
static AnsiString InternalLoadStr( int ErrorCode )
{
   const int MaxResourceBufferSize = 4096;  // maximum resource string length is 4095 bytes
   char string[MaxResourceBufferSize];
   LoadString( GetModuleHandle(0), ErrorCode, string, MaxResourceBufferSize );
   return AnsiString( string );
}
//---------------------------------------------------------------------------
void TForm1::PromeniJezik()
{
    int CP;
    if ( IDLanguage == 0 )
    {
       SetThreadLocale( 0x0409 );  // U.S. English
       CP = 1250;
    }
    else
    {
       SetThreadLocale( 0x0405 );  // Czech local
       CP = 1252;
    }

    Form1->Font->Charset = CodepageToCharset( CP );
    Form1->Caption = InternalLoadStr( IDS_FORM1 );

    Button1->Font->Charset = CodepageToCharset( CP );
    Button1->Caption = InternalLoadStr( IDS_BUTTON1 );

    Label1->Font->Charset = CodepageToCharset( CP );
    Label1->Caption = InternalLoadStr( IDS_LABEL1 );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if ( IDLanguage == 1 )
        IDLanguage = 0;
    else
        IDLanguage = 1;

    PromeniJezik();
}
//---------------------------------------------------------------------------



E sad, tragedija je da ja tebe savetujem da radis ovako, kako je proizvodjac softvera i predvideo, a ja sam ne radim ovako :) Osnovna anomalija ovakvog koda je hardcode-iranost prevoda, tj nemogucnost dodavanja novog jezika BEZ rekompajliranja koda.

Tvoja kreativnost se sada moze ogledati u smestanju prevoda u neke zasebne fajlove i sl.

Za sada, poneta ovog koda je da vidis:
- kako se cuvaju konfiguraciona podesavanja u INI fajlovima. Slicno je i za Regystry.
- Kako se menja jezik

Sviđa mi se1
Re: Promena jezika celog programa 04.11.2011. u 11:28 · pre 182 meseca #8
Off topic:

Qt ima alat Qt Linguist za jednostavno pravljenje prevoda (pravljen za prevodioce koji nisu programeri) koji nisu hardkodovani.
Potpis
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
Re: Promena jezika celog programa 04.11.2011. u 13:16 · pre 182 meseca #9
Razgledao sam kod, od ujutru par puta sam piso (dok si postiro kod) kod i nekako slabo. Sad mi je jasno kako to uradito recimo samo sa ini fajlovima, ali sada me nervira sto ovaj kod kod mene ne funkcionise t.e neizvrsava se. Uvek "otvara" LANG_ENGLISH idetifikator i kad je ID=0 i kad je ID=1. A i kad promenim drugi idetifikator (tacnije LANG_MACEDONIAN) daje mi error na njega...sve sam odradio kako u kodu?
Re: Promena jezika celog programa 04.11.2011. u 13:29 · pre 182 meseca #10
Stvarno ne znam o čemu se radi. Kod sam probao i radio je, mada ga nisam detaljnije testirao. Pamtio je promenu i startovao se onako kako je poslednji put podešeno. Sada ne mogu da ti ga pošaljem u celosti, jer nisam trenutno na računaru na kome sam ga uradio.

Što se tiče ćirilice (LANG_MACEDONIAN), pokušaj neku drugu, možda Rusku varijantu...

Pretpostavljam da su ovi fajlovi odgovorni za jezičke konstante:
c:\Program Files\Borland\CBuilder6\Include\winnt.h
c:\Program Files\Borland\CBuilder6\Include\winnt.rh

Pokušaj da uključiš (include) nešto of ovoga ispod linije:
#include "RStrings.RH"
...ili jednostavno redefiniši (define) prema specifikaciji koja je u ovim fajlovima.
Re: Promena jezika celog programa 04.11.2011. u 21:24 · pre 182 meseca #13
Ok, sve ovo je dokaz da treba ići ka novijim rešenjima što se tiče višejezičke podrške.

Kod koji sam inicijalno ostavio, radiće na XP-u, ali neće na novijim OS-ovima.


Da bi se to prevazišlo, jedno od rešenja je sledeće. Treba napraviti posebnu funkciju, koja će utvrditi tip OS-a, i prema tome reagovati:
Code:

void SetThreadLocalSettings(LANGID Language, LANGID SubLanguage)
{

   OSVERSIONINFOEX osver;
   ZeroMemory(&osver, sizeof(osver));
   osver.dwOSVersionInfoSize = sizeof(osver);

   GetVersionEx((OSVERSIONINFO *)&osver);


   if ( (osver.dwMajorVersion > 5))
   {
      typedef LANGID (WINAPI *FNSetThreadUILanguage)(LANGID wReserved);
      FNSetThreadUILanguage fnPtr = (FNSetThreadUILanguage)GetProcAddress(GetModuleHandle("kernel32.dll"),"SetThreadUILanguage");
      // ako ovo gore nece da se kompajlira, pokusaj ovako:
      // FNSetThreadUILanguage fnPtr = (FNSetThreadUILanguage)GetProcAddress(GetModuleHandle(_T("kernel32.dll")),"SetThreadUILanguage");

      if(fnPtr)
      { // vista or 2008
         LANGID langid = (*fnPtr)(Language);
      }
      else
      { // fallback for XP
         ::SetThreadLocale(MAKELCID(MAKELANGID(Language, SubLanguage), SORT_DEFAULT));
      }
   }
   else
   { //XP
      ::SetThreadLocale(MAKELCID(MAKELANGID(Language, SubLanguage), SORT_DEFAULT));
   }
}


... i zatim, umesto:
Citat:

Code:

    int CP;
     if ( IDLanguage == 0 )
     {
        SetThreadLocale( 0x0409 );  // U.S. English
        CP = 1250;
     }
     else
     {
        SetThreadLocale( 0x0405 );  // Czech local
        CP = 1252;
     }


Treba:
Code:

    int CP;
     if ( IDLanguage == 0 )
     {
        SetThreadLocalSettings( 0x0409, SUBLANG_ENGLISH_US );  // U.S. English
        CP = 1250;
     }
     else
     {
        SetThreadLocalSettings( 0x0405, SUBLANG_DEFAULT );  // Czech local
        CP = 1252;
     }

Sviđa mi se1
Re: Promena jezika celog programa 04.11.2011. u 22:32 · pre 182 meseca #14
Ovo radi i to dobro, zadatak koi smo imali bio je nad 1000 objekta (button, panel, label i.t.d) da promenimo caption...ispisali smo oko 800. Od klika do izmene ne proge ni sekunda :)...e sada one funkcije sam razumeo, ali ova nemam pojma sta radi :)) Hvala ti X Files
Re: Promena jezika celog programa 04.11.2011. u 23:19 · pre 182 meseca #15
Ali opet se vracam kod idetifikatora, javlja gresku kod ruskog, srpskog, makedonskog...pogledao sam winnt.h i winnt.rh i tamo su tako definisani a opet izadje error?

Code:

[BRCC32 Error] Strings.rc(13): Not a positive short integer
Re: Promena jezika celog programa 05.11.2011. u 00:04 · pre 182 meseca #16
Dodaj:
#include "Winnt.RH"
... u RStrings.RC


Za "Serbian Latin":

--- RStrings.RC ---
Code:

#pragma code_page(1252)
#include "RStrings.RH"
#include "Winnt.RH"

 STRINGTABLE
 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 BEGIN
   IDS_FORM1,   "My form"
   IDS_BUTTON1, "My button"
   IDS_LABEL1,  "My label"
 END

 STRINGTABLE
 LANGUAGE LANG_SERBIAN, SUBLANG_SERBIAN_LATIN
 BEGIN
   IDS_FORM1,   "Moja forma"
   IDS_BUTTON1, "Moj taster"
   IDS_LABEL1,  "Moj natpis"
 END


--- UNIT1.CPP ---
Code:

// ...
     int CP;
     if ( IDLanguage == 0 )
     {
        SetThreadLocalSettings( 0x0409, SUBLANG_ENGLISH_US );  // U.S. English
        CP = 1250;
     }
     else
     {
        SetThreadLocalSettings( 0x081a, SUBLANG_DEFAULT );  // Serbian Latin
        CP = 1252;
     }

// ...
Sviđa mi se1
Re: Promena jezika celog programa 05.11.2011. u 00:25 · pre 182 meseca #17
To sam vec odradio...samo trazim kako kirilicu da uklopim, idetifikator stavim code page za kirilicu je 1251 ama izlaze prasalnici :D trazicu gde je cakica :D
Re: Promena jezika celog programa 05.11.2011. u 00:54 · pre 182 meseca #18
Zezao me je idetifikator za sublanguage...trebalo bi ovako da bude (ako nekom pocetniku kako mene zatreba) X Files hvala ti mnogo

--- RStrings.RC ---
Code:

#pragma code_page(1252)
#include "RStrings.RH"
#include "winnt.rh"

STRINGTABLE
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
BEGIN
  IDS_FORM1,   "My form"
  IDS_BUTTON1, "My button"
  IDS_LABEL1,  "My label"
END

STRINGTABLE
LANGUAGE LANG_MACEDONIAN, SUBLANG_MACEDONIAN_MACEDONIA
BEGIN
  IDS_FORM1,   "Moja Forma"
  IDS_BUTTON1, "Batonče"
  IDS_LABEL1,  "LjNjEЅŠЃŽZDžČЌ"
END


--- UNIT1.CPP ---
Code:

int CP;
    if ( IDLanguage == 0 )
    {
       SetThreadLocalSettings( 0x0409, SUBLANG_ENGLISH_US );  // U.S. English
       CP = 1250;
    }
    if ( IDLanguage == 1 )
    {
       SetThreadLocalSettings( 0x042F, SUBLANG_MACEDONIAN_MACEDONIA );  // MKD
       CP = 1251;
    }



Re: Promena jezika celog programa 05.11.2011. u 11:23 · pre 182 meseca #19
Eto, lepo ako je proradilo.

Ipak, u perspektivi razmisli o tome da prevode držiš u sasvim zasebnim tekstualnim fajlovima, odvojenim od EXE-a ili DLL-a, tj. da budu "otvoreni" za editovanje spolja. Praksa je pokazala da je ovo praktičnije od rešenja koja se nude u okviru ekstenzija razvojnog okruženja. Na primer, pogledaj kako je to rešeno u ozbiljnijim softverima, tipa Total Commander-a...
Re: Promena jezika celog programa 05.11.2011. u 12:09 · pre 182 meseca #20
Dok sam radio sa ovim kodom probo sam problem resiti sa ini, to mi je dobro ispalo, u jednim fajlom cuvam id jezika u drugi ini prevode i u zavisnost sta odberem to citam. E sada kod mene "current language for non-unicode programs" stoi MKD...nisam proverio da smenim to pa da vidim kako bi radilo onda. Sto sa ovim kodom sto si ti postirao to je zaobidjeno...
Odgovori
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme