Localizarea în Visual C: Diferență între versiuni
Admin (Discuție | contribuții) m (→Cum convertesc dintr-un string in altul) |
(→Cum convertesc dintr-un string în altul) |
||
(Nu s-au afișat 13 versiuni intermediare efectuate de alți 2 utilizatori) | |||
Linia 1: | Linia 1: | ||
− | |||
− | |||
== Introducere == | == Introducere == | ||
− | Am | + | Am în mentenanţă o aplicaţie MFC, veche de 7 ani şi de curând am putut să renunţ la suportul pentru Win9x şi am început trecerea aplicaţiei la Unicode. |
− | Acum pot | + | Acum pot să recomand oricui vrea, să internaţionalizeze/localizeze, să folosească librăria gettext din următoarele motive: |
* mentenanţa fişierelor de localizare este incomparabil mai uşoară | * mentenanţa fişierelor de localizare este incomparabil mai uşoară | ||
* există orice fel de unelte de localizare pentru fişiere gettext (.PO) | * există orice fel de unelte de localizare pentru fişiere gettext (.PO) | ||
Linia 10: | Linia 8: | ||
== Trecerea aplicației la Unicode == | == Trecerea aplicației la Unicode == | ||
− | Unii o pot considera | + | Unii o pot considera inutilă, dar experienţa mea spune că merită să renunţi la Win9x și să treci la Unicode. Cel puțin, scapi de problema codepage-urilor. |
− | + | Începeţi prin a înlocui tipurile de date și apelurile la funcții cu următoarele alternative, care de fapt sunt toate macro-uri, care se compilează diferit, în funcție de target. Această fază nu vă va 'strica' aplicaţia şi veţi putea să faceţi build-uri separate. | |
Nu uitați să faceți un branch separat înainte de a începe, s-ar putea să dureze de 3X mai mult decât credeți, acum depinde de când și de cine a fost scrisă aplicația inițial. | Nu uitați să faceți un branch separat înainte de a începe, s-ar putea să dureze de 3X mai mult decât credeți, acum depinde de când și de cine a fost scrisă aplicația inițial. | ||
<pre> | <pre> | ||
− | char | + | char _TCHAR |
LPSTR LPTSTR | LPSTR LPTSTR | ||
LPCSTR LPCTSTR | LPCSTR LPCTSTR | ||
Linia 32: | Linia 30: | ||
sscanf _stscanf | sscanf _stscanf | ||
wsprintf _tcs | wsprintf _tcs | ||
− | atoi | + | atoi _tstoi |
− | itoa | + | itoa _itot_s |
− | sscanf | + | sscanf _stscanf |
vsprintf _vstprintf | vsprintf _vstprintf | ||
− | fopen | + | fopen _tfopen |
fputs _fputs | fputs _fputs | ||
− | fclose | + | fclose _tfclose |
</pre> | </pre> | ||
<source lang="c"> | <source lang="c"> | ||
− | /* Cum Bill cam uită să ducă treaba la bun sfârşit a uitat de (w)sprintf aşa că adăugaţi şi asta într-un H*/ | + | /* Cum Bill cam uită să ducă treaba la bun sfârşit, a uitat de (w)sprintf aşa că adăugaţi şi asta într-un H*/ |
#ifdef UNICODE | #ifdef UNICODE | ||
#define _tsprintf wsprintf | #define _tsprintf wsprintf | ||
Linia 53: | Linia 51: | ||
=== Ceva mai puţin evident despre ..prinf(...) === | === Ceva mai puţin evident despre ..prinf(...) === | ||
− | + | Funcţiile din gama printf, pot primi ca parametrii atât char, w_char cât şi t_char aşa că **trebuie** ajutate să-şi dea seama ce primesc | |
<pre> | <pre> | ||
Apel build unicode build ne-unicode alias | Apel build unicode build ne-unicode alias | ||
Linia 67: | Linia 65: | ||
<pre> | <pre> | ||
− | W2A și CW2A | + | W2A(...) și CW2A(...) |
− | A2T și CA2T | + | A2T(...) și CA2T(...) |
− | T2A și CT2A | + | T2A(...) și CT2A(...) |
</pre> | </pre> | ||
Linia 77: | Linia 75: | ||
* A - ASCII | * A - ASCII | ||
− | Nu uitați | + | Nu uitați că ''nu le puteți folosi oricum'', deoarece fac niște hack-uri cam nasoale. Dacă vreți să le folosiți citiți '''neapărat''' înainte |
* http://codexpert.ro/forum/viewtopic.php?f=23&t=149&p=650&hilit=CW2A#p650 | * http://codexpert.ro/forum/viewtopic.php?f=23&t=149&p=650&hilit=CW2A#p650 | ||
* http://codexpert.ro/forum/viewtopic.php?f=14&t=416&p=2426&hilit=ct2a#p2426 | * http://codexpert.ro/forum/viewtopic.php?f=14&t=416&p=2426&hilit=ct2a#p2426 | ||
Linia 106: | Linia 104: | ||
=== ... === | === ... === | ||
− | + | Descărcaţi: | |
* <tt>gettext-runtime</tt> (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/gettext) | * <tt>gettext-runtime</tt> (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/gettext) | ||
* <tt>libiconv</tt> (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/libiconv) | * <tt>libiconv</tt> (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/libiconv) | ||
− | Ar trebui | + | Ar trebui să ştiţi că, implicit, gettext întoarce textele în UTF-8, ceea ce este foarte bine, mai puţin pentru Windows, care foloseşte în modul Unicode (UTF16-LE), aşa că trebuie să le convertiţi la runtime (oricum e suficient de rapidă conversia). |
<source lang="cpp"> | <source lang="cpp"> | ||
Linia 123: | Linia 121: | ||
== Extragerea textelor == | == Extragerea textelor == | ||
− | Extragerea textelor din | + | Extragerea textelor din fişierele .C si .CPP este extrem de uşoară, folosind <tt>xgettext</tt>, dar când veţi ajunge la fişierele <tt>.RC</tt>, o să descoperiţi că nu sunt suportate. Din fericire, după multe încercări nereuşite, am găsit singur o soluţie simplă |
<source lang="bash">xgettext --from-code=UTF-8 --add-comments --omit-header --no-location \ | <source lang="bash">xgettext --from-code=UTF-8 --add-comments --omit-header --no-location \ | ||
Linia 130: | Linia 128: | ||
</source> | </source> | ||
− | Sau pe scurt: | + | Sau pe scurt: întrucât sintaxa Tcl e destul de compatibilă cu cea din .RC, folosind keyword-urile respective, obţineţi un parser de .RC în xgettext. Cool?... o să trimit şi un mail ca să modifice să recunoască fişierele rc direct. |
+ | |||
− | |||
== [[Legături|Legături]] == | == [[Legături|Legături]] == | ||
* http://www.gnu.org/software/gettext/ - de citit cu atenţie | * http://www.gnu.org/software/gettext/ - de citit cu atenţie | ||
− | * http://taossa.com/index.php/2007/01/09/string-theory-for-windows/ - cum se | + | * http://taossa.com/index.php/2007/01/09/string-theory-for-windows/ - cum se lucrează cu şiruri în Windows |
--[[User:Admin|sorin]] | --[[User:Admin|sorin]] | ||
+ | |||
+ | [[Categorie:Tutorial]] | ||
+ | [[Categorie:Programare]] |
Versiunea curentă din 22 noiembrie 2009 07:07
Cuprins
Introducere
Am în mentenanţă o aplicaţie MFC, veche de 7 ani şi de curând am putut să renunţ la suportul pentru Win9x şi am început trecerea aplicaţiei la Unicode.
Acum pot să recomand oricui vrea, să internaţionalizeze/localizeze, să folosească librăria gettext din următoarele motive:
- mentenanţa fişierelor de localizare este incomparabil mai uşoară
- există orice fel de unelte de localizare pentru fişiere gettext (.PO)
- poate fi folosită şi în aplicaţii comerciale (este LGPL)
Trecerea aplicației la Unicode
Unii o pot considera inutilă, dar experienţa mea spune că merită să renunţi la Win9x și să treci la Unicode. Cel puțin, scapi de problema codepage-urilor.
Începeţi prin a înlocui tipurile de date și apelurile la funcții cu următoarele alternative, care de fapt sunt toate macro-uri, care se compilează diferit, în funcție de target. Această fază nu vă va 'strica' aplicaţia şi veţi putea să faceţi build-uri separate.
Nu uitați să faceți un branch separat înainte de a începe, s-ar putea să dureze de 3X mai mult decât credeți, acum depinde de când și de cine a fost scrisă aplicația inițial.
char _TCHAR LPSTR LPTSTR LPCSTR LPCTSTR strlen _tcslen strcpy _tcscpy strcmp _tcscmp strncmp _tcsmcmp stricmp _tcsicmp strchr _tcschr strncmp _tcsncmp sprintf _tsprintf /* Vezi mai jos */ strstr _tcsstr sscanf _stscanf wsprintf _tcs atoi _tstoi itoa _itot_s sscanf _stscanf vsprintf _vstprintf fopen _tfopen fputs _fputs fclose _tfclose
/* Cum Bill cam uită să ducă treaba la bun sfârşit, a uitat de (w)sprintf aşa că adăugaţi şi asta într-un H*/
#ifdef UNICODE
#define _tsprintf wsprintf
#define tstring wstring
#else
#define _tsprintf sprintf
#define tstring string
#endif
Ceva mai puţin evident despre ..prinf(...)
Funcţiile din gama printf, pot primi ca parametrii atât char, w_char cât şi t_char aşa că **trebuie** ajutate să-şi dea seama ce primesc
Apel build unicode build ne-unicode alias -------------------------------------------------------------------------------- sprintf "%s" LPWSTR LPSTR normal sprintf "%S" LPSTR LPWSTR inverse sprintf "%hs" LPSTR LPSTR single-byte sprintf "&ls" LPWSTR LPWSTR double-byte
Cum convertesc dintr-un string în altul
Puteți folosi niște macrocomenzi gen:
W2A(...) și CW2A(...) A2T(...) și CA2T(...) T2A(...) și CT2A(...)
- C - constant
- W - Wide
- T - TCHAR (Adica W în unicode și A în rest)
- A - ASCII
Nu uitați că nu le puteți folosi oricum, deoarece fac niște hack-uri cam nasoale. Dacă vreți să le folosiți citiți neapărat înainte
- http://codexpert.ro/forum/viewtopic.php?f=23&t=149&p=650&hilit=CW2A#p650
- http://codexpert.ro/forum/viewtopic.php?f=14&t=416&p=2426&hilit=ct2a#p2426
Gettext
Gettext functions and comments
// Translators: This is a text that is going to be used by translators in order to translate the next term corectly.
print(_("Code"));
// This is how we MUST use printf syntax in order to be able to translate corectly the programs.
// This syntax permits the changing the order of the parameters.
printf("'%2$d' us tge 2th parameter and '%1$s' is the first one.", param1, param2);
// SYntax
// _(...) este doar un macro care se expandeaza la gettext(...)
// dgettext
// dcgettext
char * ngettext (const char *msgid_singular, const char *msgid2_plural, unsigned long int n); // For plural
char * dngettext (const char *domain, const char *msgid1_singular, const char *msgid2_plural, unsigned long int n); //
char * dcngettext (const char *domain, const char *msgid1, const char *msgid2, unsigned long int n, int category); //
// Formatting with positions
fprintf "%2$d %1$d" // (POSIX but not C 99)
// printf, vfprintf, sprintf, vsprintf, fwprintf, wprintf, swprintf, vswprintf
...
Descărcaţi:
- gettext-runtime (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/gettext)
- libiconv (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/libiconv)
Ar trebui să ştiţi că, implicit, gettext întoarce textele în UTF-8, ceea ce este foarte bine, mai puţin pentru Windows, care foloseşte în modul Unicode (UTF16-LE), aşa că trebuie să le convertiţi la runtime (oricum e suficient de rapidă conversia).
#include "../contrib/gettext-runtime/include/libintl.h"
CString strDomain=CString(textdomain("myproject")); // if you put "" will default to "messages"
CString strBinded = CString(bindtextdomain("myproject","d:\\dev\\pbxtools\\src\\debug\\locale\\")); // put you path here
// later
AfxMessageBox(_("Hello World!"), (UINT)MB_OK, (UINT)0);
Extragerea textelor
Extragerea textelor din fişierele .C si .CPP este extrem de uşoară, folosind xgettext, dar când veţi ajunge la fişierele .RC, o să descoperiţi că nu sunt suportate. Din fericire, după multe încercări nereuşite, am găsit singur o soluţie simplă
xgettext --from-code=UTF-8 --add-comments --omit-header --no-location \
--keyword=MENUITEM --keyword=LTEXT --keyword=DEFPUSHBUTTON --keyword=PUSHBUTTON --keyword=CAPTION \
--language=Tcl -o resources.po project.rc
Sau pe scurt: întrucât sintaxa Tcl e destul de compatibilă cu cea din .RC, folosind keyword-urile respective, obţineţi un parser de .RC în xgettext. Cool?... o să trimit şi un mail ca să modifice să recunoască fişierele rc direct.
Legături
- http://www.gnu.org/software/gettext/ - de citit cu atenţie
- http://taossa.com/index.php/2007/01/09/string-theory-for-windows/ - cum se lucrează cu şiruri în Windows
--sorin