2009-10-13 7 views
5

Gibt es irgendeine Art und Weise in der Win32-API einen drei Buchstaben bestehenden Sprachcode zu konvertieren, wie GetLocaleInfo() mit LOCALE_SABBREVLANGNAME angegeben, um ein entsprechenden LANGID oder LCID zurückgegeben? Das heißt, gehen Sie "umgekehrt" zu dem, was normalerweise tut?Konvertieren drei Buchstaben bestehenden Sprachcode zu Sprachkennung (LANGID)

Was ich versuche zu tun, zu analysieren, welche Art von Sprache einer Ressource DLL verwendet, und so weit, ohne etwas über die DLL zu berühren, von dem DLL-Namen mit einem Format gehen nameLNG.dll, wo LNG ist ein drei Buchstaben-Code, scheint die einfachste Methode zu sein, vorausgesetzt, eine solche Funktion existiert.

Wenn dies nicht einfach zu tun ist, denke ich, dass Plan B unseren Sprach-DLLs eine Versionsinfo-Ressource geben soll, dort ihre jeweiligen Kulturen angeben und später in der Anwendung lesen, welche Kulturen sie verwenden.

Antwort

2

Leider gibt es keine direkte Win32-API, die Ihnen eine LANGID mit einer 3-Buchstaben-Abkürzung gibt.

Es sieht aus wie CLanguageSupport ist dein Freund today :-) Es implementiert bereits Ihren Plan B, um die LANGID basierend auf dem Inhalt der Versionsinfo-Ressource nachzuschlagen.

Das Stück Code, den Sie suchen ist int die Funktion

LANGID CLanguageSupport::GetLangIdFromFile(LPCTSTR pszFilename) 

Natürlich ist der Nachteil ist, dass Sie eine Diskrepanz zwischen der Versionsinformation und dem DLL-Namen haben. Aber Sie würden es sehr schnell während der Tests erfassen. Und wenn Sie ein Tool wie appTranslator die DLLs für Sie erstellen lassen, sind Sie sicher auf der sicheren Seite.

+0

Ja, ich denke, dass ich am Ende diese Klasse benutzen werde, da Sie anscheinend nicht nur eines, sondern zwei der Probleme, mit denen wir konfrontiert sind, bereits beiseite geschoben haben. Vielleicht stellen wir sogar das Sprach-Untermenü wieder her, das ich vor wenigen Tagen weggenommen hatte, und meinten, unser Wechsel zum MFC-Mechanismus wäre endgültig. Naja ... – Jonas

1

Sie können die installierten Ländereinstellungen mit EnumSystemLocales() auflisten und die Karte selbst erstellen. Ich mache das während der Anwendungsinitialisierung in einem Dienst, den ich vor einiger Zeit geschrieben habe, und es hat bisher gut funktioniert.

Ich würde in diesem Fall empfehlen, Plan B zu verwenden. Ich verzichte normalerweise auf die Codierung von Dateien in den Dateinamen. Wenn aus anderen Gründen die 3-stellige ISO-639 Variante nicht perfekt ist, wenn Sie nicht genau angeben, welche Variante Sie verwenden - ISO-639-2/B, ISO-639-2/T oder ISO-639-3.

Wenn Sie länderspezifische Varianten angeben müssen, sollten Sie einen Blick auf RFC3066 werfen. Grundsätzlich müssen Sie die Sprache und den Ländercode und in einigen Fällen auch den Ländercode angeben. In jedem Fall kapselt die LCID all diese Güte ein.

Die eine Sache, die ich nicht ganz sicher bin, ist, ob die LangID in der Ressource Informationen eine vollständige LCID ist oder nicht. Die Codes, die in der VERSIONINFO Referenz aufgeführt sind, sind LCIDs, also würde ich versuchen, eine LCID in dem VERSIONINFO-Header zu verwenden. Wenn nicht, können Sie die Informationen immer als Zeichenfolge in den Zeichenfolgenblock aufnehmen.

+1

EnumSystemLocales geben Sie mir nur eine Liste von drei Buchstaben Akronyme, oder? Ich bin mir nicht sicher, wie ich eine Karte erstellen kann, indem ich nur diese Informationen verwende und mir die LCIDs oder LANGIDs, aus denen übersetzt werden soll, entgehen lassen. Diese Lösung wäre perfekt, wenn die Callback-Funktion für EnumSystemLocales ein * Paar * von LCID- und ISO-Strings zurückgegeben hätte. – Jonas

+0

Das Argument für das EnumLocalesProc ist eigentlich die LCID, die als Hexadezimalzahl in eine Zeichenfolge formatiert ist. Die Dokumentation ist darüber nicht klar - _ "Zeiger auf einen Puffer, der eine Null-terminierte Gebietsschema-Bezeichner-Zeichenfolge enthält" _. Was sie nicht erwähnen, ist, dass Sie etwas wie '_tcstoul (lpLocaleString, NULL, 16)' darauf setzen müssen, um den Gebietsschema-Identifizierer in ein verwendbares Formular zu bringen. Sobald Sie die LCID haben, können Sie bekommen, was Sie brauchen, von 'GetLocaleInfo()' mit 'LOCALE_SISO639LANGNAME' und' LOCALE_SISO3166CTRYNAME'. –

0

können Sie die LangID erhalten durch GetLocaleInfo() mit LOCAL_RETURN_NUMBER|LOCALE_ILANGUAGE für die LCType Parameter aufrufen, wie Sie LOCALE_SABBREVLANGNAME den aus drei Buchstaben bestehenden ISO-Code zu erhalten, übergeben. Durch Übergeben derselben IDCID an diese Funktion können Sie die entsprechende LangID mit dem ISO-Code speichern.

Beachten Sie, dass MSDN LOCALE_ILANGUAGE sagt sollte nicht zugunsten LOCALE_SLANG auf Vista und höher verwendet werden, aber ich glaube, dass der Kommentar nicht für die Verwendung von LOCALE_ILANGUAGE mit LOCALE_RETURN_NUMBER gilt.

Wenn sich Ihr Projekt weiterentwickelt, können Sie mehrere lokalisierte Dateien für jede Sprache generieren. Aus diesem Grund würde ich vorschlagen, dass Sie Ihre lokalisierten Dateien in Unterverzeichnissen speichern, die nach der Sprache benannt sind. Microsoft hat Verzeichnisse verwendet, die nach den LangIDs benannt sind, z. B. "1033" als das englische Ressourcenverzeichnis. Ich denke, es wäre freundlicher, den Drei-Buchstaben-Code zu verwenden, wie "ENU \ name.dll". In jedem Fall sind Unterverzeichnisse eine einfache Lösung und werden Ihren Buildprozess hoffentlich nicht so sehr verkomplizieren, wie den Zieldateinamen zu ändern.

+0

habe ich leider keinen Zugriff auf die LCID, sondern eine LANGID aus dem Sprachcode drei Buchstaben Akronym (der Faux-ISO-Code). – Jonas

+0

FWIW, MS möchte, dass wir uns von LOCALE_ILANGUAGE entfernen, weil sie auf reine "Lang-IDs" umstellen möchten, a la .NET cultures-IDs. Sie versuchen uns zu überzeugen, dass LANGID * eines Tages sterben könnte, zumindest für neu unterstützte Sprachen in Win8 + –

Verwandte Themen