• MFC宏常识


    1、宏就是用宏定义指令#define定义一个标识符,用它来表示一个字符串或一段源代码。

    MFC宏作为MFC类库的一个组成部分在MFC应用程序中经常出现。

    MFC宏在路径

    ".../Microsoft Visual Studio/VC/atlmfc/include"

    下的Afxwin.h、Afx.h及Afxmsg_.h等MFC头文件中分别进行了定义。

    (1)常用的MFC宏

    包括消息映射宏运行时类型识别宏序列化宏调试宏异常宏等。

    要想真正了解MFC的内部机制和熟练运用MFC,必须掌握MFC宏的基本原理和使用方法。

    (2)有关运行时类型识别的宏

    运行时类型识别(RTTI)是指在程序运行时能够确定一个对象的类型。

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

    1.运行时基础宏:RUNTIME_CLASS(class_name)

    返回参数class_name所指定类的静态成员变量class##class_name的指针,该指针指向一个CRuntime结构。

    宏定义如下:

    #define RUNTIME_CLASS(class_name)  
                  ((CRuntimeClass*)(&class_name::class##class_name)) 

    程序能够利用RUNTIME_CLASS宏实时创建类的实例。

    为了让这个宏起作用,定义的类必须是类CObject的派生类,并且在派生类的定义中必须使用宏DECLARE_DYNAMIC、DECLARE_DYNCREATE或DECLARE_SERIAL,

    在派生类的实现源文件中使用宏IMPLEMENT_DYNAMIC、IMPLEMENT_DYNCREATE或IMPLEMENT_SERIAL。

    这三个宏使MFC类及其派生类具有三个不同等级的功能。

    2.动态支持宏:DECLARE_DYNAMIC(class_name)和IMPELMENT_DYNAMIC(class_name,base_class_name)

    使用动态支持宏能够使CObject派生类的对象具有基本的类型识别机能,可以通过调用成员函数CObject::IsKindOf(ClassName)测试对象与给定类Class_Name的关系。

    DECLARE_DYNAMIC()宏定义如下:

    #define DECLARE_DYNAMIC(class_name)  
    public:  
        static const CRuntimeClass class##class_name;  
        virtual CRuntimeClass* GetRuntimeClass() const; 

    例1: 定义一个类MyClass,使用RUNTIME_CLASS()宏的基本对象识别功能

    //在头文件MyClass.h 
    class CMyClass:public CObject  
    {  
      DECLARE_DYNAMIC(CMyClass)  
    public:  
      void someFunction(void);  
    };
    
    //在实现源文件MyClass.cpp中 
    #include "MyClass.h" 
    IMPLEMENT_DYNAMIC(CMyClass,CObject) 
    
    void CMyClass::SomeFunction(void)  
    {  
        CObject* pObject=new CMyClass;  
        if(pObject->IsKindOf(RUNTIME_CLASS(CMyClass)))  
        {  
            CMyClass* pMyObject=(CMyClass*)pObject;  
            AfxMessageBox("MyObject is an object of the class CMyClass");  
        }  
        else 
            AfxMessageBox("MyObject is not an object of the class CMyClass");  
        delete pObject;  
    }  

    3.动态创建宏:DECLARE_DYNCREATE(class_name)和 IMPLEMENT_DYNCREATE(class_name,base_class_name)

    动态创建是动态支持的一个超集,除了基本的类型识别机能,使用动态创建宏能够使CObject类的派生类具有运行时动态创建对象的功能。

    注意,支持动态创建的类必须有一个默认的不带参数的构造函数,用于一个稳定的对象。

    MFC应用程序框架利用这个机能动态创建新的对象。

    例如,当序列化期间从磁盘读取一个对象时,应用程序框架将利用文档类、视图类和框类的动态创建功能业动态创建它们的运行时对象。

    在MFC应用程序框架中,向导为MFC派生类自动添加了这两个动态创建宏。

    4.序列化:DECLARE_SERIAL()和IMPLEMENT_SERIAL()

    序列化是动态支持和动态创建的一个超集,除了基本的类别识别和动态创建机能,使用序列化宏能够使CObject类的派生类具有实现对象持久性的序列化功能。


    MFC调试宏

    1.TRACE跟踪声明宏

        TRACE()宏语法说明如下:

    TRACE(<输出格式>,<表达式>)

    其中的参数是由输出格式和表达式组成,其形式与函数printf()的参数一样。

    TRACE宏的功能是在调试运行时把表达式的值输出到Output调试窗口。

    TRACE宏只在MFC应用程序Debug版的调试运行状态下才起作用,并且必须保证在Developer Studio中的Enable tracing设置,这需要执行Tools|MFC Tracer命令。

    例2 对于以下代码:

        char* szName="LiMing";  
    
        int nAge=18;  
    
        TRACE("Name=%s,Age=%",szName,nAge); 
    
    调试运行时在Ouput窗口将输出以下内容:
    
          Name=LiMing,Age=18

    2.ASSERT断言宏 

     ASSERT(<表达式>)

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

    例如,在视图派生类的成员函数GetDocument()中,MFC使用了ASSERT()宏判断当前文档是否是运行时类的对象。

       例3 :设已自定义一个名为CMyFrame的框架窗口类,它也是CFrameWnd的派生类。在程序中构建一个与CMyFrame相关联的文档模板对象,并为构建的文档模板创建框架窗口。然后可以编写如下代码使用这个框架窗口。

          CMyFrame* pFrame=(CMyFrame*)AfxGetMainWnd();  
    
          ASSERT(pFrame->IsKindOf(RUNTIME_CLASS(CMyFrame)));   //判断pFrame的类型
    
          pFrame->DoSomeOperation();        //调用成员函数完成某些操作

    AfxGetMainWnd()是一个全局函数,返回值向应用程序主窗口的指针,类型为CWnd*,因此必须对它进行强制类型转换。但如何知道是否转换成功?

    CMyFrame类也是CObject的派生类,可以结合成员函数IsKindOf()使用ASSERT()宏来检查pFrame的类型。

    在pFrame->DoSomeOperation()语句之前插入ASSERT()宏,就可以在运行机制时做类型检查,当类型不匹配时,引发一个断方,可以中断程序执行。

    ASSERT宏只在Debug版本中才起作用,它在Release版本中是不会被编译的,

    在Release版本中可以使用VERIFY宏。VERIFY宏与ASSERT宏在Debug版本中的作用一致,

    区别在于在Release版本中VERIFY宏仍然有效,它会对参数表达式求值,但不管结果如何都不会暂停程序的运行。

    为了避免给程序带来不良的后果,使用ASSERT宏时必须保证参数表达式中不能有函数调用语句,

    因为ASSERT宏中的函数调用语句在Release版本中根本不在。

    出现这种情况时,可以使用VERIFY宏取代ASSERT宏。

    3.ASSERT_VALID断言有效宏

    ASSERT_VALID()宏语法说明如下:

    ASSERT_VALID(<指针>)

    ASSERT_VALID宏用于检查指针和对象的有效性。对于一般指针,只检查指针是否为空。

    对于MFC类对象指针,通过调用CObject类的成员函数AssertValid()判断对象的舍法性。

    ASSERT_VALID宏提示指针或对象无效的方式与ASSERT宏一样,弹出一个信息对话框。

    ASSERT_VALID宏也是只在Debug版本中才起作用。

  • 相关阅读:
    一个体验好的Windows 任务栏缩略图开发心得
    扫脸动画
    ShimmerTextView
    201512-2 消除类游戏 (水题,暴力)
    CCF 201512-1 数位之和 (水题)
    UVa 557 Burger (概率+递推)
    CCF 201604-2 俄罗斯方块 (模拟)
    CCF 201604-1 折点计数 (水题,暴力)
    UVa 10213 How Many Pieces of Land ? (计算几何+大数)
    UVa 1641 ASCII Area (计算几何,水题)
  • 原文地址:https://www.cnblogs.com/staring-hxs/p/3648831.html
Copyright © 2020-2023  润新知