常用MFC宏


  最近我在用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=18; 
//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") == 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 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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM