最近我在用MFC开发一个智能家居监控平台的软件(用到了MSCOMM串口通信控件),当我通过在一个对话框类A中定义另一个对话框类B的对象访问B的public成员时,提示不可访问。后来经过多天的向朋友求救,终于在一个大神的帮助下找到了解决方案。原来在使用ActiveX控件时会产生一个DECLARE_EVENTSINK_MAP()宏,在此宏之后定义的每一个成员如果不指定一个新的存取类型都会失去其原有的属性。如果在DECLARE_EVENTSINK_MAP()宏(或者其它宏)之后定义任何一个成员,都必须为其指定一个新的存取类型
  请看DECLARE_EVENTSINK_MAP()宏的定义(在afxwin.h中):
#ifdef _AFXDLL
#define DECLARE_EVENTSINK_MAP() \
private: \
static const AFX_EVENTSINKMAP_ENTRY _eventsinkEntries[]; \
static UINT _eventsinkEntryCount; \
protected: \
static const AFX_EVENTSINKMAP eventsinkMap; \
static const AFX_EVENTSINKMAP* PASCAL GetThisEventSinkMap(); \
virtual const AFX_EVENTSINKMAP* GetEventSinkMap() const; \ #else
#define DECLARE_EVENTSINK_MAP() \
private: \
static const AFX_EVENTSINKMAP_ENTRY _eventsinkEntries[]; \
static UINT _eventsinkEntryCount; \
protected: \
static const AFX_EVENTSINKMAP eventsinkMap; \
virtual const AFX_EVENTSINKMAP* GetEventSinkMap() const; \ #endif
下面就简介一下MFC常用宏:
 
OLE控件事件宏
DECLARE_EVENTSINK_MAP()
  An OLE container can provide an event sink map to specify the events your container will be notified of. Use the DECLARE_EVENTSINK_MAP macro at the end of your class declaration. Then, in the .CPP file that defines the member functions for the class, use the BEGIN_EVENTSINK_MAP macro, macro entries for each of the events to be notified of, and the END_EVENTSINK_MAP macro to declare the end of the event sink list.
 
消息映射宏
Message-Map Declaration and Demarcation Macros
Declares that a message map will be used in a class to map messages to functions (must be used in the class declaration).
Begins the definition of a message map (must be used in the class implementation).
Ends the definition of a message map (must be used in the class implementation).
 
Message-Mapping Macros
Indicates which function will handle a specified command message.
Indicates which function will handle a specified control-notification message.
Indicates which function will handle a user-defined message.
Indicates which function will handle a menu command from a DocObject or its container.
Indicates which function will handle a registered user-defined message.
Indicates which function will handle a registered user-defined message when you have a CWinThread class.
Indicates which function will handle a user-defined message when you have a CWinThread class.
Indicates which function will handle a specified user-interface update command message.
 
Message-Map Range Macros
Indicates which function will handle the range of command IDs specified in the first two parameters to the macro.
Indicates which update handler will handle the range of command IDs specified in the first two parameters to the macro.
Indicates which function will handle notifications from the range of control IDs specified in the second and third parameters to the macro. The first parameter is a control-notification message, such as BN_CLICKED.

MFC调试宏

TRACE()——跟踪调试宏

  TRACE(<输出格式>,<表达式>)中的参数是由输出格式和表达式组成,其形式与函数printf()的参数一样。TRACE宏的功能是在调试运行时把表达式的值输出到Output调试窗口。TRACE宏只在MFC应用程序Debug版的调试运行状态下才起作用,并且必须保证Developer Studio中的Enable tracing设置使能。

  注:VS2010 中,用TRACE不要加 _T ,不然会提示_CrtDbgReport: String too long or IO Error

示例代码:

char* szName="LiMing";
int nAge=;
//vs2010 中,用TRACE不要加 _T ,不然会提示_CrtDbgReport: String too long or IO Error
TRACE("Name=%s,Age=%d\n",szName,nAge);

ASSERT()——断言宏

  ASSERT(<表达式>) :如果表达式为真,则程序继续执行;否则暂停程序的运行,并弹出一个对话框,告诉用户程序暂停运行的行及所在文件的信息。用户可选择终止运行、调试程序或继续运行。

ASSERT_VALID()——断言有效宏

  ASSERT_VALID(<指针>)用于检查指针和对象的有效性。对于一般指针,只检查指针是否为空。对于MFC类对象指针,通过调用CObject类的成员函数AssertValid()判断对象的舍法性。ASSERT_VALID宏提示指针或对象无效的方式与ASSERT宏一样,弹出一个信息对话框。ASSERT_VALID宏也是只在Debug版本中才起作用。

