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

Introductiontoptop

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 Compilertoptop

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.

Directivestoptop

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)

GoRC 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 Symbolstoptop

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

Numberstoptop

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

Arithmetictoptop

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 Manipulationtoptop

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 Settoptop

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!"#$%&'()*+,-./
40414243444546475051525354555657
0123456789:;<=>?
60616263646566677071727374757677
@ABCDEFGHIJKLMNO
100101102103104105106107110111112113114115116117
PQRSTUVWXYZ[\]^_
120121122123124125126127130131132133134135136137
`abcdefghijklmno
140141142143144145146147150151152153154155156157
pqrstuvwxyz{|}~
160161162163164165166167170171172173174175176177
ƒˆŠŒŽ
200201202203204205206207210211212213214215216217
˜šœžŸ
220221222223224225226227230231232233234235236237
 ¡¢£¤¥¦§ ¨©ª«¬­®¯
240241242243244245246247250251252253254255256257
°±²³´µ· ¸¹º»¼½¾¿
260261262263264265266267270271272273274275276277
ÀÁÂÃÄÅÆÇ ÈÉÊËÌÍÎÏ
300301302303304305306307310311312313314315316317
ÐÑÒÓÔÕÖ× ØÙÚÛÜÝÞß
320321322323324325326327330331332333334335336337
àáâãäåæç èéêëìíîï
340341342343344345346347350351352353354355356357
ðñòóôõö÷ øùúûüýþÿ
360361362363364365366367370371372373374375376377

The Windows Character Set and hex values
Space!"#$%&'()*+,-./
202122232425262728292A2B2C2D2E2F
0123456789:;<=>?
303132333435363738393A3B3C3D3E3F
@ABCDEFGHIJKLMNO
404142434445464748494A4B4C4D4E4F
PQRSTUVWXYZ[\]^_
505152535455565758595A5B5C5D5E5F
`abcdefghijklmno
606162636465666768696A6B6C6D6E6F
pqrstuvwxyz{|}~
707172737475767778797A7B7C7D7E7F
ƒˆŠŒŽ
808182838485868788898A8B8C8D8E8F
˜šœžŸ
909192939495969798999A9B9C9D9E9F
 ¡¢£¤¥¦§ ¨©ª«¬­®¯
A0A1A2A3A4A5A6A7A8A9AAABACADAEAF
°±²³´µ· ¸¹º»¼½¾¿
B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
ÀÁÂÃÄÅÆÇ ÈÉÊËÌÍÎÏ
C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF
ÐÑÒÓÔÕÖ× ØÙÚÛÜÝÞß
D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF
àáâãäåæç èéêëìíîï
E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
ðñòóôõö÷ øùúûüýþÿ
F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF

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 filetoptop

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 Resourcetoptop

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 Resourcetoptop

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= it's an application)
		VFT_DLL			(2= it's a DLL)
		VFT_DRV			(3= it's a device driver)
		VFT_FONT			(4= it's a font)
		VFT_VXD			(5= it's a virtual device)
		VFT_STATIC_LIB		(7= it's 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= it's a printer driver)
		VFT2_KEYBOARD		(2= it's a keyboard driver)
		VFT2_LANGUAGE		(3= it's a language driver)
		VFT2_DISPLAY		(4= it's a display driver)
		VFT2_MOUSE		(5= it's a mouse driver)
		VFT2_NETWORK		(6= it's a network driver)
		VFT2_SYSTEM		(7= it's a system driver)
		VFT2_DRV_INSTALLABLE	(8= it's an installable driver)
		VFT2_DRV_SOUND	(9= it's a sound driver)
		VFT2_DRV_COMM	(0Ah= it's 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", "2.0.0.0"
			VALUE "DevelopmentFile","Dev2000.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 Resourcetoptop

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 Resourcetoptop

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 Resourcetoptop

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 system's 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 (don't 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 (don't 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 system's 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 CHARACTERISTICStoptop

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.

LANGUAGEtoptop

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 typestoptop

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. I.e. 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:

  1. 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.
  2. 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 Stufftoptop

Copyright

GoRC is Copyright © Jeremy Gordon 1997-2022 [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.