Escribir aplicaciones internacionales para Windows

IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.

Haga clic aquí para ver el artículo original (en inglés): 65124
Este artículo se ha archivado. Se ofrece "tal cual" y no se volverá a actualizar.
Resumen
Este artículo forma parte de un conjunto de siete artículos, denominados conjuntamente "Notas del programador de Windows". Obtener más información sobre el contenido de otros artículos puede encontrarse en el artículo de Knowledge Base:
65260Notas del programador de Windows
Más información
Los archivos siguientes están disponibles para descargarlos del Centro de descarga de Microsoft:


IntlApps.exe

Para obtener información adicional acerca de cómo descargar los archivos de soporte técnico de Microsoft, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
119591Cómo obtener Archivos de soporte técnico de Microsoft desde los servicios en línea
Microsoft exploró este archivo en busca de virus. con el software de detección de virus más reciente disponible en la fecha de publicación. Asimismo, el archivo se almacenó en servidores seguros que ayudan a impedir la realización de cambios no autorizados.

Versión de Microsoft (r) Windows (tm) proporciona un entorno que permite a las aplicaciones independencia país e idioma.

Este documento es una colección de información relacionada con la compatibilidad internacional en Windows. Para obtener más información sobre las funciones mencionadas en este documento, consulte la documentación incluida con el Kit de desarrollo de software (SDK) de Windows y el Kit de desarrollo de dispositivos (DDK).
=======================================================================              CREATING AN INTERNATIONAL APPLICATION=======================================================================To reach worldwide audiences with your products, you need to createapplications that can be marketed in more than one country and thatcan be modified for new markets.An international application must have the following characteristics: - Country and language independence - Easy localizationAll applications, regardless of the language used in the interface,should be able to handle data from different countries and indifferent languages. For example, a database developed primarily forthe English-speaking market should be able to handle French and Germaninput. The application also should handle the appropriate currencysymbols and date and time formats. Furthermore, it should be able toexecute complex operations, such as sorting, using the languageselected by the user.Ease of localization is the second goal to strive for when writinginternational applications. Localization can be defined as the processof adapting an application for a market other than the one for whichit was originally designed. This adaptation involves translation ofthe product, addition of new features when required, and modificationof the product to meet local needs. Applications should be developedso that localization is a fast and painless task.This document explains how to internationalize your Windows-basedapplication.=======================================================================             ACHIEVING COUNTRY AND LANGUAGE INDEPENDENCE=======================================================================Windows 3.0 provides resources to help your applications achievecountry and language independence. These resources consist ofinternational information stored in the WIN.INI file and in language-sensitive Windows functions. By using these resources and followingthe guidelines described in this section, your application willproduce the correct international behavior.INTERNATIONAL INFORMATION IN WIN.INI====================================The [Intl] section of the WIN.INI file contains the current Windowscountry settings. These settings can be modified by the user throughthe Control Panel, or by the application through theWriteProfileString() function. Applications have access to the currentcountry settings through the GetProfileInt() and GetProfileString()functions. Applications should read the required country settings atstart-up, and should monitor the WM_WININICHANGE message to update itscountry settings accordingly, in case they are changed.The following is a list of the country settings stored in WIN.INI:Setting        Description-------        -----------iCountry       Country code. This value is based on the telephone               country code. The only exception is Canada, for which a               2 is used instead of 1 (1 is used by the United               States). Use this setting if your application has to               control a country-dependent feature not supported by               Windows 3.00.sCountry       String defining the selected country name.sLanguage      The national language selected by the user. Changing               the language using the Control Panel's International               dialog box will change the installed language-dependent               module. The language values are as follows:                  Value       Language                  -----       --------                  dan         Danish                  dut         Dutch                  eng         International English                  fcf         French Canadian                  fin         Finnish                  frn         French                  ger         German                  ice         Icelandic                  itn         Italian                  nor         Norwegian                  por         Portuguese                  spa         Spanish                  swe         Swedish                  usa         U.S. EnglishsList          List separator. This character is used to separate               elements in a list. The list separator must be               different from the decimal separator to avoid conflicts               with lists of numbers.iMeasure       Measurement system selected by the user, where               0 = metric, 1 = English. Use this setting to control               measurement-dependent features of your application.iTime          Time format. This setting defines the time format: 12               hours or 24 hours, where 0 = 12-hour clock, 1 = 24-hour               clock.sTime          Time separator. This character is displayed between               hours and minutes, and between minutes and seconds.s1159          In some countries, the time is displayed followed by a               trailing string (AM, for example). This setting               contains the trailing string used for times between               00:00 and 11:59.s2359          Trailing string (PM, for example) for times between               12:00 and 23:59, when in 12-hour clock format, or               trailing string (GMT, for example) for any time in               24-hour clock format.iTLZero        When displaying time, this value specifies whether or               not the hours should have a leading zero. The               convention is 0 = no leading zero (9:15, for example),               1 = leading zero (09:15, for example).iDate          This is the Windows 2.x style for defining the date               format. It has been kept for compatibility reasons. We               recommend using sShortDate instead. The values for this               setting are:                  0 = Month-Day-Year                  1 = Day-Month-Year                  2 = Year-Month-DaysDate          Date separator. Kept for compatibility with               Windows 2.x. Try using sShortDate instead.sShortDate     This is a new Windows 3.00 format. This string defines               a "date picture" of the short date format. More               information about the short date format can be stored               using this method. sShortDate accepts only the values               M, MM, d, dd, yy and yyyy. See sLongDate for               information about these values and pictures.sLongDate      This setting is like sShortDate, but it also can               contain strings mixed with days of the week, dates,               months, and years. The definition of this date picture               is as follows:               Value       Item       Format               -----       ----       ------               M           Month      1-12               MM          Month      01-12               MMM         Month      Jan-Dec               MMMM        Month      January-December               d           Day        1-31               dd          Day        01-31               ddd         Day        Mon-Sun               dddd        Day        Monday-Sunday               yy          Year       00-99               yyyy        Year       1900-2040               Examples:               Date Picture                  Meaning               ------------                  -------               d MMMM, yyyy                  9 January, 1989               dddd, MMMM d, yyyy            Friday, February 7, 1989               M/d/yy                        3/18/89               dd-MM-yyyy                    18-03-1989               d 'of' MMMM, yyyy             9 of January, 1989sCurrency      This string defines the currency symbol of a given               country. Be very careful with this setting. Do not make               global replacements of currency amounts in your               application if the currency symbol is changed through               the Control Panel. Once the user has entered an amount               using certain currency, that currency should stay the               same. Also, be careful with this setting when sharing               files among users or applications.iCurrency      This setting defines the currency format. The               convention is:                  0 = Currency symbol prefix, no separation ($1, for                      example)                  1 = Currency symbol suffix, no separation (1$)                  2 = Currency symbol prefix, one character separation                      ($ 1)                  3 = Currency symbol suffix, one character separation                      (1 $)iCurrDigits    This value defines the number of digits used for the               fractional part of a currency amount.iNegCurr       This value defines the negative currency format. The               definition follows the convention:                  0 = ($1)                  1 = -$1                  2 = $-1                  3 = $1-                  4 = (1$)                  5 = -1$                  6 = 1-$                  7 = 1$-               In these examples, the dollar symbol represents any               currency symbol defined by sCurrency.sThousand      This is the symbol used to separate thousands in               numbers with more than three digits.sDecimal       Character used to separate the integer part from the               fractional part of a number.iDigits        Value defining the number of decimal digits that should               be used in a number.iLzero         This setting defines whether a decimal value less than               1.0 (and greater than -1.0) should contain a leading               zero.                  0 = No leading zero (for example, .7)                  1 = Leading zero (0.7)LANGUAGE-SENSITIVE WINDOWS FUNCTIONS====================================Windows 3.00 introduces the concept of national language. Language, inconjunction with country, allows Windows to describe more preciselythe characteristics of a given geographical location. The following isa list Windows functions that behave differently, depending on thelanguage selected:   AnsiLower()   AnsiLowerBuff()   AnsiUpper()   AnsiUpperBuff()   IsCharAlpha()   IsCharAlphaNumeric()   IsCharLower()   IsCharUpper()   lstrcmp()   lstrcmpi()Comparing and Sorting Strings-----------------------------The Windows 3.00 functions lstrcmp and lstrcmpi allow applications tocompare and/or sort strings based on the natural language selected bythe user. These functions take into account different alphabeticalorderings, diacritical marks, and special cases that require charactercompression or expansion.It is very important to notice that these functions do not act thesame way as do the C functions strcmp and strcmpi. The comparison doneby lstrcmp and lstrcmpi is based on a primary value and a secondaryvalue (see the following table). Each character has a primary and asecondary value. For example, in the following matrix, the letter "d"has a primary value of 4 and a secondary value of 2.   Primary   Values                       Secondary Values   ------                       ----------------            1   2   3   4   5   6   7   8   9  10  11  12  13  14    1       A  A2  A3  A4  A5  A6  A7   a  a2  a3  a4  a5  a6  a7    2       B   b    3       C  C2   c  c2    4       D   d    5       E  E2  E3  E4  E5   e  e2  e3  e4  e5    6       F   f   *******************************************************************   NOTE: This table uses these character values because some accented   characters cannot easily be represented for electronic   transmission. The printed application note contains the actual   accented characters and may be easier to read and comprehend.   Capital letters precede the lowercase letters. The following is a   list of the accent codes:      A2 - A with a grave accent      A3 - A with an acute accent      A4 - A with a circumflex      A5 - A with a tilde      A6 - A with an umlaut      A7 - A with a circle      C2 - C with a cedilla      E2 - E with a grave accent      E3 - E with an acute accent      E4 - E with a circumflex      E5 - E with an umlaut   *******************************************************************Examples of Primary and Secondary Sorting Values------------------------------------------------When performing the comparison of two strings, the primary value takesprecedence over the secondary value. That is, the secondary value isignored unless a comparison based on the primary value shows thestrings as equivalent.The following examples show the effect of primary and secondary valueson string comparisons:   Comparison   Reason   ----------   ------   A = A        Primary values equal   A < a        Primary values equal, secondary values unequal (A < a)   Ab < ab      Primary values equal, secondary values unequal (A < a)   ab < Ac      Primary values unequal (b < c)Note, however, that lstrcmpi ignores the effect of case in determiningsecondary value. That is, when lstrcmpi is called to compare "AB" and"ab", the two strings will be equivalent. However, lstrcmpi does notignore diacritical marks, so "Ab" precedes "(a6)b", regardless ofwhether the comparison is performed by lstrcmp or lstrcmpi. ("a6" isan "a" with an umlaut.)When comparing strings of different lengths, length takes precedenceover secondary values. That is, the shorter string will always precedethe longer string as long as the primary values in the shorter stringequal the primary values of the equivalent characters in the longerstring. For example, "ab" precedes "ABC", but "ABC" precedes "AD".Depending on the language module installed, some characters will betreated differently. For example, if the German language module isinstalled, the beta character expands to "ss". If the Spanish languagemodule is installed, the characters "ch" will be treated as a singlecharacter that sorts between "c" and "d".Case Conversions----------------The case conversion functions AnsiLower(), AnsiLowerBuff(),AnsiUpper() and AnsiUpperBuff() depend on the language moduleinstalled. Different languages treat case conversions differently. Donot use the C case-conversion functions; they do not take intoconsideration characters with values more than 128.Character Classification Functions----------------------------------The functions IsCharAlpha(), IsCharAlphaNumeric(), IsCharLower(), andIsCharUpper() are also language dependent. Use these functions toattain language independence.Handling Character Sets: ANSI Versus OEM----------------------------------------One of the main problems developers face when writing internationalWindows-based applications is handling characters sets. It is veryimportant to understand ANSI and OEM.ANSI is the character set used internally by Windows and itsapplications. Windows does not recognize any character set other thanANSI.OEM is defined by Windows as the character set used by MS-DOS. The term"OEM" does not refer to a specific character set; instead, it refersto any of the different character sets (code pages) that can beinstalled and used by MS-DOS.Because Windows runs on top of MS-DOS, there must be a layer betweenWindows and MS-DOS that performs translations between ANSI and OEM. WhenWindows is first installed, the Windows Setup program looks at theMS-DOS-installed character set, and then installs the correct ANSI-OEMtranslation tables and Windows OEM fonts.Windows-based applications should use the Windows functions AnsiToOem()and OemToAnsi() when transferring information to and from MS-DOS. Also,applications should use the correct character set when creatingfilenames. For more information about handling filenames, see thefollowing section.There is no one-to-one mapping between ANSI and OEM. ApplyingAnsiToOem() and then OemToAnsi() to a given string will not alwaysresult in the original string.Keep in mind that both ANSI and OEM are 8-bit character sets. Alwaysuse "unsigned char" instead of "signed char". Bugs that result fromusing "signed char" are very hard to track.Handling Filenames------------------One of the problems dealing with the ANSI and OEM character sets isthe handling of filenames. Different applications do file handlingdifferently, depending on factors such as speed, size, and programmingstyle. This section describes the most common methods.The easiest way to deal with filenames in Windows is to use ANSI forall filenames, and use the functions _lcreat(), _lopen(), andOpenFile() to deal with MS-DOS and the OEM character set.Another way to deal with filenames is to use OpenFile() to obtain afully qualified pathname, the szPathName field, from the OFSTRUCTdata structure. Be very careful here. The szPathName field containscharacters from the OEM character set. The szPathName field must firstbe converted to ANSI before it is used as a parameter for OpenFile(),other Windows functions, or in a dialog box.The following example shows this conversion:if (OpenFile("myfile.txt", &of, OF_EXISTS) == -1)    {        OemToAnsi(of.szPathName, szAnsiPath);        OpenFile(szAnsiPath, &of, OF_CREATE);    }Note that the value of of.szPathName must be converted from OEM toANSI.The third, and perhaps most complicated, method of handling files is todirectly call MS-DOS [using the DOS3Call() function or an INT 21Hinstruction]. You must ensure that your application always passes OEMcharacters to MS-DOS.Another problem occurs when applications try to create filenames inANSI that have no equivalent characters in OEM. For example, thecharacter E4 (E-circumflex) does not exist in code page 437 (437 isthe standard U.S. extended ASCII character set). If the applicationtries to save the file (E4).TXT, Windows will convert (E4).TXT intoE.TXT [by using the AnsiToOem() function], and then it will pass thefile to MS-DOS. The end result is a confused user that doesn't understandwhat happened to his/her file. You can solve this problem by using theES_OEMCONVERT and CBS_OEMCONVERT control styles. These styles (thefirst for edit controls and the second for combo boxes) will read theuser's input and convert the typed character to a valid character (onethat exists in the OEM character set). This way, the user will see onthe screen the real filename that will be stored at the MS-DOS level.Handling the Keyboard---------------------The most important keyboard issue for international applications isthe use of the VK_OEM keys as user input. The problem here is that thelocations of the VK_OEM keys change, depending on the keyboard layoutchosen by the user. The VkKeyScan() function is helpful in thesecases.VkKeyScan() is used to translate an ANSI character into a virtual-keycode plus a shift state. This function also could be used when oneapplication has to send text to another application by simulatingkeyboard input.Some other useful functions are the following: - ToAscii(). This function is the opposite of VkKeyScan(). It   converts a virtual-key code plus a shift state to an ANSI   character. - GetKeyNameText(). This function retrieves a string that contains   the name of a key (for example, the SHIFT key or the ENTER key).   The string will be in the language related to the keyboard. For the   French keyboard layout, the name of the keys will be in French. - GetKbCodePage(). It is important to note that there is no real   relationship between the keyboard and the code page installed. This   function will return the code page (OEM character set) that was   running at the MS-DOS level when Windows was installed.To enter characters that are not on your keyboard, use the ALT key andthe numeric keypad. For ANSI characters, hold down the ALT key andthen, on the numeric keypad, type 0 (zero) and the three-digit code ofthe character you want. For OEM characters, do the same thing withouttyping the 0 prefix.Handling WIN.INI, SYSTEM.INI,SETUP.INF, and Private Initialization Files-------------------------------------------The WIN.INI, SYSTEM.INI, and SETUP.INF files are ANSI files. Normally,applications do not touch SYSTEM.INI or SETUP.INF. For WIN.INI andprivate initialization files, applications should use the functionsGetPrivateProfileInt(), GetPrivateProfileString(), GetProfileInt(),GetProfileString(), WritePrivateProfileString(), andWriteProfileString(). Make sure ANSI is always used with thesefunctions.The section names and setting names in WIN.INI and privateinitialization files should be independent of the language of theapplication. Normally, all of these names should be in English. Forexample, in WIN.INI, the section name [Desktop] and the setting nameWallpaper should always remain in English so that applications indifferent languages can access the same information.=======================================================================                     ACHIEVING EASY LOCALIZATION=======================================================================Creating applications that are easy to localize is not difficult ifyou follow a few basic rules.ISOLATION OF LOCALIZABLE INFORMATION====================================The most important rule for localization is to never mix functionalcode with strings, messages, or any other information that has to bemodified. In a normal Windows-based application, all the menus, strings,and messages should be placed in the resource script (.RC) file. All thedialog-box information should be placed in the dialog script (.DLG)file. If you do this, there will be no need to recompile theexecutable file for a new localized version of the product. Just usethe resource compiler (RC). Hard-coded strings (strings mixed withfunctional code) are the worst enemy of localization.Strings that are not meant to be modified (filenames, WIN.INI settingnames, etc.) can be placed in the resource script file. In this case,the .RC file should contain comments documenting that the names arepermanent. Better yet, mark what has to be translated (explaininglimitations, if any) and what should not be modified. The better thedocumentation, the easier the localization.Place in the .RC files and .DLG files anything that could be alocalization item. It is better to have extra information in thesefiles than to have too little.In cases where an .RC or .DLG file cannot be used, place all theinformation in a file (such as an include file) that is separate fromany functional code.ALLOCATING EXTRA SPACE FOR STRINGS==================================Many languages are more verbose than English; therefore, they requiremore space to hold strings or to display dialog boxes. There arecases, as with menus, where the space allocation is done dynamically.However, in most cases, the application must provide the space. Thefollowing table shows how much additional space should be allocatedfor strings of various lengths:   Length of   English Text          Space Allocation   (In Characters)       (In Addition to Text)   --------------        ---------------------      1-10                      200 percent     11-20                      100 percent     21-30                       80 percent     31-50                       60 percent     51-70                       40 percent      70+                        30 percentAvoid creating dense menus where most of the available space (a line,for example) is already used up in the English version. Dialog boxesshould be designed so that items can be moved freely, allowing theorganization of the contents as the translation demands. Do not crowdstatus bars with information. Even abbreviations are often longer indifferent languages.HANDLING FOREIGN SYNTAX AND GRAMMAR===================================Never make assumptions about syntax or grammar when dealing withforeign languages. The ordering of words can be different, and thenumber of words required is often greater than in English.All messages should be self contained, not dynamically assembled. Formessages that have variables added to them at run time, do not makeany assumptions about the position of the variable in the message. Theway to handle variables in messages is by using the Windows functionwsprintf(). For example, you could place in the .RC file the stringcontaining the variable, as follows:   CannotOpen, "The application could not open the file %s"Use wsprintf() to incorporate the variable into the string, asfollows:   LoadString(hInst, CannotOpen, lpFormat, MaxLen);   wsprintf(FinalString, lpFormat, FileName);Avoid using a single word in more than one message. Words such as"None" can have different translations (different gender and number)depending on the context.Do not create plurals of words by adding "s". Keep two strings, onefor the singular and one for the plural.Avoid parsing text to obtain information. Parsing normally assumesspecific syntax.Avoid using slang, abbreviations, and jargon, since they are difficultto translate.When handling graphic objects such as bitmaps, cursors, and icons, tryto avoid the use of embedded text. Text is difficult to modify when ingraphical form. If you cannot avoid this, be careful about leavingenough space for translation, and try to create tools to simplify themodification.Graphic objects are also language dependent. Always look for graphicobjects that represent international concepts.OTHER RULES===========Do not hard code the position or size of any element on the screen.Remember that items will change position and size as they gettranslated. If you must define the size or position of certain object,place this definition in the .RC file.Be careful when using the CreateWindow() function. This functioncontains two parameters: lpClassName and lpWindowName. The lpClassNameparameter should be constant and independent from localization. On theother hand, lpWindowName is the string that will appear in the captionbar and therefore should be localized. The string used forlpWindowName should be taken from the resources.Microsoft is a registered trademark and Windows is a trademark ofMicrosoft Corporation.				

Advertencia: este artículo se tradujo automáticamente

Propiedades

Id. de artículo: 65124 - Última revisión: 02/10/2014 09:17:25 - Revisión: 3.1

Microsoft Windows Software Development Kit 3.0, Microsoft Windows Software Development Kit 3.1

  • kbnosurvey kbarchive kbmt kbfile kbintldev KB65124 KbMtes
Comentarios