码迷,mamicode.com
首页 > 其他好文 > 详细

向自己的模块添加错误代码_使用vc自带的工具MC创建资源并将其添加至DLL或EXE中

时间:2015-06-08 10:00:56      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

本文主要介绍怎么使用Visual Studio自带的MC.exe工具来创建一个消息资源并将其添加到自己的DLL(.exe)中,从而达到为自己的模块添加错误代码的目的。

 

一、MC工具介绍

Message Compiler(MC) 是用来创建消息资源的工具,这些消息资源被DLL(EXE)模块引用。MC的输入是一个特定格式的文本文件,即*.mc文件,这种特定格式使得在一个文件中定义多种语言支持变得非常容易。

当编写完成一个*.mc文件之后,为了在程序中使用这个文件,你需要一些操作。首先,使用MC工具将这种文件编译成一个*.rc文件(还会生成*.h*.bin文件);然后将*.rc*.h添加进相应的DLLEXE)模块中编译;最后通过相应的事件日志函数或者FomatMessage函数对其中的消息文本进行使用。(具体的操作过程请看后面的例子)

 

二、消息文本文件定义(*.mc文件)

1、概述

Messages定义在一个*.mc文件中,MC工具会自动为每条消息赋一个编号,然后会生成一个*.h文件,以供程序引用其中的消息ID

*.mc文件里定义消息最常见的语法为KEYWORD=VALUE,等号两边的空格会被忽略。下一条类似的定义以空格或者换行来分隔。其中VALUE可以是一个整型常量,或者一个类似宏标识的符号,或者是一个8个字符(或更少)的名字。

 

2、注释

单行注释:以一个分号开头,然后后面接注释文字,为了在生成的*.h文件中也以注释状态出现,勿必在分号后面撞上一个//。如下:

;//这是一个单行注释


多行注释:每行都以分号开头,但是为了同样的目的,勿必如以下写多行注释:

;/*这是多行注释

;这是多行注释

;这是多行注释*/

 

3、头部定义块

*.mc文件以头部定义开始,头部定义一些名字标识以及语言标识供后面消息定义使用。头部通常包含以下0个或多个声明(可以是多个相同的声明,比如语言部分)。

MessageIdTypedef=type----用于消息标识定义的类型,如#define name ((type)0xnnnnnnnn)  注:在*.h文件中可看到此类定义。这个类型必须能够容下消息码的范围(32位),比如DWORD。这个类型也可以是程序部分中自定义的。默认状态下是无类型的,也就没有相应的转换。你可以在需要使用这个声明时,才开始定义它。如:MessageIdTypedef=DWORD

SeverityNames=(name=number[:name])----设置消息码中第3130位,即Severity部分。

默认的设置如下:

SeverityNames=(

Success=0x0

Informational=0x1

Warning=0x2

Error=0x3

)

FacilityNames=(name=number[:name])----设置消息码中27--16位,即Facility部分,默认的设置如下:

FacilityName=(

System=0x0FF

Application=0xFFF

)

 

LanguageNames=(name=number:filename)----设置消息所用语言标识,可设置多个语言版本。默认的设置如下:

LanguageNames=(English=1:MSG0001),其中1可由宏MAKELANGID生成,比如生成简体中文的,MAKELANGID( LAN_CHINES, SUBLANG_CHINESE_SIMPLIFIED),生成的值 为0x804,则我们可以定义LanguageNames=(Chinese=0x804:MSG0804),其中MSG0804是我们自定义的名字,生成的*.bin文件会以其命令,如MSG0804.bin

OutputBase=number----生成消息常量数值格式,比如指定16,生成16进制的数,指定10,生成10进制的数等。

 

4、消息主体定义 

消息文本文件包含以下0个或多个声明,其中MessageId标识了一个消息定义的开始,必须存在,SeverityFacility声明是可选的。

MessageId=[number|+number]----消息序号标识,这项必须要有,但是值是可选的。如果没有指定值,此值等于上一个Facility加上1,如果在指定的值前面带上了一个+号,则用上一个Facility加上此值来生成MessageId

Severity=name----在头部声明FacilityNames指定的一个名字,这个声明是可选的。如果没有指定值,则使用在消息定义块中最后指定的那个值。默认的第一个消息定义是

Facility=Application

SymbolicName=name----一个标识符,在*.h文件中可看到,如#define name ((type)0xnnnnnnnn)

OutpubBase={number}----生成消息常量数值格式,比如指定16,生成16进制的数,指定10,生成10进制的数等。

Language=name----在头部声明LanguageNames指定的一个名字,此项是可选项,如果没有指定值,则使用在消息定义块中最后指定的那个值。默认的第一个消息定义是

Language=English

Message Text----消息文本。

.(点号) ----消息定义终止符,注:此终止符为英文输入模式下输入,否则使用mc工具进行编译时会提示无终止符的。消息定义例子如下:

MessageId=0x1

Severity=Error

Facility=Runtime

SymbolicName=MSG_BAD_COMMAND

Language=English

You have chosen an incorrect command.

.

Language=Chinese

你选择了一个不正常的命令。

.

 

你还可以在消息文本定义中使用一些控制符,具体的可查看MSDN

 

三、*.mc文件定义的例子

 

1、文件内容,文件名字McFile.mc

 

;//***** Sample.mc *****

;//This is the header section.

MessageIdTypedef=DWORD

SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
    Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
    Warning=0x2:STATUS_SEVERITY_WARNING
    Error=0x3:STATUS_SEVERITY_ERROR
    )


FacilityNames=(System=0x0:FACILITY_SYSTEM
    Runtime=0x2:FACILITY_RUNTIME
    Stubs=0x3:FACILITY_STUBS
    Io=0x4:FACILITY_IO_ERROR_CODE
)

LanguageNames=(English=0x409:MSG00409)
LanguageNames=(Chinese=0x804:MSG00804)

; // The following are message definitions.


MessageId=0x1
Severity=Error
Facility=Runtime
SymbolicName=MSG_BAD_COMMAND
Language=English
You have chosen an incorrect command.
.
Language=Chinese
你选择了一个不正常的命令。
.

MessageId=0x2
Severity=Warning
Facility=Io
SymbolicName=MSG_BAD_PARM1
Language=English
Cannot reconnect to the server. 
.
Language=Chinese
无法连接服务器。
.

MessageId=0x3
Severity=Success
Facility=System
SymbolicName=MSG_STRIKE_ANY_KEY
Language=English
Press any key to continue . . . %0 
.
Language=Chinese
按任意键继续...
.



MessageId=0x4
Severity=Error
Facility=System
SymbolicName=MSG_CMD_DELETE
Language=English
File %1 contains %2 which is in error 
.
Language=Chinese
文件 %1 包含 %2 r损坏。
.


MessageId=0x5
Severity=Informational
Facility=System
SymbolicName=MSG_RETRYS
Language=English
There have been %1!d! attempts with %2!d!%% success%! Disconnect from the server and try again later. 
.
Language=Chinese
未知错误!无法连接服务器,请稍后重试!
.

 

2、使用MC工具编译

打开visual studio的命令行界面,进入McFile.mc文件目录,使用命令mc -a -A McFile.mc进行编译,如下:

 技术分享

 

编译成功后,会在当前目录下生成McFile.hMcFile.rcMSG00409.binMSG00804.bin四个文件,因为文本文件中支持中英文,所以生成了两个*.bin文件。

 

McFile.h文件部分预览如下:

//***** Sample.mc *****
//This is the header section.
// The following are message definitions.
//
//  Values are 32 bit values layed out as follows:
//
//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//  +---+-+-+-----------------------+-------------------------------+
//  |Sev|C|R|     Facility          |               Code            |
//  +---+-+-+-----------------------+-------------------------------+
//
//  where
//
//      Sev - is the severity code
//
//          00 - Success
//          01 - Informational
//          10 - Warning
//          11 - Error
//
//      C - is the Customer code flag
//
//      R - is a reserved bit
//
//      Facility - is the facility code
//
//      Code - is the facility's status code
//
//
// Define the facility codes
//
#define FACILITY_SYSTEM                  0x0
#define FACILITY_STUBS                   0x3
#define FACILITY_RUNTIME                 0x2
#define FACILITY_IO_ERROR_CODE           0x4


//
// Define the severity codes
//
#define STATUS_SEVERITY_WARNING          0x2
#define STATUS_SEVERITY_SUCCESS          0x0
#define STATUS_SEVERITY_INFORMATIONAL    0x1
#define STATUS_SEVERITY_ERROR            0x3


//
// MessageId: MSG_BAD_COMMAND
//
// MessageText:
//
//  You have chosen an incorrect command.
//
#define MSG_BAD_COMMAND                  ((DWORD)0xC0020001L)


 

3、将生成的资源文件编译进dll(exe)模块中。

创建一个WIN32DLL工程,将McFile.hMcFile.rc文件添加进去,进行编译,生成相应的dll即可提供给我们的程序使用。

 

四、使用自己定义的错误代码,即第三步生成的消息资源模块

 

#include <iostream>
#include <windows.h>

using namespace std;


//
#ifdef _UNICODE
#define COUT wcout
#else
#define COUT cout
#endif


int main()
{
	DWORD dwError = 0;

	DWORD dwLanguageId = MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL );

	//解决问题:wcout输出时显示不了中文
	COUT.imbue( std::locale( "chs" ) );

	HLOCAL lpMsgTextBuf = NULL;
	COUT << TEXT("输入一个自定义的错误代码(如:3221356545(0xC0020001) ):");
	while( cin >> dwError )
	{
		lpMsgTextBuf = NULL;

		HMODULE ghResDll = LoadLibrary( TEXT("WinMsgDll.dll") );
		if ( NULL == ghResDll )
		{
			COUT << TEXT("加载消息模块失败!") << endl;
			return -1;
		}


		BOOL bOk = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | 
			FORMAT_MESSAGE_IGNORE_INSERTS | 
			FORMAT_MESSAGE_ALLOCATE_BUFFER,
			ghResDll, dwError, dwLanguageId, (LPTSTR)&lpMsgTextBuf, 0, NULL );


		if ( !bOk )
		{
			COUT << TEXT("error ") << GetLastError() << endl;
		}

		if ( NULL != lpMsgTextBuf )
		{
			COUT << (LPTSTR)lpMsgTextBuf << endl;
			LocalFree( lpMsgTextBuf );
		}

		COUT << TEXT("输入一个自定义的错误代码(如:3221356545(0xC0020001) ):");
	}
	return 0;
}


五、相应例子visual studio 2005工程文件代码下载

工程文件下载:使用MC工具创建自定义错误代码DLL

 

作者:山丘儿
转载请标明出处,谢谢。原文地址:http://blog.csdn.net/s634772208/article/details/46402677

向自己的模块添加错误代码_使用vc自带的工具MC创建资源并将其添加至DLL或EXE中

标签:

原文地址:http://blog.csdn.net/s634772208/article/details/46402677

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!