2009-10-13 43 views
5

Có một số cách trong Win32 API để chuyển đổi một mã ngôn ngữ ba lá thư, như được trả về bởi GetLocaleInfo() với LOCALE_SABBREVLANGNAME quy định, đến một tương ứng LANGID hoặc LCID? Đó là, đi vào "đảo ngược" với những gì GetLocaleInfo() thường làm gì?Chuyển đổi ba lá thư mã ngôn ngữ để nhận dạng ngôn ngữ (LANGID)

Điều tôi đang cố gắng phân tích loại ngôn ngữ mà tài nguyên DLL đang sử dụng, và cho đến nay, không cần chạm vào bất kỳ điều gì về DLL, theo tên dll có định dạng nameLNG.dll, trong đó LNG là ba mã ngôn ngữ thư, có vẻ là phương pháp dễ nhất, giả sử một hàm như vậy tồn tại. Nếu điều này không dễ làm, tôi đoán Kế hoạch B là cung cấp cho ngôn ngữ của chúng tôi DLL tài nguyên thông tin phiên bản, chỉ định nền văn hóa tương ứng ở đó, và sau đó trong ứng dụng, đọc nền văn hóa nào họ sử dụng.

Trả lời

2

Thật không may, không có API Win32 trực tiếp nào cung cấp cho bạn LANGID có chữ viết tắt gồm 3 chữ cái.

Có vẻ như CLanguageSupport là bạn của bạn today :-) Nó đã triển khai kế hoạch B của bạn để tra cứu LANGID dựa trên nội dung của tài nguyên thông tin phiên bản.

Các đoạn mã bạn đang muốn tìm int chức năng

LANGID CLanguageSupport::GetLangIdFromFile(LPCTSTR pszFilename) 

Tất nhiên, nhược điểm là bạn có thể có sự không phù hợp giữa các thông tin phiên bản và tên DLL. Nhưng bạn sẽ nhanh chóng nắm bắt nó trong quá trình thử nghiệm. Và nếu bạn để một công cụ như appTranslator tạo các tệp DLL cho bạn, bạn chắc chắn sẽ ở bên an toàn.

+0

Vâng, tôi nghĩ rằng tôi sẽ kết thúc bằng cách sử dụng lớp này sau đó, vì bạn đã rõ ràng đã bước bên không chỉ một, nhưng hai trong số các vấn đề chúng ta đang phải đối mặt. Chúng tôi thậm chí có thể thực hiện lại menu phụ ngôn ngữ mà tôi vừa mới mất vài ngày trước đây, nghĩ rằng việc chuyển sang cơ chế MFC của chúng tôi sẽ là cuối cùng. Oh well ... – Jonas

1

Bạn có thể liệt kê các miền được cài đặt bằng cách sử dụng EnumSystemLocales() và tự xây dựng bản đồ. Tôi làm điều này trong quá trình khởi tạo ứng dụng trong một dịch vụ mà tôi đã viết một lúc trước và nó đã hoạt động tốt cho đến nay.

Tôi khuyên bạn nên sử dụng Gói B trong trường hợp này. Tôi thường tránh được việc mã hóa nội dung vào tên tệp. Nếu không vì lý do nào khác, sử dụng biến thể ISO-639 gồm 3 ký tự không hoàn hảo trừ khi bạn chỉ định rõ bạn đang sử dụng biến thể nào - ISO-639-2/B, ISO-639-2/T hoặc ISO-639-3.

Nếu bạn cần cung cấp các biến thể địa phương cụ thể, thì bạn nên xem xét kỹ lưỡng RFC3066. Về cơ bản, bạn cần phải chỉ định ngôn ngữ và mã quốc gia và, trong một số trường hợp, mã vùng là tốt. Trong mọi trường hợp, LCID đóng gói tất cả sự tốt lành này.

Điều mà tôi không hoàn toàn chắc chắn là liệu langID trong thông tin tài nguyên có phải là LCID đầy đủ hay không. Các mã được liệt kê trong tài liệu tham khảo VERSIONINFO là LCID nên tôi sẽ thử sử dụng LCID trong tiêu đề VERSIONINFO. Nếu không, bạn luôn có thể bao gồm thông tin dưới dạng chuỗi trong khối chuỗi.

+1

EnumSystemLocales chỉ cung cấp cho tôi danh sách ba từ viết tắt của chữ cái, phải không? Tôi không biết cách xây dựng bản đồ bằng cách chỉ sử dụng thông tin này và thiếu LCID hoặc LANGID để dịch từ? Giải pháp này sẽ là hoàn hảo nếu chức năng gọi lại cho EnumSystemLocales sẽ trả về một cặp * của chuỗi LCID và "ISO". – Jonas

+0

Đối số cho 'EnumLocalesProc' thực sự là LCID được định dạng dưới dạng số thập lục phân thành một chuỗi. Tài liệu hướng dẫn ít rõ ràng hơn về điều này - _ "Con trỏ tới một bộ đệm chứa chuỗi định danh miền địa phương đã kết thúc bằng null" _. Những gì họ không đề cập đến là bạn phải gọi một cái gì đó như '_tcstoul (lpLocaleString, NULL, 16)' trên nó để có được định danh miền địa phương vào một hình thức có thể sử dụng. Khi bạn có LCID, bạn có thể nhận được những gì bạn cần từ 'GetLocaleInfo()' bằng cách sử dụng 'LOCALE_SISO639LANGNAME' và' LOCALE_SISO3166CTRYNAME'. –

0

Bạn có thể nhận LangID bằng cách gọi GetLocaleInfo() với LOCAL_RETURN_NUMBER|LOCALE_ILANGUAGE cho LCType tham số , cũng giống như bạn thông qua LOCALE_SABBREVLANGNAME để nhận mã ba ký tự ISO. Bằng cách chuyển cùng một số lcid cho hàm này, bạn có thể lưu LangID tương ứng bằng mã ISO.

Lưu ý rằng MSDN nói LOCALE_ILANGUAGE không được sử dụng có lợi cho LOCALE_SLANG trên Vista trở lên, nhưng tôi cho rằng nhận xét không áp dụng cho việc sử dụng LOCALE_ILANGUAGE với LOCALE_RETURN_NUMBER.

Khi dự án của bạn phát triển, bạn có thể tạo một số tệp được bản địa hóa cho từng ngôn ngữ. Vì lý do này, tôi khuyên bạn nên lưu trữ các tệp đã bản địa hóa của mình trong các thư mục con được đặt tên theo ngôn ngữ. Microsoft đã sử dụng các thư mục có tên sau LangID, ví dụ "1033" làm thư mục tài nguyên tiếng Anh. Tôi nghĩ rằng sẽ thân thiện hơn khi sử dụng mã ba chữ cái, chẳng hạn như "ENU \ name.dll". Trong mọi trường hợp, thư mục con là một giải pháp đơn giản và hy vọng sẽ không làm phức tạp quá trình xây dựng của bạn nhiều như thay đổi tên tệp đích.

+0

Rất tiếc, tôi không có quyền truy cập vào LCID, nhưng muốn có LANGID từ mã ngôn ngữ có ba chữ viết tắt (mã giả-ISO). – Jonas

+0

FWIW, MS muốn chúng tôi di chuyển khỏi LOCALE_ILANGUAGE vì họ muốn chuyển sang chỉ "id lang", một id văn bản la .NET. iow họ cố gắng thuyết phục chúng tôi rằng LANGID * có thể * chết một ngày nào đó, ít nhất là cho các ngôn ngữ mới được hỗ trợ trong Win8 + –

Các vấn đề liên quan