VERIFY()——校验宏

  In the Debug version of MFC, evaluates its argument. If the result is 0, the macro prints a diagnostic message and halts the program. If the condition is nonzero, it does nothing. The diagnostic message has the form "assertion failed in file <name> in line <num>".

  In the Release version of MFC, VERIFY evaluates the expression but does not print or interrupt the program. For example, if the expression is a function call, the call will be made.

示例代码:

// VERIFY can be used for things that should never fail, though
// you may want to make sure you can provide better error recovery
// if the error can actually cause a crash in a production system. // It _is_ possible that GetDC() may fail, but the out-of-memory
// condition that causes it isn't likely. For a test application,
// this use of VERIFY() is fine. For any production code, this
// usage is dubious. // get the display device context
HDC hdc;
VERIFY((hdc = ::GetDC(hwnd)) != NULL); // give the display context back
::ReleaseDC(hwnd, hdc);

有关运行时类型识别的宏

  非多态语言不需运行时的类型信息,因为每个对象的类型在编译时就确定了(例如:在写程序的时候我们指定了对象的类型)。但在支持多态的语言中(例如C++),可能存在这种情况:在编译时你并不知道某个对象的类型信息,而只有在程序运行时才能获得对象的准确信息。我们已经知道,C++是通过类的层次结构、虚函数以及基类指针来实现多态的。基类指针可以用来指向基类的对象或者其派生类的对象,也就是说,我们并不总是能够在任何时刻都预先知道基类指针所指向对象的实际类型。因此,必须在程序中使用“运行时类型识别”来识别对象的实际类型。  

  运行时类型识别(runtime type information,RTTI)是指在程序运行时能够确定一个对象的类型。MFC扩充了一般C++中运行时类型识别的功能,当一个类支持MFC的运行时类型识别功能时,它允许程序获取对象的信息(如类名、所占存储空间大小及版本号等)和基类信息(runtime class informtation,RTCI)。

DECLARE_DYNAMIC()——动态支持宏

  Adds the ability to access run-time information about an object's class when deriving a class from CObject.

  If you use the DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC macros as described, you can then use the RUNTIME_CLASS macro and the CObject::IsKindOf function to determine the class of your objects at run time.

RUNTIME_CLASS(class_name)——运行时基础宏

  Gets the run-time class structure from the name of a C++ class.

  RUNTIME_CLASS returns a pointer to a CRuntimeClass structure for the class specified by class_name. Only CObject-derived classes declared with DECLARE_DYNAMIC,DECLARE_DYNCREATE, or DECLARE_SERIAL will return pointers to a CRuntimeClass structure.

示例代码:

CRuntimeClass* prt = RUNTIME_CLASS(CAge);
ASSERT(strcmp(prt->m_lpszClassName, "CAge") == );

Color Macros

RGB()

语法形式:COLORREF RGB( BYTE byRed, BYTE byGreen, BYTE byBlue )

  The intensity for each argument is in the range 0 through 255. If all three intensities are zero, the result is black. If all three intensities are 255, the result is white.

  To extract the individual values for the red, green, and blue components of a COLORREF color value, use theGetRValueGetGValue, and GetBValue macros, respectively.

字符编码宏

_T、_TEXT、TEXT、_L、L

  _T("")是一个宏,定义于tchar.h下,作用是让你的程序支持Unicode编码。

#define  __T(x)      L ## x

#define  _T(x)       __T(x)
#define _TEXT(x) __T(x)
  如果你编译一个程序为ANSI方式,_T实际不起任何作用;而如果编译一个程序为UNICODE方式,则编译器会把"Hello"字符串以UNICODE方式保存。
#ifdef   UNICODE
#define __T(x) L ## x
#else
#define __T(x) x
#endif
  _T和_L的区别在于,_L不管你是以什么方式编译,一律以UNICODE方式保存

  在字符串前加一个L作用: 如 L"我的字符串" 表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。

  如果你定义了UNICODE,那么_T宏会把字符串前面加一个L。这时 _T("ABCD") 相当于 L"ABCD" ,这是宽字符串;如果没有定义,那么_T宏不会在字符串前面加那个L,_T("ABCD") 就等价于 "ABCD"。
 
CHAR、WCHAR、TCHAR
typedef   unsigned   char   CHAR;
typedef unsigned wchar_t WCHAR;

CHAR实际上就是unsigned char,WCHAR为wchar_t,而TCHAR根据是否支持UNICODE而不同。

