#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调试宏
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=18; //vs2010 中,用TRACE不要加 _T ,不然会提示_CrtDbgReport: String too long or IO Error TRACE("Name=%s,Age=%d ",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") == 0);
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 theGetRValue, GetGValue, 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)
#ifdef UNICODE #define __T(x) L ## x #else #define __T(x) x #endif
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。