GoRC
Resource Compiler Manual

GoLogo A "Go" development tool: http://www.GoDevTool.com

Version 1.0

by Jeremy Gordon - email

Introduction
Starting the Resource Compiler
Directives (eg. #define, #if, #include)
Other Symbols
Numbers
Arithmetic
Strings and String Manipulation
Windows Character Set
Raw Data Resources (eg. cursor, bitmap, RCDATA etc)
STRINGTABLE Resource
VERSIONINFO Resource
ACCELERATORS Resource
MENU Resource
DIALOG Resource
VERSION and CHARACTERISTICS
LANGUAGE
Capitalisation of nameIDs and types
Legal Stuff

Introductiontop

This document assumes that the reader has some knowledge of resources, what they are and how they work.

This document is intended for use with the GoRC resource compiler. There are some slight differences in the permitted syntax between the Microsoft Resource compiler and GoRC. In general GoRC will accept all RC source files that the Microsoft Resource compiler will accept but is slightly more flexible in its syntax.

RC source files (those with an ".rc" extension) should be text without formatting codes, other than carriage return, linefeed or tabs, such as produced by most simple text editors. More sophisticated word processors can also produce such files if they are instructed to produce TXT files, ASCII or ANSI files.

The resource script and include files can be in Unicode format. If so, GoRC expects a Byte Order Mark (BOM). GoRC can read the UTF-8 Unicode format with BOM, or the UTF-16LE Unicode format with BOM.

GoRC can make two types of binary resource files from a resource script. It can make an OBJ file in COFF format, which is suitable for linking with other OBJ files to produce the final EXE or DLL. It can also produce a RES file, which is an intermediate file in binary format. GoRC can also convert a RES file to an OBJ file.

The OBJ file made by GoRC can either be in Win32 format (the default) or Win64 format if you specify the /machine AMD64 or /machine X64 switch in the command line.

Here are the syntax rules which are used in this reference:-

Starting the Resource Compilertop

The command line syntax is:-

GoRC [command line switches] filename[.ext]

Where,

command line switches		can be one or more of the following:-
							/h or /?			help
							/d				define a word
							/o				create OBJ file
							/r				create RES file
							/fo				specify output file
							/machine AMD64	or
							/machine X64		object output file will be in 64-bit format
							/ne				no error messages
							/ni				no information messages
							/nw				no warning messages
							/nu				no warning message for a user-defined resource type
							/no				no output messages at all

filename					is the name of the resource script

ext						is the extension of the filename of the resource script

Input and Output files
The default action of GoRC is RC > RES and OBJ.
If no extension is given in the command line and GoRC cannot find filename.RC then it looks for filename.RES. If found, this results in the action RES > OBJ.

The default action can be overridden to achieve RC > RES in the following ways:-

The default action can be overridden to achieve RC > OBJ in the following ways:-

You can ensure the action is RES > OBJ by giving the input file with the extension RES.

By default, the output filenames will be the same as those of the input file, but you can use the /fo switch to change this. This is used as follows:-

By default, the output files will be placed in the same directory as the input file. You can specify a full path for the output files when using the /fo switch. You can enclose the filenames in quotes to permit the use of filenames with spaces and other unusual characters.

GoRC can work with Unicode input and output filenames, but the extensions used must be as set out above.

Errors and Warnings
Errors will cause the Resource Compiler to stop and no output files will be made. The console then shows the nature of the error and where it occurred. (unless the command line switch /ne has been specified). The Resource Compiler will also return with a code of 1, which will be likely to halt the build process if you are using a make file.

Warnings do not stop the Resource Compiler. A warning will be given (unless the command line switch /nw has been specified) if:-

A warning will also be given if an expression has been defined more than once in the command line, resource script or in a non ".h" include file. This is because it would be unusual to define an expression more than once and it may be that this is a programming error. It is perfectly permissible to cancel a previous definition using #undef so that the expression can be redefined. In that case no warning is given. Also, because the Resource Compiler does not always need to look into ".h" files to evaluate an expression, and because it is presumed that such ".h" files ought to be free of such errors, no check of previous definitions in header files is carried out.

Directivestop

Directives are words in the resource script which give instructions to the Resource Compiler.

There are 3 types of directives:-

The Defining Directives

Evaluating types

These are #define macros which evaluate to a number or to a quoted string:-

#define name value

From this point when name is encountered in the resource script it is replaced by value.

Examples
#define IDC_BUTTON 0x20
#define DLGCONTROL 0x20 | 0x40
#define DLGTEXT "Hello world"
#define OTHER DLGCONTROL + IDC_BUTTON
#define WINNT
(this sets the name WINNT to a value of 1, that is, TRUE)

The RC compiler automatically defines RC_INVOKED, so that you can use the conditional directives to skip over unwanted resource script text.

Example
#ifndef RC_INVOKED
skipped text
#endif

You can define a name from the command line:-

Examples
GoRC /d WINVER=400h mainres
This compiles the resource script mainres, on the basis that WINVER is equal to hex 400 throughout.

GoRC /d WINNT mainres
This compiles the resource script mainres, on the basis that WINNT has a value of 1 (that is, TRUE).

GoRC /d WINNT=55h /d good=0x44 mainres
Example of more than one definition.

GoRC /d WINNT=330, good=0x44 mainres
Example of more than one definition using comma.

To remove the value for a definition and have name undefined, use #undef:

#undef name

From this point in the resource script any earlier value for the name given by a #define is no longer used.

Examples
#undef IDC_BUTTON
#undef DLGCONTROL

Non evaluating types

These are #define macros which do not evaluate to a single result:-

#define name value1 value2 value3

From this point when name is encountered in the resource script it is replaced by value1 value2 value3.

Example
#define GRASSHOPPER Deep Influences On Us
#define FILENAME README
#define EXTENSION TXT
FILENAME.EXTENSION (becomes README.TXT)

Macros with arguments

These are #define macros which use the arguments supplied when the macro is used.

Syntax for the macro in which the arguments are declared:-

#define  name(arg1,arg2,arg3,...)   use of arguments

Syntax to supply the arguments:-

name(arg1,arg2,arg3,...)

Examples
#define NIM($a,$b) $a+$b
NIM(23,45)
(result is 68)

#define NIMROD($a,$b) #$a
NIMROD (HANG,OVER)
(result is "HANG")

Note that the number of arguments which are supplied must exactly match the number of arguments declared, but they need not all be used. When an argument is declared there must be no space between the macro name and the arguments, but there can be spaces when the argument is supplied or used.

The Include Directive

The #include directive will cause the Resource Compiler to load and look at the specified file:-

#include path\filename

Where,

path\filename	can be either:-
				a quoted string
				a non-quoted string
				a string in less-than and greater-than characters

The Resource Compiler will look for the file using the path specified. If no path is specified it will look in the current directory. If the file is not found it will look for it in the path given by the INCLUDE environment string. You can set the INCLUDE environment string using the SET command in the MSDOS window, or by calling the SetEnvironmentVariable API. You can also use control panel, system, advanced, environment if your operating system will permit this, followed by a reboot. Note: there may be a different environment string for each folder or sub-folder. Ensure the environment string you wish to use is in the current directory.

To the Resource Compiler there are two types of #include files:-

You can nest #include files but it is probably good practice to avoid this as far as possible.

Definition Priority

A #define directive in an ".h" include file is regarded as of lower priority than a #define directive in the command line, resource script or in a non ".h" include file. Therefore if there is any conflict between the #defines, the #define in the ".h" include file will be ignored.

The Conditional Directives

With these directives you can select at compile-time that part of the resource script or of the defining directives which you want to be compiled. This may be useful if, for example, you want to make different versions of your program from the same resource script.

The syntax of the basic structure of a conditional directive in its simplest form is as follows:-

#if condition
	text A
#endif

Here if the condition is TRUE text A will be compiled. If, however, the condition is FALSE, the compiler will jump over text A and will continue compiling from the #endif.

You can add something to do if the condition is FALSE as follows:-

#if condition
	text A
#else
	text B
#endif

Here if the condition is TRUE, text A will be compiled, but text B will not be compiled. If, however, the condition is FALSE, text A will be jumped over but text B will be compiled.

The #endif indicates the end of the conditional frame, so that all text after that will be compiled.

The #else statement must always be next before the #endif.

You can add a further condition to the frame:-

#if condition1
	text A
#elif condition2
	text B
#endif

Here if condition1 is TRUE, text A will be compiled, but text B will be jumped over and compilation will continue from the #endif. If, however, condition1 is FALSE, text A will be jumped over to the #elif when condition2 will be tested. If then condition2 is TRUE, text B will be compiled. "#elif" is the same as "#elseif".

Adding the #else to the above conditional frame produces:-

#if condition1
	text A
#elif condition2
	text B
#else
	text C
#endif

Here if condition1 is TRUE, text A will be compiled, but text B and text C will be jumped over and compilation will continue from the #endif. If, however, condition1 is FALSE, text A will be jumped over to the #elif when condition2 will be tested. If then condition2 is TRUE, text B will be compiled, and text C will be ignored; if, however condition2 is FALSE text B will be jumped over to the #else and text C will be compiled.

You can have as many #elifs as you like in each conditional frame, but there can only be one #else per frame, and each #if must have a corresponding #endif. Some programmers nest the conditional frames, but this can become very confusing and may not be good programming practice. If this is done it is recommended that you label each #endif with a comment so that you can see to which #if it refers.

Types of #if statements

#ifdef expression		where expression is a word which may be defined in the resource script
					or in a header file. This statement returns TRUE if the expression is defined
					and FALSE if it is not defined. The expression must be a word and not a
					number nor a quoted string.
		
#ifndef expression		as above but this statement returns FALSE if the expression is defined and
					TRUE if it is not defined.

#if  0					this statement always returns FALSE and so it can be used to jump over
					text which ought to be ignored.

#if expression1  relational-operator  expression2

					where,

					expression1 must be a word which is defined elsewhere in the file,
					in an include file or on the command line. It cannot be a number.

					relational operator can be one of the following:-
						>=	greater than or equals
						<=	less than or equals
						==	equals
						=	equals
						!=	not equal
						>	greater than
						<	less than

					expression2 can be a number or a word which is defined elsewhere in
					the file, in an include file or on the command line, which evaluates to a
					number. For example, #if WINVER>=400h will return TRUE if WINVER
					is defined as 400h or more.

#if ! expression		this reverses the result of the condition, so #if is not the same as #if !.
					For example, #if!0 would return TRUE.

Other Symbolstop

These are some other symbols which may be used in the resource script or a header file and which have a special meaning to the Resource Compiler.

;		single line comment - everything after this to the end of the line is ignored

//		single line comment - everything after this to the end of the line is ignored

;;  ...		block comment - can span several lines and everything between the leading
     ...  ;;	and trailing marks is ignored

/*  ...		block comment - can span several lines and everything between the leading
     ...  */	and trailing marks is ignored

\		line continuation - at the end of a line or just before a comment, allows processing to
		continue with the material on the next line (cannot be used in quoted strings or filenames)

{		same as BEGIN

}		same as END

-number	means the number is negative (eg. -22h if a dword becomes 0FFFFFFDEh)

~number	means the number is inverted (eg. ~22h if a dword becomes 0FFFFFFDDh)

+		plus for addition (eg. 22h + 3h produces 25h)

-		minus for subtraction (eg. 22h - 3h produces 1Fh)

| or ¦		bitwise OR (eg. 22h | 3h produces 23h)

&		bitwise AND (eg. 22h & 3h produces 2h)

!value	in arithmetic, this causes the value to be inverted and
		then ANDed with the existing, and is the same as minus value

NOT value	same as above

#		in a #define macro, this causes quotes to be added to what follows
		eg. #HELLO becomes "HELLO"
		eg. #(MAJOR.MINOR) becomes "MAJOR.MINOR"

##		in a #define macro, this joins two elements, removing all spaces in between
		eg. PATCH ## WORK becomes PATCHWORK

(...)		in a #define macro, the material within the parentheses is evaluated first

Numberstop

The Resource Compiler recognises the following types of numbers, for example:-

6666666h	a hex number
3434343H	a hex number
9999999D	a decimal number
22553388d	a decimal number
34567789	a decimal number
0x456789		a hex number
456L		specifies the number is to be recorded as a dword
			where otherwise it would be a word

Arithmetictop

The resource compiler can perform limited arithmetic on the following:-

Examples of arithmetic
66h+2h CURSOR first.cur
#define BELLS 200h | 22h + 1h
BELLS+1000h ICON icon1.ico
BELLS-1h ICON icon1.ico
STYLE WS_TABSTOP | WS_GROUP | WS_DISABLED
DIALOG 0x34+2,0x20,0x300-0x60,400-200

The Resource Compiler cannot resolve more complex formulae involving for example logical operators, decimal points, multiplication or division.

Strings and String Manipulationtop

Quoted strings in the stringtable resource and in all text for dialogs and menus must be kept in the binary resource files and in the EXE in Unicode. If the resource script is an ANSI text file, however, the strings will be in ANSI characters. In that case the Resource Compiler converts them to Unicode using the API MultiByteToWideChar. This API uses the current codepage for this conversion, so you need to ensure that at compile time your machine is set to use the same codepage as was used when the source script was made.

If the resource script is a Unicode file, then codepages are not used; the strings are used as they appear in the resource script.

The strings are put in the RES file (or OBJ file) in Unicode whether or not you use the "C" style Unicode indicator L"string". The Resource Compiler regards the L"string" indicator as implicit for these types of strings. So there is no need to use that indicator in your resource script (unless you want to insert special Unicode characters - see below).

There is no implicit L"string" indicator for quoted strings in the raw data resources (eg. RCDATA). Therefore in an ANSI file such strings are not converted to Unicode unless L"string" is specified.

All quoted strings may contain escape sequences which are dealt with in a special way by the Resource Compiler:-

&		in menu title strings this causes the system at run-time to create an
		accelerator for the menu item using the character following the ampersand.
		If you need an ampersand include it twice eg. &&

" "" "		double-up the quotation marks to retain them. For example
		"""Hello there""" will be kept as "Hello there" and
		"He said ""Hello there"" quickly" will be kept as He said "Hello there" quickly

""		an empty string (useful for example in static controls
		where the text is to be inserted during run-time later)

\t		tab (converted to the 9h TAB character)

\a		alert (converted to the 8h BELL character)
		in menus this is used to align all the following text to the right

\n		new line (converted to the 0Ah LINEFEED character)

\r		return (converted to the 0Dh CARRIAGE RETURN character)

\\		converted to one backslash only

\number	see below

\other	the backslash is regarded as an ordinary backslash

\number to produce a special character

In all quoted strings which are converted by the Resource Compiler you can have:-

\number

This then will cause the character represented by number to be inserted in the text. For example, "Copyright \251 2005" inserts a © symbol in the text. Strange! The © symbol, as everybody knows, is ANSI value 169, or A9 in hex.

However, the Resource Compiler uses octal numbers in this feature rather than decimal, ie. all digits are to base 8. Why? This is simply to provide compatibility with existing resource scripts.

Sometimes \number can look rather odd. For example "The entrance fee was \4423", is converted to "The entrance fee was $23". Here the Resource Compiler does not try to find character 442 octal or 4423 octal because it knows that this value is too high. This works fine for characters above 38 octal, but for characters with values less than this, for example 12 octal which is the value 0Ah (linefeed) there could be confusion, for example "We found on average about\1223 flies in each of the soups". This should be written "We found on average about\01223 flies in each of the soups". This is because the Resource Compiler will only look at 3 octal digits and no more, so it stops after the \012 (linefeed), and the value 23 is kept in the text properly. Of course you could use \n instead to ensure there is no chance of confusion and this would be better.

\number in hex rather than in octal

You can also use hex values when entering \number, by including x after the backslash. For example the hex version "Copyright \xA9 2005" is the same as "Copyright \251 2005" which is the octal version. Again the Resource Compiler will not look beyond the second hex digit for the value, so ensure that where small values are used you insert the zero if there is any danger of confusion. For example in "The capacitor had a value of 3\xb5farads" the Resource Compiler does not take the hex number b5f, but looks only at b5 hex. However, in the string "It returned to Earth\x0aafter 44 years with 5 more people on board", the zero is required to avoid using the hex number aa as the special character.

\number in Unicode strings

The Resource Compiler looks at up to four hex digits in \number if the string is expressly declared to be a Unicode string. You can do this by using the "C"-style indicator L"string" for the string. So, for example to create a string for a dialog button which displays a Shekel you would use the following string:-

L"\x20AA"

This creates the Unicode special character 20AAh (the Shekel sign).

You would not need to do this if you used Unicode format files, since you could display the Shekel normally and it would be coded properly by the Resource Compiler.

The Windows Character Settop

The character set used when the string is written to the screen by the menu, dialog or other method, depends on which character set is in use in the computer running the EXE. For computers used in English this is usually the Windows Character Set. A table of octal values may be difficult to find so one is provided as follows for your use, along with another table afterwards with the hex values.

The Windows Character Set and octal values

Space!"#$% &'()*+ ,-
404142434445 464750515253 5455
./01234 56789:;
565760616263 646566677071 7273
<=>?@AB CDEFGHI
74757677100101 102103104105106107 110111
JKLMNOP QRSTUVW
112113114115116117 120121122123124125 126127
XYZ[\]^ _`abcde
130131132133134135 136137140141142143 144145
fghijkl mnopqrs
146147150151152153 154155156157160161 162163
tuvwxyz {|}~
164165166167170171 172173174175176177 200201
202203204205206207 210211212213214215 216217
220221222223224225 226227230231232233 234235
¡¢£¤ ¥¦§¨© ª«
236237240241242243 244245246247250251 252253
¬®¯° ±²³´ µ·¸ ¹
254255256257260 261262263264265 266267270271
º»¼½ ¾¿ÀÁ ÂÃÄÅ ÆÇ
272273274275276277 300301302303304305 306307
ÈÉÊË ÌÍÎÏ ÐÑÒÓ ÔÕ
310311312313314315 316317320321322323 324325
Ö×ØÙ ÚÛÜÝ Þßàá âã
326327330331332333 334335336337340341 342343
äåæç èéêë ìíîï ðñ
344345346347350 351352353354355 356357360361
òóôõ ö÷øù úûüý þÿ
362363364365366367 370371372373374375 376377

The Windows Character Set and hex values

Space!"#$% &'()*+ ,-
202122232425 262728292A2B 2C2D
./01234 56789:;
2E2F30313233 343536373839 3A3B
<=>?@AB CDEFGHI
3C3D3E3F4041 424344454647 4849
JKLMNOP QRSTUVW
4A4B4C4D4E4F 505152535455 5657
XYZ[\]^ _`abcde
58595A5B5C5D 5E5F60616263 6465
fghijkl mnopqrs
666768696A6B 6C6D6E6F7071 7273
tuvwxyz {|}~
747576777879 7A7B7C7D7E7F 8081
828384858687 88898A8B8C8D 8E8F
909192939495 969798999A9B 9C9D
¡¢£¤ ¥¦§¨© ª«
9E9FA0A1A2A3 A4A5A6A7A8A9 AAAB
¬®¯° ±²³´ µ·¸ ¹
ACADAEAFB0 B1B2B3B4B5 B6B7B8B9
º»¼½ ¾¿ÀÁ ÂÃÄÅ ÆÇ
BABBBCBDBEBF C0C1C2C3C4C5 C6C7
ÈÉÊË ÌÍÎÏ ÐÑÒÓ ÔÕ
C8C9CACBCCCD CECFD0D1D2D3 D4D5
Ö×ØÙ ÚÛÜÝ Þßàá âã
D6D7D8D9DADB DCDDDEDFE0E1 E2E3
äåæç èéêë ìíîï ðñ
E4E5E6E7E8 E9EAEBECED EEEFF0F1
òóôõ ö÷øù úûüý þÿ
F2F3F4F5F6F7 F8F9FAFBFCFD FEFF

Resource Statements

Resource statements are the instructions to the Resource Compiler which contain the information from which the output file is actually made. They fall into four main categories:-

Raw data resource types (a) taking data from a filetop

With these resources the Resource Compiler merely takes raw data from an input file and adds it to the output file (sometimes with some extra processing). Hence the data from these files makes its way to the EXE, when the file is linked, for use during run-time. This is a convenient way to keep the data from such files in the EXE. An alternative would be to ship the individual files with the product for loading at run-time, but this runs the risk that those files may get lost.

The data (as raw data) can be used at run-time by calling the FindResource and LoadResource APIs, but there are some specific APIs which also provide manipulation of the data. The various raw data resource types which work using files, their resource type numbers, and the specific API (if any) to load them during run-time are:-

CURSOR			1	LoadCursor or LoadImage
BITMAP			2	LoadBitmap or LoadImage
ICON			3	LoadIcon or LoadImage
FONT			8	no longer in use
RCDATA			10
MESSAGETABLE	11	FormatMessage
PLUGPLAY		19
VXD				20
ANICURSOR		21
ANIICON			22
HTML			23
MANIFEST		24
User-defined resource

The User defined resource is a resource holding raw data only, which is of the type defined by the user. It can be defined by name, for example, MyRes, or by number, which can be any 16-bit number above 0FFh. The numbers 1 to 0FFh are reserved for the system defined resources.

The general syntax for these resource types in the resource script (using CURSOR as an example) is:-

nameID CURSOR filename

Where,

nameID	can be either:-
			a 16-bit number of value 1 to 7FFFh
			an expression which evaluates to that number
			a name (except for FONT, a FONT resource cannot be identified by name)
filename	can be either:-
			a quoted string
			a non-quoted string
			a string in less-than and greater-than characters

			Unless the file is in the current directory, the full path should be given.
Examples
2 CURSOR happy.cur
0x6666 BITMAP c:\bitmaps\happy.bmp
MyIcon ICON "happy.ico"
#define ID_MINE 22
ID_MINE ICON <happier.ico>
44h RCDATA happy.txt
ID_MINE RCDATA happier.txt
1 MANIFEST "YourApp.manifest"
788h MYRES happier.txt			;(a user-defined resource)
MY_CAT WAVE sounds/cat.wav	;(a user-defined resource)
788h 100h happier.txt			;(a user-defined resource)

Raw data resource types (b) taking data from resource script

These resources allow you to insert raw data into the EXE via the binary resource file. The Resource Compiler makes no alteration to the raw data. Unless use is being made of the ability of the system to distinguish between resources of different languages, assembler programmers would probably not find much use for this as it is so simple to use the data segment to keep data..

The data (as raw data) can be used at run-time by calling the FindResource and LoadResource APIs.

This type of resource is RCDATA (type number 10) when used with BEGIN and END, and not with a filename. Alternatively you can choose any name for the resource in which case it works the same way as RCDATA except that the resource type has a name. This is called a user-defined resource. Alternatively you can also simply provide any 16-bit number above 0FFh for the resource type.

The syntax for RCDATA used in this way is:-

nameID RCDATA
[defining-statements]
BEGIN
	raw-data
END

Or, in the case of a user-defined resource:-

nameID type
[defining-statements]
BEGIN
	raw-data
END

Where,

nameID				can be either:-
						a 16-bit number of value 1 to 7FFFh
						an expression which evaluates to that number
						a name

defining-statements		need not be present, but can be either:-
						a VERSION statement
						a CHARACTERISTICS statement
						a LANGUAGE statement

						see below for details

type					can be either:-
						a 16-bit number greater than 0FFh
						an expression which evaluates to a 16-bit number greater than 255
						a name in characters

raw-data				can be either:-
						an ANSI quoted string
						a Unicode quoted string starting with L"
						a numerical value stored as a word
						a numerical value stored as a dword (ending in L)
Examples
0x3333 RCDATA
BEGIN
	"Hello world"
	"Hello world (zero terminated)\0"
	L"A Unicode version of the above\0"
	0x9999  ;hex number stored as a word
END

MyRes RCDATA
BEGIN
	1034	;decimal number stored as a word
END

MyRes MyResType
BEGIN
	10456L	;decimal number stored as a dword
	1234L,56666L,99999L	;decimal numbers stored as dwords
END

34h 100h
BEGIN
	33hL,34hL,35hL,36hL		;hex numbers stored as dwords
	0x37L,0x38L,0x39L,0x40L	;C-style hex numbers stored as dwords
END

The STRINGTABLE Resourcetop

The STRINGTABLE resource enables strings to be kept in the EXE to be recovered when needed at run time. For assembler programmers this would be an alternative to keeping the strings in the data segment. Even if you need to use Unicode strings, if you are using GoAsm as your assembler it is usually easier to keep the strings in data rather than to use the STRINGTABLE resource.

If the source file is in ANSI format, strings in the STRINGTABLE resource are automatically converted to Unicode by the Resource Compiler, so there is no need to use the "C" style Unicode indicator L"string". The Resource Compiler regards the L"string" indicator as implicit. The conversion is carried out using the API MultiByteToWideChar. This API uses the current codepage for this conversion, so you need to ensure that at compile time your machine is set to use the same codepage as was used when the source script was made.

If the source file is in Unicode format, then no conversion takes place and codepages are not used; the strings are used as they appear in the resource script.

One reason why the assembler programmer might wish to keep strings in a STRINGTABLE resource rather than in the data segment would be to take advantage of the ability of the system to distinguish strings of different languages at run-time.

The strings are kept in blocks of 16 strings. Each block will have the same language and also the same upper 12 bits of the ID which was specified in the resource script. The least significant 4 bits are blanked out and are not be recorded because it is assumed that the IDs run in sequence in each block from 0 to 0Fh. To make this assumption valid, if the string IDs are not in sequence the Resource Compiler has to insert empty strings. To reduce space requirements, therefore, it is best to keep the identifiers sequential.

To recover one of the strings, call LoadString giving the string identifier. It will then be copied into a buffer with a nul terminator.

The syntax for the STRINGTABLE resource is as follows:-

STRINGTABLE
[defining-statements]
BEGIN
stringID "string"
.........
END

Where,

stringID	can be either:-
			a 16-bit number which identifies the string
			an expression which resolves to that number
"string"	can be either:-
			a quoted string of not more than 4097 characters
			an expression which is defined elsewhere as a string

If the string straddles more than one line the Resource Compiler inserts a space and a line feed character (ASCII 0Ah) at the line break and all leading spaces on the next line in your resource script are suppressed.

Information resource types

These types of resources are used to keep information about the EXE in a certain format, for use by tools or for information to the user.

There are two types of such resources.

Firstly DLGINCLUDE (resource type17) which contains a filename which is read by the Microsoft Dialog Editor. This filename is that of the include file containing definitions when making dialogs. This information is not actually kept in the EXE, and is disgarded by the linker.

Its syntax is:-

nameID DLGINCLUDE filename

Where,

nameID	can be either:-
			a 16-bit number of value 1 to 7FFFh
			an expression which evaluates to that number
			a name
filename	can be either:-
			a quoted string
			a non-quoted string
			a string in less-than and greater-than characters
			unless the file is in the current directory, the full
			path should be given

The VERSIONINFO Resourcetop

Secondly, the VERSIONINFO resource (resource type 16), which is used to keep information about the version of the EXE and may be required during its installation or if it is updated.

The version information can be retrieved in various ways using the APIs GetFileVersionInfo, GetFileVersionInfoSize, and VerQueryValue. Also it is the information which appears in the "Version" property sheet when looking at the "Properties" of an Executable file in Windows.

The syntax for this resource is:-

1 VERSIONINFO
[fixed-info statements]
BEGIN
	BLOCK "StringFileInfo"
	BEGIN
		BLOCK lang-charset
		BEGIN
			string-value statements
		END
	END
	BLOCK "VarFileInfo"
	BEGIN
		VALUE "Translation"
		lang/char statements
	END
END

Where,

fixed-info statements	can be one or more of the following statements with data as in the following
					examples. The data is used by the Resource Compiler to fill a structure of
					13 dwords which is kept in the binary resource file and therefore in the EXE
					file (the VS_FIXEDFILEINFO structure)

FILEVERSION 3h,0Ah,0,3Dh
					this value needs to be written as four 16-bit values which
					are in fact recorded as two dwords: in this example the first dword
					(most significant) is 3000Ah and the second dword (least significant)
					is 3Dh, producing a version value of 3000A 0000003Dh.

PRODUCTVERSION 6666h,0000h,0000h,7777h
					defines a product version of 66660000 00007777h

FILEFLAGSMASK 3Fh	specifies which bits in the next parameter are valid

FILEFLAGS fileflags	which can be one or more of the following flags or values:-
VS_FF_DEBUG		(1= the file contains debugging information)
VS_FF_PATCHED		(4= the version information has been changed from the
					original shipping version)
VS_FF_PRERELEASE	(2= the file is a development version only and is not
					commercially available)
VS_FF_PRIVATEBUILD	(8= the file was not built using standard release procedures)
VS_FF_SPECIALBUILD	(20h= the file was built using standard release procedures but
					is a variation of the standard file of the same version number)
FILEOS fileos where fileos specifies the operating system for which the file was designed and can be one of the following values:-
VOS_UNKNOWN		(value zero - unknown)
VOS_DOS			(1000h= file designed for DOS)
VOS_NT				(4000h= file designed for Windows NT)
VOS__WINDOWS32	(4= file designed for 32-bit Windows)
VOS_NT_WINDOWS32	(40004h= file designed for 32-bit Windows running
					under Windows NT)
FILETYPE filetype where filetype specifies the general type of the file and can be one of the following values:-
VFT_UNKNOWN		(value zero=unknown)
VFT_APP			(1= its an application)
VFT_DLL				(2= its a DLL)
VFT_DRV			(3= its a device driver)
VFT_FONT			(4= its a font)
VFT_VXD			(5= its a virtual device)
VFT_STATIC_LIB		(7= its a static link library)
FILESUBTYPE subtype where subtype specifies more information about the type of file, and if filetype is VFT_DRV can be one of the following values:-
VFT2_UNKNOWN 		(value zero -unknown)
VFT2_PRINTER		(1= its a printer driver)
VFT2_KEYBOARD		(2= its a keyboard driver)
VFT2_LANGUAGE		(3= its a language driver)
VFT2_DISPLAY		(4= its a display driver)
VFT2_MOUSE		(5= its a mouse driver)
VFT2_NETWORK		(6= its a network driver)
VFT2_SYSTEM		(7= its a system driver)
VFT2_DRV_INSTALLABLE	(8= its an installable driver)
VFT2_DRV_SOUND	(9= its a sound driver)
VFT2_DRV_COMM		(0Ah= its a communications driver)

					if filetype is VFT_FONT it can be one of the following values:-

VFT2_FONT_RASTER		(1= a raster font)
VFT2_FONT_VECTOR		(2= a vector font)
VFT2_FONT_TRUETYPE	(3= a TrueType font)

					if filetype is VFT_VXD this value must be the virtual-device
					identifier included in the virtual-device control block
The names of the fixed-info statements are fixed and are used by the Resource Compiler to decide where in the VS_FIXEDFILEINFO structure to put the specified value. As you can see, certain values have definite meanings reserved by Microsoft, but there seems to be no reason why you cannot use your own values which may have a special meaning to your application. lang-charset is a quoted string containing (in numbers) a hex number which gives the language and character set used in the string-value statements which follow. The most common value found here is "040904E4" meaning US English + Windows, multilingual character set. lang/char statements are two 16-bit numbers separated by a comma. The first represents a language and the second a character set supported by the application. If a lang/char statement is included in the VERSIONINFO resource, the system will initialise the "Version" property sheet found when looking at the "Properties" of the executable file, and will include a "Language" key. The most common value found is 0x409,1252 which is US English + Windows, multilingual character set, with the latter being given in its decimal value, but 4E4h would do just as well. string-value statements are a series of statements containing two quoted strings with the following syntax:- "name", "value" "name" is a string which would be given to the API VerQueryValue in order to retrieve the value. The following strings are looked for by the system when showing the "Version" property sheet:- "FileVersion", "FileDescription" and "LegalCopyright", and the value appears at the top of the property sheet adjacent to the words "File Version", "Description" and "Copyright" respectively. Other strings appear in listboxes in the property sheet. You can use whatever string you like, although if they are too long they are truncated in the property sheet and they always appear in alphabetical order. You often see one of the following strings being used:- "Comments" "CompanyName" "InternalName" "LegalTradmarks" "OriginalFilename" "PrivateBuild" "ProductName" "ProductVersion" "SpecialBuild" "value" is a user defined value in a quoted string which corresponds to one of the standard strings and will be returned by VerQueryValue.
Example of a VERSIONINFO resource
1  VERSIONINFO
FILEVERSION			2,0,0,0
PRODUCTVERSION	2,0,0,0
FILEFLAGSMASK	0x0000003FL
FILEFLAGS		0x0000000BL
FILEOS			0x00010001L
FILETYPE		0x00000001L
FILESUBTYPE	0x00000000L
BEGIN
	BLOCK "StringFileInfo"
	BEGIN
		BLOCK "040904E4"
		BEGIN
			VALUE "CompanyName", "MySoftware Company"
			VALUE "Contact e-mail", "MySoftware@ether.com"
			VALUE "FileDescription","MySoftware.Exe"
			VALUE "FileVersion", "3.45"
			VALUE "DevelopmentFile","Dev345.asm"
			VALUE "LegalCopyright","Copyright\251 2005 Co"
			VALUE "Resources made using","GoRC.Exe"
		END
	END
	BLOCK "VarFileInfo"
	BEGIN
		VALUE "Translation", 0x0409,1252
	END
END

Resources for the User-Interface

These types of resources make it easy to create accelerators, menus, and dialogs - three basic ingredients for the user interface. In each case it is possible to use the APIs instead of using the resource file, but this is normally much less convenient, and no advantage can be taken of the system being able automatically to discriminate between menus and dialogs of different languages.

In order to use these resources, in a single language application a specific API is called to obtain a handle to the resource.

The five resource types under this heading, the resource type numbers and the APIs used to use the resources are:-

ACCELERATORS	9	LoadAccelerators
MENU			4	LoadMenu
MENUEX			4	LoadMenu
DIALOG			5	CreateDialogParam, DialogBoxParam
DIALOGEX		5	CreateDialogParam, DialogBoxParam

The ACCELERATORS Resourcetop

The syntax for the ACCELERATORS resource is:-

nameID ACCELERATORS
[defining-statements]
BEGIN
	event, result [,type/options]
	.........
END

Where,

nameID				can be either:-
						a 16-bit number of value 1 to 7FFFh
						an expression which evaluates to that number
						a name

defining-statements		need not be present, but can be either:-
						a VERSION statement
						a CHARACTERISTICS statement
						a LANGUAGE statement

						see below for details

event				specifies the keystroke which will cause result to be sent to the
					message loop of the process which loaded the accelerators.
					It can be either:-
						a single character enclosed in quotes
							eg. "a" meaning the key "a"
						a single character preceded by a caret
							eg. "^A" meaning the key is a Crtl key
							if ^ is used the character must be an upper case letter
						a 16-bit number
						an expression which evaluates to a 16-bit number
							eg. the commonly used VK_ names listed in Winuser.h

result				can be either:-
						a 16-bit number
						an expression which evaluates to a 16-bit number

type/options			can be any of the following values, separated by commas:-
						ASCII		(value zero, meaning that the event value refers
									to an ASCII character value)
						VIRTKEY		(1= meaning that the event value refers
									to a virtual key value)
						(if neither ASCII nor VIRTKEY are specified, then ASCII is assumed)
						SHIFT		(4= event only occurs if Shft key is pressed)
						CONTROL	(8= event only occurs if Crtl key is pressed)
						ALT			(10h= event only occurs if Alt key is pressed)
						NOINVERT	(2= do not highlight a top level menu item if
									possible when an accelerator is used)
Example of ACCELERATORS resource
0x20 ACCELERATORS
BEGIN
	"N", 20h, CONTROL
	"^A", 0x1111
	"K", 0x2222
	"k", 0x3333, ALT
	98, 0x4444, ASCII
	66, 0x5555, ASCII
	"g", 0x6666
	"G", 0x7777
	"K", 0x2222, VIRTKEY
	67, 0x5556, VIRTKEY
	68, 0x5557, VIRTKEY, NOINVERT
	VK_F1, 0x8888, VIRTKEY
	VK_F2, 0x8889, CONTROL, VIRTKEY
	VK_F3, 0x888A, SHIFT, VIRTKEY
	VK_LBUTTON, 0x888B, ALT, VIRTKEY
	VK_NUMPAD4, 0x888C, ALT, SHIFT,VIRTKEY
	VK_SPACE, 0x888D, CONTROL, SHIFT,VIRTKEY
	VK_END, 0x888E, ALT, CONTROL,VIRTKEY
END

The MENU Resourcetop

The syntax for the MENU resource is:-

nameID MENU
[defining-statements]
BEGIN
	MENUITEM "text", id [,type/state]
	POPUP "text" [,type/state]
	BEGIN
		MENUITEM "text", id [,type/state]
	END
	MENUITEM SEPARATOR
	.........
END

The syntax for the MENUEX resource is:-

nameID MENUEX [,helpID]
[defining-statements]
BEGIN
	MENUITEM "text", id [,type/state]
	POPUP "text", [id] [,type/state][,helpID]
	BEGIN
		MENUITEM "text", id [,type/state]
	END
	MENUITEM SEPARATOR
END

Where,

nameID				can be either:-
						a 16-bit number of value 1 to 7FFFh
						an expression which evaluates to that number
						a name

defining-statements		need not be present, but can be either:-
						a VERSION statement
						a CHARACTERISTICS statement
						a LANGUAGE statement

						see below for details

"text"				is a quoted string containing the text for the menu or popup item,
					which can also contain:-
						\t	which inserts a tab
						\a	which aligns to the right all text which follows it
						&	the system uses the following character as an accelerator key
						&&	use two ampersands to write &
					You can have a menu item without any text by having "" in this field,
					but this simply gives the same result as having a SEPARATOR.
					If you want a completely empty menu line use " " instead, giving the
					menu item a string which contains only a space.

id					is the value which is sent to the window procedure of the window
					which owns the menu. It can be:-
						a 16-bit number (MENU) or a 32-bit number (MENUEX)
						an expression which evaluates to the above number

type/state				is one or more of the following words separated by spaces or
					the | (OR) operator:-

			type
					MENUBREAK			40h
							puts the next menu item on a new line or in a new column
							in the case of popup menus
					MENUBARBREAK		20h
							same as above but includes a separator line
					OWNERDRAW		100h
							process is responsible for drawing the menu
					RADIOCHECK		200h
							radio button used instead of check-mark for checked items
					RIGHTJUSTIFY		4000h
							right justifies menu text only, not popups
					HELP				4000h
							identifies a help item
					SEPARATOR			800h
							for popups only
			state
					CHECKED			8h
						checks the menu item
					GRAYED				3h
							disables and greys the menu item
					DISABLED			3h
							same as above
					INACTIVE			2h
							menu item not greyed but cannot be selected
					HILITE				80h
							highlights the menu item
					DEFAULT			1000h
							displays text in bold and the enter key will act in the same way
							as a mouse click on this item

					Instead of using the type/state words, you can use their respective value
					instead, but ensure that they are inserted as follows:-
						type,state
					or	type+type,state+state
					(type values are first, then comma, then state values)

helpID				(MENUEX only) is the value sent to the window procedure of the window
					which owns the menu if F1 is pressed when the menu is active. It can be:-
						a 32-bit number
						an expression which evaluates to a 32-bit number

					important - in the POPUP statement, to ensure that the helpID is
					properly identified, make sure there are a total of 3 commas between
					id and helpID. This tells the Resource Compiler that helpID is not
					a type nor a style value.

MENUITEM SEPARATOR	creates a horizontal line in the menu which is useful for
						separating different types of menu items
Example of MENU resource
#define IDM_NEW 10h
#define IDM_OPEN 20h
GENERIC MENU
BEGIN
	POPUP "&File"
	BEGIN
		MENUITEM "&New...", IDM_NEW, GRAYED
		MENUITEM "&Open...", IDM_OPEN, GRAYED
		MENUITEM SEPARATOR
		POPUP "Send to"
		BEGIN
			MENUITEM "Drive a:"
		END
	END
	POPUP "View"
	BEGIN
		MENUITEM "Toolbar\tCrtl+T", 33h, CHECKED | HILITE
	END
END
Example of MENUEX resource
#define IDM_NEW 10h
#define IDM_OPEN 20h
GENERIC MENUEX 99999999h
BEGIN
	POPUP "nice day", 0x100, CHECKED,,6666666h
	BEGIN
		MENUITEM "&New...", IDM_NEW, MENUBREAK | GRAYED
		MENUITEM "&Open...", IDM_OPEN, GRAYED
		MENUITEM SEPARATOR
		POPUP "Send to"
		BEGIN
			MENUITEM "Drive a:"
		END
	END
	POPUP "View"
	BEGIN
		MENUITEM "Toolbar", 33h, CHECKED | HILITE
	END
END

The DIALOG Resourcetop

The syntax for the DIALOG resource is:-

nameID DIALOG x, y, width, height
[defining-statements]
[dialog-statements]
BEGIN
	iconcontrol
	textcontrol
	non-textcontrol
	generic-control
END

The syntax for the DIALOGEX resource is:-

nameID DIALOGEX x, y, width, height [,helpID]
[defining-statements]
[dialog-statements]
BEGIN
	iconcontrol
	textcontrol [,helpID]
	non-textcontrol [,helpID]
	generic-control [,helpID]
END

Where,

nameID				can be either:-
						a 16-bit number of value 1 to 7FFFh
						an expression which evaluates to that number
						a name

x					is the horizontal position of the dialog in dialog units

y					is the vertical position of the dialog in dialog units

width				is the width of the dialog in dialog units

height				is the height of the dialog in dialog units

helpID				(DIALOGEX only) is the value which is sent to the dialog procedure
					if F1 is pressed when the dialog is active. A helpID specified for a
					control is sent if the user clicks the control after having dragged the
					help question mark. The helpID can be either:-
						a 32-bit number
						an expression which evaluates to a 32-bit number

defining-statements		need not be present, but can be either:-
						a VERSION statement
						a CHARACTERISTICS statement
						a LANGUAGE statement

						see below for details

dialog-statements		need not be present, but can be one or more of the following:-
CAPTION "text"		where "text" is the title of the dialog to insert in the title bar

CLASS class			this statement is used if you have registered your own private window
					class for the dialog because you want to intercept dialog messages
					before they go to the systems default dialog window procedure.

					class can be either:-
						a 16-bit number
						a quoted string

EXSTYLE exstyle		allows an extended style to be specified, which can be one or
					more of the following extended styles or their respective value
					separated by the | (OR) operator:-

		WS_EX_DLGMODALFRAME		1h
				has a double border
		WS_EX_NOPARENTNOTIFY		4h
				when window is created or destroyed, does not send the
				WM_PARENTNOTIFY message to the parent window 
		WS_EX_TOPMOST			8h
				place above all non-topmost windows and stay above them
		WS_EX_ACCEPTFILES			10h
				accept drag-drop files
		WS_EX_TRANSPARENT		20h
				sibling window(s) beneath the window get painted first
		WS_EX_MDICHILD			40h
				a MDI child window
		WS_EX_TOOLWINDOW		80h
				for use as a floating toolbar
		WS_EX_WINDOWEDGE		100h
				border has a raised edge
		WS_EX_CLIENTEDGE			200h
				border has a sunken edge
		WS_EX_OVERLAPPEDWINDOW	300h	which is the same as
				WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE
		WS_EX_PALETTEWINDOW		188h	which is the same as
				WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST
		WS_EX_CONTEXTHELP		400h
				title bar include a question mark for use with
				WM_HELP message processing to display help
		WS_EX_LEFT					0h
				default left-aligned properties
		WS_EX_RIGHT				1000h
				right-align properties for shell languages supporting
				reading-order alignment
		WS_EX_LTRREADING			0h
				default left-to-right reading-order properties
		WS_EX_RTLREADING			2000h
				right-to-left reading-order properties for shell
				languages supporting reading-order alignment
		WS_EX_RIGHTSCROLLBAR		0h
				default position to the right of the client area
		WS_EX_LEFTSCROLLBAR		4000h
				positioned to the left of the client area for shell
				languages supporting reading-order alignment
		WS_EX_CONTROLPARENT		10000h
				child windows are included in dialog box navigation
		WS_EX_STATICEDGE			20000h
				border has a three-dimensional style
		WS_EX_APPWINDOW			40000h
				top-level window when visible shows on taskbar
		WS_EX_LAYERED				80000h
				a layered window generally with a complex/animated
				shape or alpha blending
		WS_EX_NOINHERITLAYOUT	100000h
				window layout does not get passed to child windows
		WS_EX_LAYOUTRTL			400000h
				horizontal origin on right edge of window for shell
				languages supporting reading-order alignment
		WS_EX_COMPOSITED			2000000h
				descendants of the window get painted in bottom-to-top
				order using double-buffering
		WS_EX_NOACTIVATE			8000000h
				if a top-level window, does not become the foreground
				window or show on the taskbar

FONT pointsize, "typeface"							;if DIALOG
FONT pointsize, "typeface" [,weight, italic, charset]		;if DIALOGEX
					this statement must be present if the dialog has the DS_SETFONT
					style and it contains the information which the system uses to write the
					text within the dialog box and its controls. If this statement is present
					the dialog box is given the style DS_SETFONT automatically.

			pointsize		is a 16-bit number giving the size of the font

			typeface		is a quoted string giving the name of the typeface

			weight		(DIALOGEX only) is either:-
							a 16-bit number
							an expression which evaluates to a 16-bit number
							one of the words known to the Resource Compiler set
							out below (the weight is given in the second column):-
								FW_DONTCARE	0
								FW_THIN		100
								FW_EXTRALIGHT	200
								FW_LIGHT		300
								FW_NORMAL		400
								FW_MEDIUM		500
								FW_SEMIBOLD	600
								FW_BOLD		700
								FW_EXTRABOLD	800
								FW_HEAVY		900

						if this parameter is omitted it is set to zero (dont care)

			italic			(DIALOGEX only) indicates whether italics should be used and
						is either:-
							the number 0 or the word FALSE to indicate not italic, or
							the number 1 or the word TRUE to indicate italic

						if this parameter is omitted it is set to zero (non-italic)

			charset		(DIALOGEX only) indicates the character set for the dialog and
						is either:-
							an 8-bit number
							an expression which evaluates to an 8-bit number
							one of the words known to the Resource Compiler set
							out below (the value is given in the second column):-
								ANSI_CHARSET			0
								DEFAULT_CHARSET		1
								SYMBOL_CHARSET		2
								SHIFTJIS_CHARSET		128
								HANGEUL_CHARSET		129
								HANGUL_CHARSET		129
								GB2312_CHARSET		134
								CHINESEBIG5_CHARSET	136
								OEM_CHARSET			255
								JOHAB_CHARSET			130
								HEBREW_CHARSET		177
								ARABIC_CHARSET		178
								GREEK_CHARSET			161
								TURKISH_CHARSET		162
								VIETNAMESE_CHARSET	163
								THAI_CHARSET			222
								EASTEUROPE_CHARSET	238
								RUSSIAN_CHARSET		204
								MAC_CHARSET			77
								BALTIC_CHARSET			186

						if this parameter is omitted it is set to zero (dont care)

MENU menuname this statement if present specifies a menu for the dialog box and menuname is either:- a 16-bit number identifying the menu (this would be the number given as the nameID of the menu resource) an expression which evaluates to that number (or the name of a menu resource if the nameID of the menu was a name) STYLE styles this statement is used to change the default dialog box style which is:- WS_POPUP | WS_BORDER | WS_SYSMENU, which is the same as 80000000h | 800000h | 80000h To remove an unwanted default style you can use the word NOT or the ! symbol. For example STYLE NOT SYSMENU or STYLE !80000h would produce a dialog box with the style of WS_POPUP and WS_BORDER only. The following dialog styles and their respective values can be used in this statement:- DS_ABSALIGN 1h the co-ordinates of the dialog box are screen co-ordinates as opposed to client co-ordinates DS_SYSMODAL 2h gives the dialog box the WS_EX_TOPMOST style DS_FIXEDSYS 8h use the systems fixed font rather than the proportional font DS_NOFAILCREATE 10h make the dialog box even if there are errors in making the controls DS_SETFONT 40h looks for the FONT statement for the font to be used for the controls and for text in the dialog box DS_MODALFRAME 80h creates a dialog box with a modal dialog frame which can be combined with WS_CAPTION and WS_SYSMENU styles DS_NOIDLEMSG 100h suppresses WM_ENTERIDLE messages that the system would otherwise send to the owner of the dialog box DS_SETFOREGROUND 200h system to call SetForegroundWindow when the dialog is created DS_CONTROL 400h make the dialog box work like the child window of another dialog box DS_CENTER 800h centre the dialog box as far as possible on the screen DS_CENTERMOUSE 1000h centre the mouse cursor in the dialog box DS_CONTEXTHELP 2000h add a question mark to the title bar for help processing The following window styles and their respective values can also be used in this statement:- WS_TILED same as WS_OVERLAPPED 0h an overlapped window with a title bar and border WS_MAXIMIZEBOX 10000h has a maximizebox in the title bar WS_MINIMIZEBOX 20000h has a minimizebox in the title bar WS_THICKFRAME same as WS_SIZEBOX 40000h has a thick frame border for resizing WS_SYSMENU 80000h has a system menu in its title bar WS_HSCROLL 100000h has a horizontal scroll bar WS_VSCROLL 200000h has a vertical scroll bar WS_DLGFRAME 400000h creates a modal dialog box type of frame for the window which cannot have a title bar WS_BORDER 800000h has a thin-line border WS_CAPTION 0C00000h which is the same as WS_BORDER | WS_DLGFRAME and has a title bar WS_TILEDWINDOW same as WS_OVERLAPPEDWINDOW 0C80000h which is the same as WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | \ WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX an overlapped window combined with other styles WS_MAXIMIZE 1000000h created initially maximized WS_CLIPCHILDREN 2000000h a parent window can use this to exclude child window areas when drawing within the parent window WS_CLIPSIBLINGS 4000000h clips overlappping child windows out of the update region for the WM_PAINT message WS_DISABLED 8000000h initially created as disabled WS_VISIBLE 10000000h initially created as minimized WS_MINIMIZE 20000000h initially created as minimized WS_CHILD 40000000h a child window which cannot have a menu bar, and cannot be used with the WS_POPUP style WS_POPUP 80000000h a pop-up window which cannot be used with the WS_CHILD style WS_POPUPWINDOW 80880000h which is the same as WS_POPUP | WS_BORDER | WS_SYSMENU a pop-up window, used with WS_CAPTION to make the window menu visible

iconcontrol displays an icon in the dialog box. The syntax for an iconcontrol is:- ICON nameID, id, x, y Where, nameID is the identifier of an ICON resource and is either:- a 16-bit number of value 1 to 7FFFh an expression which evaluates to that number a quoted string containing the name of the ICON if the icon is identified by name id can be either:- a 16-bit number (DIALOG) or a 32-bit number (DIALOGEX) an expression which evaluates to the above number x is the horizontal position of the icon y is the vertical position of the icon textcontrol is a dialog control which contains text and which has a name which is recognised by the Resource Compiler. The name of the type of control causes the Resource Compiler to give the control the correct class and a default style. To remove a default style you will need to use the NOT specifier, as you would to remove a default style for the dialog itself. The syntax for a textcontrol is:- textcontrol "text", id, x, y, width, height, [,style[,extendedstyle]] BEGIN data-elements END Where, textcontrol is one of the names given below, listed here with their class and default style:- LTEXT static class, SS_LEFT | WS_GROUP creates a static control with left aligned text CTEXT static class, SS_CENTER | WS_GROUP creates a static control with centred text RTEXT static class, SS_RIGHT | WS_GROUP creates a static control with right-aligned text GROUPBOX button class, BS_GROUPBOX creates a labelled rectangle in the dialog box inside which other controls can be grouped CHECKBOX button class, BS_CHECKBOX | WS_TABSTOP creates a check box control (small rectangle with text next to it) AUTOCHECKBOX button class, BS_AUTOCHECKBOX | WS_TABSTOP creates a check box control which automatically changes to checked or unchecked when the user clicks in the control STATE3 button class, BS_3STATE | WS_TABSTOP creates a check box control which has 3 states checked, unchecked, and disabled (greyed) AUTO3STATE button class, BS_AUTO3STATE | WS_TABSTOP creates a STATE3 control which automatically toggles when clicked between the 3 states RADIOBUTTON button class, BS_RADIOBUTTON | WS_TABSTOP creates a radio button control AUTORADIOBUTTON button class, BS_AUTORADIOBUTTON | WS_TABSTOP creates an automatic radio button PUSHBUTTON button class, BS_PUSHBUTTON | WS_TABSTOP creates an ordinary push button control containing text DEFPUSHBUTTON button class, BS_DEFPUSHBUTTON | WS_TABSTOP creates an ordinary push button control containing text and showing as the default if the user presses enter PUSHBOX button class, BS_USERBUTTON | BS_CHECKBOX | WS_TABSTOP giving a flat appearance to the button "text" is the text to appear in the control id can be either:- a 16-bit number (DIALOG) or a 32-bit number (DIALOGEX) an expression which evaluates to the above number x is the horizontal position of the control in dialog units y is the vertical position of the control in dialog units width is the width of the control in dialog units height is the height of the control in dialog units style see above for details extendedstyle see above for details data-elements are one or more elements of data, called "creation data". A pointer to this data is sent to the dialog procedure in the lParam parameter of the WM_CREATE message when the control is created. The data is made using the same format as for the RCDATA resource. non-textcontrol is similar to a textcontrol except that it does not contain text in the first instance (this must be added at run-time). The syntax for a non-textcontrol is:- non-textcontrol id, x, y, width, height, [,style[,extendedstyle]] BEGIN data-elements END Where the id, x, y, width, height, style and extendstyle parameters are the same as for the text-control. non-textcontrol is one of the names given below, listed here with their class and default style:- EDITTEXT edit class, ES_LEFT | WS_BORDER | WS_TABSTOP creates a simple edit control HEDIT handwriting edit (pen) control IEDIT ink edit (pen) control LISTBOX listbox class, LBS_NOTIFY | WS_BORDER creates a basic listbox SCROLLBAR scrollbar class, SBS_HORZ creates a basic scrollbar COMBOBOX combobox class, CBS_SIMPLE creates a basic combobox control generic-control is a control where you explicitly specify the class of the control. It is mainly used for those control classes which do not come into the button, edit, static, listbox, scrollbar, or combobox classes. However, you can use the generic-control syntax to make those controls too. The syntax for a generic-control is as follows:- CONTROL "text", id, class, style, x, y, width, height [,style,[extendedstyle]] BEGIN data-elements END Where the id, x, y, width, height, style and extendstyle parameters are the same as for the text-control. Note that here there are no default styles, other than WS_CHILD and WS_VISIBLE, so style and extendedstyle should be chosen to suit the particular control being made. "text" can be either:- a quoted string containing the text for the control or "" if it has no text in the case of a STATIC class control which has the SS_BITMAP style, "text" can be a 16-bit number representing the bitmap concerned an expression which evaluates to the above text or number For the controls which do not normally take initial text, (see non-textcontrols above) you must include an empty text string by specifying "", for the text parameter. class can be either:- a 16-bit number of value 80h to 85h (if one of the first six in the list below) an expression which evaluates to the above number a quoted string containing the name of the class shown in the second column of the list below a word shown in the first column of the list below a quoted string (for a user-defined class) The class can therefore be one of the following:- BUTTON "Button" 80h EDIT "Edit" 81h STATIC "Static" 82h LISTBOX "Listbox" 83h SCROLLBAR "Scrollbar" 84h COMBOBOX "ComboBox" 85h WC_HEADER "SysHeader32" WC_LISTVIEW "SysListView32" WC_TREEVIEW "SysTreeView32" HOTKEY_CLASS "msctls_hotkey32" UPDOWN_CLASS "msctls_updown32" ANIMATE_CLASS "SysAnimate32" WC_COMBOBOXEX "ComboBoxEx32" WC_TABCONTROL "SysTabControl32" MONTHCAL_CLASS "SysMonthCal32" PROGRESS_CLASS "msctls_progress32" REBARCLASSNAME "ReBarWindow32" TOOLTIPS_CLASS "tooltips_class32" TRACKBAR_CLASS "msctls_trackbar32" STATUSCLASSNAME "msctls_statusbar32" TOOLBARCLASSNAME "ToolbarWindow32" DATETIMEPICK_CLASS "SysDateTimePick32" WC_IPADDRESS "SysIPAddress32" WC_PAGESCROLLER "SysPager" WC_NATIVEFONTCTL "NativeFontCtl" DRAGLISTMSGSTRING "commctrl_DragListMsg"
Example of a DIALOG resource
AboutBox DIALOG 100, 100, 160, 72
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
FONT 8,"MS Sans Serif"
CAPTION "About it"
BEGIN
	CTEXT "Application", -1, 0, 8, 160, 8
	CTEXT "Version 1.2", -1, 0, 16, 160, 8
	DEFPUSHBUTTON "OK", IDOK, 55,52,50,14
	CONTROL 23h,-1,"Static",SS_BITMAP,9,6,125,41
	ICON "MyIcon" -1, 20, 10,0,0
END
Example of a DIALOGEX resource
0x45 DIALOGEX 0x30, 0x20, 0x200, 0x400, 0x98
CAPTION "goodbye"
MENU mymenu
FONT 10,"Times New Roman",FW_NORMAL,1
BEGIN
	CTEXT "hello", 0x20,0x10,0x10,0x10,0x10,,WS_EX_PALETTEWINDOW, 0x333
	COMBOBOX 0x456,30005,4560,300,20
	BEGIN
		0x888888L
		L"hello folks"
		0x99,0x67,0x5555
	END
	CONTROL "ducks",0x460,"ComboBoxEx32",0x100,30005,4560,300,20
	CONTROL "drakes",0x461,0x85,0x100,30005,4560,300,20
	CONTROL "hens",0x462,"Button",0x100,30005,4560,300,20
	CONTROL "and",0x463,"Own class",0x100,30005,4560,300,20
	CONTROL "chickens",0x464,STATUSCLASSNAME,0x100,30005,4560,300,20
	ICON "ANI_ICON",0x465, 6, 9, 18, 20
END

Defining Statements

Defining statements give some further definition to each resource. There are three types of defining-statement:-

Each defining statement is specific to the resource to which it refers, however if LANGUAGE is specified outside a specific resource it will apply to all resources thereafter.

VERSION and CHARACTERISTICStop

The syntax for these is the same:-

VERSION value
CHARACTERISTICS value

Where,

value		can be either:-
				a 32-bit number
				an expression which evaluates to a 32-bit number

The value is stored only in the RES file and not in the OBJ file nor in the EXE, so it cannot be recovered at run-time. However it could be read by tools which work with the RES file, such as some linkers.

LANGUAGEtop

The syntax of the LANGUAGE statement is:-

LANGUAGE language, sublanguage

This statement can appear anywhere in the script (outside a BEGIN...END section). In that case the specified language applies to all resources thereafter. It can also appear between the resource statement itself and the BEGIN...END section as a defining-statement. In that case the specified language only applies to the resource in which it appears.

The actual values for language and sublanguage appear in WINNT.H. The most common values for language are LANG_ENGLISH (value 9h), and for sublanguage are SUBLANG_ENGLISH_US (value 1h), SUBLANG_ENGLISH_UK (value 2h), SUBLANG_ENGLISH_AUS (value 3h) and SUBLANG_ENGLISH_CAN (value 4h). If no language is specified in your resource script the Resource Compiler uses the system language and inserts that in the binary resource file.

Making different language versions of a resource

If your product is to be used in more than one language, you will need to provide different menu and dialog text, warning and error messages to suit the language. The combined features of the Resource Compiler and the API make it reasonably easy to achieve this. The exact way this is achieved, in the context of resources, depends on whether you want:-

The first can be achieved by having different resource scripts, or by use of the conditional directives, which would instruct the Resource Compiler to compile only those parts of the resource script relevant to the desired language (see conditional directives above).

The second is possible because the API FindResource will automatically return the handle of the resource which suits the default system language for the computer which is running the program. FindResource does this by obtaining the default system language and then calling FindResourceEx. If you want to specify the language of the resource to be found, rather than relying on the system default language, then you can call FindResourceEx directly giving the language ID.

FindResource can be used as follows:-

PUSH resource type		;by type number or by name if a user-defined resource
PUSH resource nameID		;use only a name identifier not a number
PUSH hModule 			;this is hInst or zero to use current process
CALL FindResource

FindResourceEx can be used as follows

PUSH resource language	;see below
PUSH resource nameID		;use only a name identifier not a number
PUSH resource type		;by type number or by name if a user-defined resource
PUSH hModule			;this is hInst or zero to use current process
CALL FindResourceEx

Note that the nameID and type parameters are reversed for FindResourceEx!
The resource language is a 32-bit value made up as follows:-
Least significant 10 bits - the primary language value:
Next 6 bits - the secondary language value
Most significant 16 bits - zero
For a list of the language values see WINNT.h

The return from FindResource and FindResourceEx is the handle which is needed for the call to LoadResource. You can have several versions of a menu or dialog, for example, with the same nameID but with different languages specified. FindResource will return the handle of the correct one.

Language specific menus

Since the FindResource (or FindResourceEx) and LoadResource combination provide an address to the resource data itself, in order to load a language specific menu, you need to pass that address as the menu template to LoadMenuIndirect. You cannot use LoadMenu to load a language specific menu.

Language specific dialogs

Similarly, to make a language specific dialog box you need to pass the address of the dialog template returned by LoadResource to DialogBoxIndirect (modal) or CreateDialogIndirect (non-modal) rather than using the CreateDialog and DialogBox APIs. Other language specific components which are needed in your dialog should either be given a unique nameID or loaded at run-time. For example, if you have a French version of your dialog and want to include a French menu by using the MENU defining-statement in the resource script, a nameID must be given in the MENU statement which uniquely refers to the French menu. Alternatively if you have several language versions of the menu all with the same nameID you could load the menu at run-time upon the INIT_DIALOG message. This would be done by calling FindResource or FindResourceEx, then LoadResource (to get and address for the menu template of the correct menu), LoadMenuIndirect (to get the menu handle) and then SetMenu (to load the menu into the dialog box).

Language specific strings and raw data

When loading language specific strings, you can use LoadString directly. This loads a string to suit the system default language. Alternatively the address of the string itself can be obtained using FindResource, or FindResourceEx and LoadResource. The same method works for RCDATA and for a user-defined resource (and indeed for any resource which can be used by obtaining an address of the raw data of the resource).

Examples for viewing

Testbug.Exe provides examples of loading language specific menus, dialogs, strings and raw data. The relevant functions to look at with the debugger are:-

Menus, dialogs and raw data example, click "use of resources/different language versions/various resources in English" or "same showing French versions" in the menu, watching with the debugger the functions RESOURCES_IN_ENGLISH and RESOURCES_IN_FRENCH, which create dialog boxes using the dlg wndproc called MDLangDlgProc.

Strings, click "Language specific string" in the menu, watching with the debugger the function STRINGTABLES_BY_LANGUAGE.

Language search criteria

When searching for language specific resources, the system looks for a language match but has certain defaults if an exact match is not found. The system carries out the search for a resource of the correct type and ID in this order, moving down the list if the resource is not yet found:-

Clearly if the exact specified language is not present in the EXE, FindResourceEx will provide some output provided the resource type and ID match. So there is no need to worry that your product will not work in the Land of the Wizard if you use language specific resources.

Own language values

You can specify your own language values if you wish, and by this method it would be possible to make several versions of menus, dialogs and strings for your product in the same language if you wished, using the automatic language selection referred to above. To keep the system happy, ensure that your language value is between 200h and 3FFh, and the sublanguage value is between 20h and 3Fh. These values are carefully chosen. The actual languageID inserted in the binary resource file and kept in the EXE is only 16 bits long, the language value occupying the most significant 10 bits (hence a maximum value of 3FFh) and the sublanguage value occupying the least significant 6 bits (hence a maximum value of 3Fh).

Examples of the LANGUAGE statement
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
456h RCDATA
BEGIN
	"Hello world (in English)\0"
END

456h RCDATA
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
BEGIN
	"Bonjour le monde (en Français)\0"
END

STRINGTABLE
BEGIN
	55h "An English string"
END

LangMenu MENU
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
BEGIN
	MENUITEM "English menu item" 22h
END

LangMenu MENU
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
BEGIN
	MENUITEM "Version française" 22h
END

Capitalisation of nameIDs and typestop

We have seen that a resource nameID can either be a string of characters or a number. For each type of resource with a particular language the nameID must be unique. Ie. two dialogs can have the same nameID provided they have different language values. We have also seen that a user-defined resource will have a resource type identified by a string of characters or a number.

Now, the Resource Compiler will always convert the nameID or type to upper case when inserting them in the RES file or OBJ file. The reason for this is that this is expected by Windows. In practice this does not affect the way you use the resource because the system will also capitalise any nameIDs or types given to the resource APIs. For example suppose you have a dialog with a nameID of "MyDlg". Then to use the dialog you would pass the string "MyDlg" to the API CreateDialog. But in fact, the system converts the string to MYDLG and then looks for that string (as converted) in the executable.

This has two implications which you may need to be aware of.

Firstly it means that there would be a conflict in the above example if you had a second dialog (with the same language value) called MYDLG. This would be picked up at link-time by the linker.

Secondly, the Resource Compiler must ensure that not only English nameIDs or user-defined types are converted properly to upper case. So the Resource Compiler relies on the API CharUpper to do this conversion. This API can handle a number of languages properly, but it does rely on language mapping. Ensure that the machine used for compiling does support the language used in the nameIDs and user-defined types. Many languages do not actually have an upper case at all, in which case no conversion will take place.

Legal Stufftop

Copyright

GoRC is Copyright © Jeremy Gordon 1997-2013 [MrDuck Software] - all rights reserved.

GoRC - licence and distribution

You may use GoRC for any purpose including making commercial programs. You may redistribute it freely (but not for payment nor for use with a program or any material for which the user is asked to pay). You are not entitled to hide or deny my copyright.

Disclaimer

I have made every effort to ensure that GoRC's output is accurate, but you do use it entirely at your own risk. I cannot accept any liability for it failing to work properly or giving the wrong output nor for any errors in this manual.