HOWTO: Create and Call a String Resource in a DLL with a Specific Locale ID
ID: Q232625
|
The information in this article applies to:
-
Microsoft Visual Basic Professional and Enterprise Editions for Windows, versions 5.0, 6.0
SUMMARY
Occasionally, problems occur using a multi-language resource file. For example, please see the following article in the Microsoft Knowledge Base:
Q165188 INFO: Resource Language Decided by ResourceLocale Key on Win95
To work around these problems, create a localized string table and attach it to a DLL as a resource. This DLL can be loaded and strings displayed based on the current locale set in the Regional Settings. This technique requires that a separate resource DLL be created for each locale where your application is distributed.
MORE INFORMATION
To build the sample below you must to create two DLLs with an embedded resource file. You also need to create a standard EXE project that displays the strings stored as resources in the DLLs. The DLL file names contain the locale identifier associated with the regional setting selected by the user.
-
To create the DLLs with an embedded resource string table, do the following. The first time through the steps a DLL containing a Canadian English String table is created. The second time a US English string table is created and embedded in a DLL:
-
Start a new Visual Basic ActiveX DLL project. Class1 is created by default.
-
On the Add_Ins menu, select Add-In Manager. In the Add-In Manager dialog box, double-click the Visual Basic 6.0 Resource Editor. Confirm that the LoadBehavior column on the right-hand side of the window specifies Loaded, and click OK.
-
From the Tools menu, click the Resource Editor menu item.
-
In the Visual Basic Resource Editor, click on the 'abc' icon to bring up the Edit String Tables dialog box.
-
Double-click the language displayed, click the drop-down arrow, and select English (Canadian) from the drop-down combobox.
-
Double-click the text field below the language and enter the following:
Canadian English.
-
Make certain that the id number associated with this string is 101.
-
Dismiss the Edit String Table dialog box by clicking on the X in the upper-right-hand corner.
-
Click on the Save icon in the Visual Basic Resource Editor dialog box and save the file in a folder named resourcedll as res1009. This automatically adds the RES file to the DLL project that you have created.
-
On the Project menu, select Project1 Properties. Change the Project Name field from Project1 to resdll1009.
-
Save the resdll1009 project in the resourcedll folder.
-
Compile the resdll1009 project, saving the DLL to the resourcedll folder, making certain the Filename is resdll1009. The name of the DLL is important because it will be loaded in the code using this file name.
-
Create a second DLL by repeating steps 1 - 14 with the following modifications:
In step 5, set the language to English (US).
In step 6, enter the text: US English
In step 9, save the RES file in the same folder but use the name res409.
In step 10, name of the project resdll409 instead of resdll1009.
In step 11, save the resdll409 project to the resourcedll folder.
In step 12, compile the resdll409 project, saving the DLL to the resourcedll folder, and making certain the file name is resdll409.
-
Perform the following steps to create the Standard EXE project:
-
Start a new Visual Basic Standard EXE project. Form1 is created by default.
-
Add a label (Label1) to Form1.
-
Add the following code to the General Declarations section of Form1:
Option Explicit
Private Declare Function GetThreadLocale Lib "kernel32" () As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" _
(ByVal lpLibFileName As String) As Long
Private Declare Function LoadString Lib "user32" Alias "LoadStringA" _
(ByVal hInstance As Long, ByVal wID As Long, ByVal lpBuffer As String, _
ByVal nBufferMax As Long) As Long
Private Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" _
(ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, _
ByVal cchData As Long) As Long
Private Const LOCALE_IDEFAULTANSICODEPAGE = &H1004&
Private Const LOCALE_SENGCOUNTRY = &H1002
Private Const LOCALE_SNATIVECTRYNAME = &H8
Private Const LOCALE_SCOUNTRY = &H6
Function GetCharSet(sCdpg As String) As Integer
Select Case sCdpg
Case "932" ' Japanese
GetCharSet = 128
Case "936" ' Simplified Chinese
GetCharSet = 134
Case "949" ' Korean
GetCharSet = 129
Case "950" ' Traditional Chinese
GetCharSet = 136
Case "1250" ' Eastern Europe
GetCharSet = 238
Case "1251" ' Russian
GetCharSet = 204
Case "1252" ' Western European Languages
GetCharSet = 0
Case "1253" ' Greek
GetCharSet = 161
Case "1254" ' Turkish
GetCharSet = 162
Case "1255" ' Hebrew
GetCharSet = 177
Case "1256" ' Arabic
GetCharSet = 178
Case "1257" ' Baltic
GetCharSet = 186
Case Else
GetCharSet = 0
End Select
End Function
Function StripNullTerminator(sCP As String)
Dim posNull As Long
posNull = InStr(sCP, Chr$(0))
StripNullTerminator = Left$(sCP, posNull - 1)
End Function
Private Sub Form_Load()
Dim hInst As Long, lResult As Long, x As Long
Dim LCID As Long, sLcid As String
Dim resString As String * 255
Dim sCodePage As String
sCodePage = String$(16, " ")
Label1.AutoSize = True
Label1.Caption = ""
LCID = GetThreadLocale() 'Get Current locale
sLcid = Hex$(Trim$(CStr(LCID))) 'Convert to Hex
' Display decimal value of the LCID (Hex in Parentheses)
Form1.Caption = "LCID " & LCID & " (" & sLcid & ")"
x = GetLocaleInfo(LCID, LOCALE_IDEFAULTANSICODEPAGE, _
sCodePage, Len(sCodePage)) 'Get code page
sCodePage = StripNullTerminator(sCodePage)
' Load dll with string table resource.
' Might need to change path for the resdll.
hInst = LoadLibrary("resdll" & sLcid & ".dll")
' Get string with ID 101.
lResult = LoadString(hInst, 101, resString, 255)
With Label1.Font
.Name = "Lucida Sans Unicode"
.Size = 14
.Charset = GetCharSet(sCodePage) 'Convert code page to charset
End With
' Display the localized string.
Label1.Caption = resString
End Sub
-
You might need to modify the path to the Resource DLL in the code above. Run the application and the localized string should appear.
-
Compile this Standard EXE project.
-
Set the Regional Settings to English (Canada), which will require a reboot on some operating systems. Run the compiled application. This should display the Canadian English string in the label.
-
Close down the application and change the regional settings to English (US). Run the program again and the US English string should be displayed.
This sample works as a compiled EXE. It does not detect a change to the Locale ID if it is modified while the application is running or if run in the IDE. To update to the current Locale ID, create an ActiveX EXE that can be created in a new, separate thread, and retrieve the Locale ID (LCID).
The following Microsoft Knowledge Base article provides details:
Q217751 HOWTO: Get the Current User Locale ID in a VB EXE Without Restarting
Make certain your system has the appropriate code page and fonts. If you are going between code pages you need to use the Resource Editor Add-In that comes with Visual Basic 6.0 on the localized platform or create the RC file from scratch using appropriate language settings and compile with the RC.exe resource compiler.
REFERENCES
For additional information about using resource files for localization, please click the article number below to view the article in the Microsoft Knowledge Base:
Q165188 INFO: Resource Language Decided by ResourceLocale Key on Win95
Q217751 HOWTO: Get the Current User Locale ID in a VB EXE Without Restarting
Additional query words:
International multilanguage
Keywords : kbsample kbDLL kbIntl kbResourceEd kbString kbVBp kbVBp500 kbVBp600 kbLocalization kbGrpVB kbDSupport
Version : WINDOWS:5.0,6.0
Platform : WINDOWS
Issue type : kbhowto
|