The subclasses of NlsPlatformResourceConverter are provided to enable pool dictionaries containing localized messages to be stored in and retrieved from platform resource file formats.
Dynamic link libraries (.DLL files) created using the Microsoft and IBM OS/2 resource compilers are supported. The class RCConverter can produce a resource compiler input file from a pool dictionary, and can re-create the pool dictionary from the input file and the dynamic link library it produces.
The first portion of the resource compiler input file generated by the RCConverter is a comment that identifies the file along with the date and time when it was created.
Immediately following the first comment is a series of define statements that describe the pool dictionary from which the file was created. Localized messages stored as IBM Smalltalk pool variables are identified by string keys in a pool dictionary; however, when these messages are stored in dynamic link libraries they must be identified by ordinal constants. The conversion of string identifiers to ordinal values is accomplished by associating each string identifier with an ordinal value using a define statement in the resource compiler input file. For example:
define <aPoolDictionaryKey> <anInteger>
Localized messages and their associated comments follow the series of define statements. Localized messages are represented as entries in a STRINGTABLE statement associated with an ordinal value declared in the series of define statements.
RCConverter provides the convertMessages:toResourceFile: and convertMessages:comments:toResourceFile: methods to convert a dictionary containing localized messages into a resource compiler input file. The dictionary containing localized messages must be keyed by string identifiers, and can contain only messages conforming to the conditions described in RCConverter limitations. An attempt to convert a dictionary containing messages that are not valid generates an error.
In addition to a file name and a dictionary containing localized messages, the convertMessages:comments:toResourceFile: method accepts a dictionary containing comments to be written into the resource compiler input file. The dictionary containing comments should have the same keys as the dictionary that contains localized messages. The comment dictionary must conform to the same limitations that apply to message dictionaries, but need not contain a comment for every message in the dictionary being converted.
The following code example creates a resource compiler input file:
"Create a resource compiler input file." | dict comments | dict := Dictionary new at: 'X' put: 'localized message X'; at: 'Y' put: 'localized message Y'; at: 'Z' put: 'localized message Z'; yourself.
comments := Dictionary new at: 'X' put: 'comment X'; at: 'Y' put: 'comment Y'; yourself. "Store the new pool dictionary in Smalltalk." Smalltalk at: #DemoPool put: dict. RCConverter new convertMessages: (Smalltalk at: #DemoPool) comments: comments toResourceFile: 'demo.rc'
The preceding example illustrates how dictionaries containing localized messages and comments are converted into a resource compiler input file. The example produces the resource compiler input file called demo.rc, whose contents are presented in the following example:
/* Resource File for: #DemoPool. This file is generated automatically for use as the input file for the Microsoft Resource Compiler. When this file was constructed Smalltalk message identifiers were converted into numeric identifiers stored as a group of #define statements within this file.
This file is: demo.rc Creation date: 14.03.94 at: 14,37,12 This file was created with the following Smalltalk locale settings: Language: german Territory: switzerland Code page/Language driver: deu */
#define X 0 #define Z 1 #define Y 2 STRINGTABLE BEGIN 0, "localized message X" /* comment X */ 1, "localized message Z" 2, "localized message Y" /* comment Y */ END
RCConverter provides the indexFrom: and messagesFromDLL:index: methods to rebuild a dictionary containing localized messages from messages stored in a dynamic link library (DLL).
Dynamic link libraries use integers to identify localized messages and IBM Smalltalk pool dictionaries use string identifiers. You must provide the mapping between string identifiers to be used in the reconstructed dictionary and the integer identifier used by the dynamic link library. The indexFrom: method can be used to reconstruct an index from a resource compiler input file based upon a series of define statements that bind string identifiers to integer values. The following example demonstrates the process of rebuilding an index from an existing resource compiler input file:
"Retrieve an index by parsing a resource compiler input file." ^RCConverter new indexFrom: 'demo.rc'
The messagesFromDLL:index: protocol answers a reconstructed dictionary of localized messages based upon the contents of a dynamic link library and an index provided by the developer. messagesFromDLL:index: accepts any dictionary that provides mappings between strings and integers as its index parameter, although the indexFrom: method is the recommended mechanism for generating the index. The messagesFromDLL:index: method does not require a resource compiler input file to function. The following example illustrates the reconstruction of a dictionary containing localized messages from a dynamic link library:
"Answer a dictionary reconstructed from a DLL." | converter index | converter := RCConverter new. index := converter indexFrom: 'demo.rc'. ^converter messagesFromDLL: 'demo.dll' index: index.
Messages must be instances of String or DBString containing Characters whose values are strictly greater than zero (1 to 65535).
All errors codes and their corresponding messages are detailed below. Each error code is associated with a descriptive error string and an error object, which is typically related to or the cause of the current error. This error object can be obtained by sending the message currentErrorObject to an instance of RCConverter. Similarly, the descriptive error string can be obtained by sending the message currentErrorString to an instance of RCConverter. The interpretation of the error object for each error follows.
Error object: The invalid message name.
Error object: The invalid message text.
Error object: The invalid message name.
Error object: The invalid message text.
Error object: The invalid message name.
Error object: File name (String) of the file that could not be opened.
Error object: File name (String) of the DLL that could not be opened.
Error object: The integer identifier of the unreadable message.
Error object: The module handle that could not be closed.
Error object: File name (String) of the invalid resource file.