An optional additional step is to isolate the resources for each language into a
separate resource-only DLL. Under this architecture, the main XLL contains the
resources for the primary language of the add-in, and each other language is
held in a separate DLL.
A new language can be added by a third party, without any changes to the
The new language module can be distributed separately from the original add-in.
The build process is more complicated.
The authors of the add-in must distribute a resource file containing a string
table, so that the authors of the new language resource can use the correct
If new strings are added to the original version, they must also be added to
each of the resource-only DLLs.
Distribution and installation of the add-in is more complex.
It should be clear that there is no clear-cut correct decision here. Different
working environments will require different solutions, and the frequency of
changes to the add-in will also influence the decision.
You should select an appropriate naming convention for your resource-only DLLs.
You will need to be able to list them using a directory search, and to be able
to impute the language ID from the file name.
In our sample InterMulti.xll, we used "InterMultiRes_NNNN.dll", where NNNN is
the decimal representation of the language ID, e.g. "InterMultiRes_1036.dll"
for French (France). We also assumed that all the resource-only DLLs would be
in the same directory as the XLL itself.
Creating a resource only DLL
To create a resource only DLL, follow these steps:
Create an empty DLL project.
In Visual Studio 6, create a "Win32 Dynamic-Link Library" with "An empty DLL
In VS .NET or VS 2005, use "Win32 Project" in the "Visual C++ Projects" group, and select
Application type "DLL" under "Application Settings".
Put a check against "Empty project".
Add the linker option /NOENTRY to the linker settings for each build.
In VS 6, add "/NOENTRY" to the "Project Options" edit field in the Project
Settings/Linker/Customize tab of the "Project Settings" dialog.
In VS.NET or VS 2005, add "/NOENTRY" to the "Additional Options" edit field in the
Configuration Properties/Linker/Command line tab of the project properties
Create a resource file.
In VS 6, create a new "Resource Script" and enter a file name with the
In VS .NET or VS 2005, create a new "Resource File (.rc)" and enter a file name with the
Copy all the native-language resources from the core XLL to your new resource
Change the language of each resource to that of the resource-only DLL, and
change the text and bitmaps as required.
- If a resource file containing error strings is available,
change the inclusion
to the appropriate language, e.g.
For a description of these files, see here.
For more information see the topics "resource-only DLLs" in MSDN help.
Creating resource only DLLs for further languages
To support further languages, follow these steps for each language.
Copy the entire project to a new (appropriately named) directory
Change the name of the output DLL in the linker settings.
Translate all strings and bitmaps to the new language.
You will need to write support code for the purposes listed below. See the
Localized (Multiple DLLs) sample for and example of the required
Listing the available languages. This usually involves searching a directory
for DLL files with appropriate names, and then imputing the language from the
Determining the user's current language. You should retrieve the user's current
regional settings with XllGetStringLanguageID,
and then try to match one of the available languages. If no complete match is
available, then you should try to match the main language only (ignoring
Loading the DLL. Once you have determined the full file path of the DLL, use
::LoadLibrary() to get its instance handle, and pass it to
Reload all resources. If you change the language at run-time, after the XLL has
been loaded, you should (i) unregister all localized resources, (ii) set the
resource handle using XllSetStringResourceHandle and (iii) re-register
There are any number of ways to deploy the resource-only DLLs. Examples include:
Named sub-directories. All resource-only DLLs have the same name. Each is held
in a sub-directory which reflects the language ID. e.g. "1033\MyDll.dll",
"1036\MyDll.dll". This technique is used by MSDN.
Named files using numeric IDs, e.g. "MyDllRes_1033.dll", "MyDllRes_1036.dll".
This technique is used by the Localized (Multiple
Named files using language acronyms, e.g. "MyDllFRA.dll", "MyDllENU.dll". This
method is used by MFC.
Whatever technique you have chosen for determining the name and path of your
resource-only DLLs, you must ensure that they are delivered to the appropriate
directory when the XLL itself is installed.
You can find an example of this technique in the Localized
(Multiple DLLs) sample.
Next: Conversion of an existing project >>
International support | Global resource functions