#ifdef   UNICODE
typedef wchar_t TCHAR;
#else
typedef unsigned char TCHAR;
#endif

当我们定义了UNICODE宏,就相当于告诉了编译器准备采用UNICODE版本。此时,TCHAR就会由unsigned char变成wchar_t。

常用MFC宏的更多相关文章

  1. VC中常用的宏

        我们在VS环境中开发的时候,会遇到很多宏定义,这些宏可以应用到代码中,或用于编译.工程选项等设置,总之是我们开发中必不可少的工具,有必要做一个总结.有些宏是C/C++定义的,有些宏是VC环境预 ...

  2. MFC宏常识

    1.宏就是用宏定义指令#define定义一个标识符,用它来表示一个字符串或一段源代码. MFC宏作为MFC类库的一个组成部分在MFC应用程序中经常出现. MFC宏在路径 ".../Micro ...

  3. iOS - 常用的宏定义

    1.处理NSLog事件(开发者模式打印,发布者模式不打印) 1 2 3 4 5   #ifdef DEBUG   #define NSLog(FORMAT, ...) fprintf(stderr,& ...

  4. kenrnel 驱动中常用的宏

    http://blog.csdn.net/uruita/article/details/7263290 1. MODULE_DEVICE_TABLE (usb, skel_table);该宏生成一个名 ...

  5. VC中常用的宏[转]

    我们在VS环境中开发的时候,会遇到很多宏定义,这些宏可以应用到代码中,或用于编译.工程选项等设置,总之是我们开发中必不可少的工具,有必要做一个总结.有些宏是C/C++定义的,有些宏是VC环境预定义的. ...

  6. MFC宏

    1,DECLARE_MESSAGE_MAP:在头文件中声明源文件中所含有的消息映射 2,BEGIN_MESSAGE_MAP:标记源文件消息映射的开始 3,END_MESSAGE_MA:标记源文件消息映 ...

  7. Linux驱动中常用的宏

    .module_i2c_driver(adxl34x_driver)展开为 static int __int adxl34x_driver_init(void) { return i2c_regist ...

  8. 在oc中一些常用的宏定义总结

    1.打印CGRect,Size,Point #define NSLogRect(rect) NSLog(@"%s x:%.4f, y:%.4f, w:%.4f, h:%.4f", ...

  9. iOS常用的宏定义总结

    字符串是否为空 1   #define kStringIsEmpty(str) ([str isKindOfClass:[NSNull class]] || str == nil || [str le ...

随机推荐

  1. JAVA语言 第五周

    我准备在下一周对Java语法进行总结,现在写代码模板还要参考,语法掌握的不熟悉. 这一周除了对代码进行完善外,观看了一些java入门学习视频.

  2. div 光标处插入内容

    var Manager = { insertHtml: function(html, type) { var lastMemo = document.getElementById("memo ...

  3. CentOS YUM 安装 TOMCAT6

    安装tomcat6 1 yum install tomcat6 tomcat6-webapps tomcat6-admin-webapps 启动tomcat6 1 service tomcat6 st ...

  4. javolution学习--介绍

    javolution提供一个高性的Java集合(collection )类库和一些实用的工具类.虽然这个类包只提供非常少的几个集合类,但是这些类就能够代替大部分java.util类.javolutio ...

  5. jQuery插件开发的两种方法及$.fn.extend的详解(转)

    jQuery插件开发的两种方法及$.fn.extend的详解 jQuery插件开发分为两种:1 类级别.2 对象级别,下面为大家详细介绍下   jQuery插件开发分为两种: 1 类级别 类级别你可以 ...

  6. 第四章 栈与队列(c2)栈应用:括号匹配

  7. Hudson 打包部署到Was上特别慢

    一.找问题点 1.打包很快,到部署很慢 2.部署到其他was一样很慢 二.解决 经过寻找,网上找出以下一段话: 问题出在web.xml,web.xml中的版本信息不对,要根据你的servlet版本和运 ...

  8. SSH 连接很慢

    相信很多朋友在使用Linux系统的时候因为安全性的原因摒弃了telnet rlogin 或者 X-window,而把openssh作为自己默认的远程登录方式.然而经常会遇到的一个情况是telnet到s ...

  9. PHP遍历数组常用方式(for,foreach,while,指针等等)

    1使用for循环遍历数组 count($arr)用于统计数组元素个数         for循环只能用于遍历,纯索引数组!!如果存在关联数组,count统计两种数组的总个数         使用for ...

  10. PTA 7-7 六度空间(广搜)

    “六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论.这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够 ...