|
|
1.1 ! root 1: This document describes how messages will be input, stored and formatted ! 2: by a Win32 application. ! 3: ! 4: 1. Message Input ! 5: ! 6: Messages are input as ASCII text in a text file. The format of this ! 7: file supports specifying multiple versions of the same message text, ! 8: one for each language supported. It also supports automatic assignment ! 9: of code numbers to each message, along with the generation of a C ! 10: language include file for use by the application for accessing the ! 11: messages using symbolic constants. The purpose of the message text ! 12: file is to define all of the messages needed by an application, in a ! 13: format that makes it easy to support multiple languages with the same ! 14: image file. ! 15: ! 16: Message text files are converted into binary resource files by the ! 17: MC program. These binary resource files are then input to the RC ! 18: compiler which will put them in the resource table for an ! 19: application or DLL. ! 20: ! 21: The format of the message text file (default extension is .mc). ! 22: Basic syntax is Keyword=Value, where spaces around the equal sign ! 23: are ignored, and the value is delimited by white space from the next ! 24: keyword=value pair. Case is ignored when comparing against keyword ! 25: names. The value portion can either be a numeric integer constant, ! 26: {NUMBER}, using C syntax; a symbol name, {NAME}, that follows the ! 27: rules for C identifier names; or a file name that follows the ! 28: rules for the FAT file system (8 characters or less, no periods). ! 29: ! 30: Comment lines are allowed in the message text file. The comment ! 31: syntax is the same as for WIN.INI, namely a semicolon begins a ! 32: comment which is terminated by the end of the line. Comments that ! 33: exist by themselves on a line are copied as is to the output .h ! 34: file, with the semicolon converted to the C end of line comment ! 35: syntax (//). ! 36: ! 37: The overall structure of a message text file consists of a header ! 38: section which contains zero or more of the following keywords: ! 39: ! 40: MessageIdTypedef={NAME} ! 41: SeverityNames=({NAME}={NUMBER}:{NAME}) ! 42: FacilityNames=({NAME}={NUMBER}:{NAME}) ! 43: LanguageNames=({NAME}={NUMBER}:{FILENAME}) ! 44: ! 45: These keywords have the following meaning: ! 46: ! 47: MessageIdTypedef - gives a symbolic name that is output as the ! 48: typedef name for each numeric MessageId value. The default ! 49: value for this is NULL, which means there will be no type ! 50: cast output when defining symbolic names for a MessageId. ! 51: ! 52: SeverityNames - defines the set of names that are allowed as the ! 53: value of the Severity keyword in the message definition. ! 54: The set is delimited by left and right parenthesis. ! 55: Associated with each severity name is a number that, when ! 56: shifted left by 30, gives the bit pattern to logically OR ! 57: with the Facility value and MessageId to come up with the ! 58: full 32-bit message code. The default value of this keyword ! 59: is: ! 60: ! 61: SeverityNames=(Success=0x0 ! 62: Informational=0x1 ! 63: Warning=0x2 ! 64: Error=0x3 ! 65: ) ! 66: ! 67: Severity values occupy the high two bits of a 32-bit message ! 68: code. Any severity value that does not fit in two bits is ! 69: an error. The severity codes can be given symbolic names ! 70: by following each value with :{NAME} ! 71: ! 72: FacilityNames - defines the set of names that are allowed as the ! 73: value of the Facility keyword in the message definition. ! 74: The set is delimited by left and right parenthesis. ! 75: Associated with each facility name is a number that, when ! 76: shift it left by 16 bits, gives the bit pattern to logically ! 77: OR with the Severity value and MessageId to come up with the ! 78: full 32-bit message code. The default value of this keyword ! 79: is: ! 80: ! 81: FacilityNames=(System=0x0FF ! 82: Application=0xFFF ! 83: ) ! 84: ! 85: ! 86: Facility codes occupy the low order 12 bits of the high ! 87: order 16-bits of a 32-bit message code. Any facility code ! 88: that does not fit in 12 bits is an error. This allows for ! 89: 4096 facility codes. The first 256 are reserved for ! 90: use by the system software. ! 91: ! 92: The facility codes can be given symbolic names by following ! 93: each value with :{NAME} ! 94: ! 95: LanguageNames - defines the set of names that are allowed as the ! 96: value of the Language keyword in the message definition. ! 97: The set is delimited by left and right parenthesis. ! 98: Associated with each language name is a number and a file ! 99: name that will be used to name the binary output file that ! 100: will contain all of the message text for that language. The ! 101: number corresponds to the Language Id tag to use in the ! 102: resource table. The number is separate from the file name ! 103: with a colon. The initial value of this keyword is: ! 104: ! 105: LanguageNames=(English=1:MSG00001) ! 106: ! 107: Any new names that an application defines in its .mc file ! 108: which don't override any of the builtin names will be added ! 109: to the list of valid languages. This allows an application ! 110: to support private languages with descriptive names. ! 111: ! 112: Following the header section are zero or more message definitions. ! 113: Each message definition begins with one or more of the following ! 114: keywords. ! 115: ! 116: MessageId={|{NUMBER}|+{NUMBER}} ! 117: Severity={SEVERITY_NAME} ! 118: Facility={FACILITY_NAME} ! 119: SymbolicName={NAME} ! 120: ! 121: The MessageId keyword is required to mark the beginning of the ! 122: message definition, although its value is optional. If no value is ! 123: specified, then the value used will be the last value used for the ! 124: facility, plus one. If the value is specified as +{NUMBER} then ! 125: the value used will be the last value used for the facility, plus ! 126: the number after the plus sign. Otherwise if a numeric value is ! 127: given, that will be value used. Any MessageId value that does not ! 128: fit in 16 bits is an error. ! 129: ! 130: Severity and Facility are optional keywords that can specify ! 131: additional bits to OR into the final 32-bit message code. If either ! 132: of these are not specified they default to the value last specified ! 133: for a message definition. The initial values of these prior to ! 134: processing the first message definition is: ! 135: ! 136: Severity=Success ! 137: Facility=Application ! 138: ! 139: The value associated with these keywords must match one of the names ! 140: given to the FacilityNames and SeverityNames keywords. The SymbolicName ! 141: keyword allows the ISV to associate a C symbolic constant name with the ! 142: final 32-bit message code that is a result of ORing together the ! 143: MessageId, Severity and Facility bits. The constant definition is ! 144: output to the generated .h file with the following format: ! 145: ! 146: // ! 147: // {MESSAGETEXT} ! 148: // ! 149: ! 150: #define CONSTANT_SYMBOL_NAME ((MessageIdTypedef) 0x12345678) ! 151: ! 152: where the comment before the definition is a copy of the message ! 153: text for the first language specified in the message definition. ! 154: The CONSTANT_SYMBOL_NAME is the value of the SymbolicName keyword. ! 155: The MessageIdTypedef is not output if it is NULL, the default value. ! 156: ! 157: After the message definition keywords, comes one or more message text ! 158: definitions. Each message text definition begins with the Language ! 159: keyword that identifies which binary output file this message text ! 160: is to be output to. Beginning on the very next line is the first ! 161: line of the message text. The message text is terminated by a line ! 162: containing a single period at the beginning of the line, immediately ! 163: followed by a new line. No spaces allowed around keyword. Within ! 164: the message text, blank lines and white space are preserved as part ! 165: of the message. ! 166: ! 167: Language={LANGUAGE_NAME} ! 168: {MESSAGETEXT} ! 169: . ! 170: ! 171: Within the message text, several escape sequences are supported for ! 172: dynamically formatting the message. The percent sign character (%) ! 173: begins all escape sequences. ! 174: ! 175: ! 176: %0 - This terminates a message text line without a trailing ! 177: newline. This can be used to build up long lines or to ! 178: terminate the message itself without a trailing newline, ! 179: which is useful for prompt messages. ! 180: ! 181: %n!printf format string! - This identifies an insert. The ! 182: value of n can be between 1 and 99. The printf format ! 183: string must be bracketed by exclamation marks. It is ! 184: optional and defaults to !s! if not specified. ! 185: ! 186: The printf format string can contain the * specifier for ! 187: either the precision or width components, and if so, they ! 188: will consume inserts %n+1 and %n+2 for their values at run ! 189: time. MC will print a warning message if an explicit ! 190: reference is made to these inserts elsewhere in the message ! 191: text. ! 192: ! 193: Inserts must reference a parameter passed to the FormatMessage API ! 194: call. It will return an error if a message refers to an insert that ! 195: was not passed to the FormatMessage API call. ! 196: ! 197: Any other character following a percent sign, other than a digit will ! 198: be formatted in the output message without the percent sign. Some ! 199: examples: ! 200: ! 201: %% - will output a single percent sign in the formatted message text. ! 202: ! 203: %n - will output a hard line break when it occurs at the end of a ! 204: a line. Useful when FormatMessage is supplying normal line ! 205: breaks so the message fits in a certain width. ! 206: ! 207: %r - will output a hard carriage return, without a trailing newline. ! 208: ! 209: %b - will output a space in the formatted message text. This ! 210: can be used to insure there are the appropriate number of ! 211: trailing spaces in a message text line. ! 212: ! 213: %t - will output a tab in the formatted message text. ! 214: ! 215: %. - will output a single period in the formatted message text. ! 216: This can be used to get a single period at the beginning of ! 217: a line without terminating the message text definition. ! 218: ! 219: %! - will output a single exclamation point in the formatted ! 220: message text. This can be used to get an exclamation point ! 221: immediately after an insert without it being mistaken for ! 222: the beginning of a printf format string. ! 223: ! 224: Unicode support is not understood yet. If the input file is ASCII ! 225: text, do we need an escape sequence to allow input of Unicode values? ! 226: Or do we just let them use DBCS in the text file, assuming they have ! 227: a text editor that can do this. ! 228: ! 229: 2. Message Compiler (MC) ! 230: ! 231: This program converts .mc message text files into binary files ! 232: suitable for inclusion into a .RC file by the resource compiler. ! 233: ! 234: Command line syntax: ! 235: ! 236: MC [-v] [-w] [-s] [-h DirSpec] [-r DirSpec] filename[.mc] ... ! 237: ! 238: where: ! 239: ! 240: -v - generates verbose output to stderr. ! 241: ! 242: -w - generates a warning message whenever an insert escape ! 243: sequence is seen that is a superset of the type supported ! 244: by OS/2 mkmsgf (i.e. anything other than %0 and %n). ! 245: Useful for converting old OS/2 message files to this ! 246: format. ! 247: ! 248: -s - Add an extra line to the beginning of each message that is ! 249: the symbolic name associated with the message id. ! 250: ! 251: -h DirSpec - specifies the target directory of the generated ! 252: .h file. The file name is the name of the .mc file with a ! 253: .h extension. ! 254: ! 255: -r DirSpec - specifies the target directory of the generated ! 256: .rc file. The file name is the name of the .mc file with a ! 257: .rc extension. ! 258: ! 259: filename.mc - specifes one or more input message files that ! 260: will be compiled into one or more binary resource ! 261: files, one for each language that the message ! 262: files contain message text for. ! 263: ! 264: The message compiler reads the .mc file and generates a .h file ! 265: containing all the symbolic name definitions. For each LanguageId ! 266: that was used to specify message text, it outputs a binary file ! 267: containing a message table resource. It also outputs a single .rc ! 268: file that contains the appropriate RC syntax to include each binary ! 269: file output as a resource with the appropriate name and type ids. ! 270: ! 271: 3. Message Win32 API Calls ! 272: ! 273: DWORD ! 274: APIENTRY ! 275: FormatMessage( ! 276: DWORD dwFlags, ! 277: LPVOID lpSource, ! 278: DWORD dwMessageId, ! 279: DWORD dwLanguageId, ! 280: LPSTR lpBuffer, ! 281: DWORD nSize, ! 282: va_list Arguments ! 283: ) ! 284: ! 285: Routine Description: ! 286: ! 287: This function formats a message string. Input to this function is a ! 288: message definition. It can come from a buffer passed into this ! 289: function. It can come from a message table resource in a module ! 290: already loaded. Or the caller can ask this function to search the ! 291: system message table resource(s) for the message. This function ! 292: finds the message definition based on the Message Id and the ! 293: Language Id and copies the message text to the output buffer, ! 294: processing any imbedded insert sequences if requested. ! 295: ! 296: Arguments: ! 297: ! 298: dwFlags - Specifies options to the formatting process along with how ! 299: to interpret the lpSource parameter. The low order 16bits of ! 300: this parameter are the maximum width of a line, in characters. ! 301: Possible values are: ! 302: ! 303: FORMAT_MESSAGE_ALLOCATE_BUFFER - the lpBuffer is a PVOID * and ! 304: nSize is the minimum size to allocate. This function will ! 305: then allocate a buffer large enought to hold the formatted ! 306: message and store the pointer to the buffer in the location ! 307: pointed to by lpBuffer. Caller should free the buffer ! 308: with LocalFree when they are done using it. ! 309: ! 310: FORMAT_MESSAGE_IGNORE_INSERTS - insert sequences in the message ! 311: definition will be ignored and passed through to the output ! 312: buffer as is. Useful for fetching a message for later ! 313: formatting. If this flag is set, the lpArguments parameter ! 314: is ignored. ! 315: ! 316: FORMAT_MESSAGE_FROM_STRING - lpSource is a pointer to a null ! 317: terminated message definition. It can contain insert ! 318: sequences just as the message text in the .mc file can. ! 319: ! 320: FORMAT_MESSAGE_FROM_HMODULE - lpSource is a module handle that ! 321: contains the message table resource(s) to search. If this ! 322: handle is NULL, then the current process's application ! 323: image file will be searched. ! 324: ! 325: FORMAT_MESSAGE_FROM_SYSTEM - If the requested message was not ! 326: found in lpSource or if lpSource was not examined (i.e. neither ! 327: of the preceeding two flags was specified), then this function ! 328: will search the system message table resource(s). ! 329: ! 330: FORMAT_MESSAGE_ARGUMENT_ARRAY - If set, specifies that the passed ! 331: Arguments parameter is NOT a va_list structure but instead is ! 332: just a pointer to an array of 32-bit values that represent ! 333: the arguments. ! 334: ! 335: FORMAT_MESSAGE_MAX_WIDTH_MASK - The low order 8 bits specify the ! 336: maximum width of each line formatted into the output buffer. ! 337: A maximum width of zero, means that no restrictions are ! 338: placed on the width, and only the line breaks in the message ! 339: definition will be placed in the output buffer. If a non-zero ! 340: value is specified, then line breaks in the message definition ! 341: text are ignored, and instead line breaks are calculated based ! 342: on the maximum width, with white space delimited strings never ! 343: being split across a line break. Hard coded line breaks in ! 344: the message definition text, that are identified by the %n ! 345: escape sequence, are always output to the output buffer. ! 346: ! 347: If the width specified is FORMAT_MESSAGE_MAX_WIDTH_MASK, then ! 348: line breaks in the message file are ignored and only hard coded ! 349: line breaks are kept and none are generated. ! 350: ! 351: lpSource - specifies where to retrieve the message definition from. ! 352: The type of this parameter depends upon the settings in the ! 353: dwFlags parameter. ! 354: ! 355: FORMAT_MESSAGE_FROM_HMODULE - lpSource is an hModule of the ! 356: module that contains the message table to search. ! 357: ! 358: FORMAT_MESSAGE_FROM_STRING - lpSource is an LPSTR that points ! 359: to unformatted message text. It will be scanned for ! 360: inserts and formatted accordingly. ! 361: ! 362: If neither of these options is specified, then this parameter is ! 363: ignored. ! 364: ! 365: dwMessageId - specifices the 32-bit message identifier that identifies ! 366: the message being requested. This parameter is ignored if the ! 367: FORMAT_MESSAGE_FROM_STRING flag is specified. ! 368: ! 369: dwLanguageId - specifices the 32-bit language identifier that ! 370: identifies the language of the message being requested. This ! 371: parameter is ignored if the FORMAT_MESSAGE_FROM_STRING flag is ! 372: specified. ! 373: ! 374: lpBuffer - specifies a pointer to a buffer where the formatted message ! 375: is to be written. A terminating null byte will also be written. ! 376: If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag was specified, then ! 377: this parameter points to a 32-bit pointer value that is filled in ! 378: by this call with a pointer allocated via LocalAlloc to contain ! 379: the text of the message. ! 380: ! 381: nSize - specifies the maximum number of bytes that can be stored in ! 382: the output buffer. This parameter is ignore if the ! 383: FORMAT_MESSAGE_ALLOCATE_BUFFER flag is set. ! 384: ! 385: Arguments - specifies a pointer to variable number of arguments. ! 386: These arguments are used to satisfy insert requests in the ! 387: format string. Thus %1 in the format string specifies the ! 388: first argument in the variable number of arguments described ! 389: by the Arguments parameter; %3 would specify the third, etc. ! 390: ! 391: The interpretation of each 32-bit arguments value depends upon ! 392: the formatting information associated with the insert in the ! 393: message definition. The default is to treat each pointer as a ! 394: pointer to a null terminated string. ! 395: ! 396: By default the Arguments parameter is of type va_list, which is ! 397: a language and implementation specific data type for describing ! 398: a variable number of arguments. If you do not have a pointer of ! 399: type va_list, then specify the FORMAT_MESSAGE_ARGUMENT_ARRAY ! 400: flag and pass a pointer to an array of 32-bit values that are ! 401: are input to the message formatted as the insert values. ! 402: Return Value: ! 403: ! 404: DwORD - Returns the number of bytes actually stored in the output ! 405: buffer, excluding the terminating null character. Returns 0 if ! 406: an error occurred. Extended error status is available via the ! 407: GetLastError API.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.