MFC消息映射表

MFC程序各个文件

在上一篇《从Win32过渡到MFC工程》中,我们将所有的逻辑写在了一个cpp文件中,现在我们对文件进行整理。

FirstMFC的功能:弹出一个窗口,显示窗口对应的图标、窗口名、窗口可以相应各种事件。

FirstMFC头文件与CPP文件分开

FirstMFC.h进行声明

class CMyApp :public CWinApp
{
public:
	BOOL InitInstance();
};

FirstMFC.cpp实现头文件的相关声明

引入公用的头文件(stdafx.h)和同名的头文件、MainDlg.h(对话框)

stdafx.h内容(公共资源)如下:

#include <afxwin.h>
#include "resource.h"

资源的添加方式是通过源文件->添加资源的引导界面实现的:

 此处的CMainDlg对话框和图标IDI_LOGO都是通过此方式添加的。

实现同名头文件声明的函数

#include "stdafx.h"
#include "FirstMFC.h"
#include "MainDlg.h"

BOOL CMyApp::InitInstance()
{
    CMainDlg dlg;
    dlg.DoModal();

    return TRUE;
}

CMyApp theApp;

MainDlg.h头文件主要内容如下:

1、CMainDlg的一些声明信息(声明函数定义、资源ID定义包括对话框资源,图标资源等);

2、DECLARE_MESSAGE_MAP() 宏定义,声明消息映射,一般这个宏调用写在类定义的结尾处

3、对应消息处理函数的声明。

class CMainDlg :public CDialog
{
private:
    enum{ IDD = IDD_MAIN_DLG };
public:
    HICON m_hIcon;
    HICON m_hIcon1;
    CMainDlg();

    BOOL OnInitDialog();

    //声明消息映射
    DECLARE_MESSAGE_MAP()

public:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);        //WM_CREATE消息处理函数
    afx_msg void OnClose();                                        //WM_CLOSE消息处理函数
};
View Code

在对内容3中的消息处理函数声明的时候,有的时候消息处理函数签名我们不能时刻记住,可以通过类向导来实现。通过类向导界面操作,可以在对应头文件中声明消息处理函数、同时在对应cpp文件中书写好消息处理函数的实现。

步骤如下:切换到类视图,在对应的CMainDlg类上进行类向导操作。右键->类向导->点击添加处理程序

 即可看到MainDlg头文件和CPP文件下添加如下代码:

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); //MainDlg.h中
//cpp中
int CMainDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDialog::OnCreate(lpCreateStruct) == -1)
        return -1;

    // TODO:  在此添加您专用的创建代码

    return 0;
    
}

同时在MainDlg.cpp中的BEGIN_MESSAGE_MAP(CMainDlg, CDialog)和END_MESSAGE_MAP之间增加对应名称的消息映射

在BEGIN_MESSAG_MAP和END_MESSAGE_MAP之间的内容成为消息映射入口项。

//消息映射
BEGIN_MESSAGE_MAP(CMainDlg, CDialog)//开始消息映射
    ON_WM_CREATE()
END_MESSAGE_MAP()//结束消息映射

消息映射表

在类定义文件MainDlg.h中添加的宏DECLARE_MESSAGE_MAP()我们查看该宏,如下:

protected: 
    static const AFX_MSGMAP* PASCAL GetThisMessageMap(); 
    virtual const AFX_MSGMAP* GetMessageMap() const; 

其声明了两个函数GetThisMessageMap和GetMessageMap。

在类的实现文件MainDlg.cpp中BEGIN_MESSAGE_MAP宏的信息如下:

#define BEGIN_MESSAGE_MAP(theClass, baseClass) 
    PTM_WARNING_DISABLE 
    const AFX_MSGMAP* theClass::GetMessageMap() const 
        { return GetThisMessageMap(); } 
    const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() 
    { 
        typedef theClass ThisClass;                           
        typedef baseClass TheBaseClass;                       
        static const AFX_MSGMAP_ENTRY _messageEntries[] =  
        {

# define END_MESSAGE_MAP() 
        {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } }; 

        static const AFX_MSGMAP messageMap = { &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; 
        return &messageMap; 
    }

我们将theClass和baseClass分别替换为实际传入的CMainDlg和CDialog,替换END_MESSAGE_MAP宏,最后的结果如下:

const AFX_MSGMAP* CMainDlg::GetMessageMap() const
{
    return GetThisMessageMap();
}

const AFX_MSGMAP* PASCAL CMainDlg::GetThisMessageMap()
{
    typedef CMainDlg ThisClass;
    typedef CDialog TheBaseClass;

    static const AFX_MSGMAP_ENTRY _messageEntries[] =
    {

        { WM_CREATE, 0, 0, 0, AfxSig_is, (AFX_PMSG)(AFX_PMSGW)(static_cast< int (AFX_MSG_CALL CWnd::*)(LPCREATESTRUCT) > (&ThisClass::OnCreate)) },
        { WM_CLOSE, 0, 0, 0, AfxSig_vv, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(void) > (&ThisClass::OnClose)) },
        { WM_DESTROY, 0, 0, 0, AfxSig_vv, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(void) > (&ThisClass::OnDestroy)) },
        { WM_PAINT, 0, 0, 0, AfxSig_vv, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(void) > (&ThisClass::OnPaint)) },
        { WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (&ThisClass::OnLButtonDown)) },
        { WM_LBUTTONUP, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (&ThisClass::OnLButtonUp)) },
        { WM_LBUTTONDBLCLK, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (&ThisClass::OnLButtonDblClk)) },
        { WM_MOUSEMOVE, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (&ThisClass::OnMouseMove)) },
        { WM_TIMER, 0, 0, 0, AfxSig_v_up_v, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT_PTR) > (&ThisClass::OnTimer)) },
        { WM_SIZE, 0, 0, 0, AfxSig_vwii, (AFX_PMSG)(AFX_PMSGW)(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, int, int) > (&ThisClass::OnSize)) },
        { UM_TEST, 0, 0, 0, AfxSig_lwl, (AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT(AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM)>(&CMainDlg::OnTest)) },
        { WM_COMMAND, (WORD)BN_CLICKED, (WORD)IDC_BTN_TEST, (WORD)IDC_BTN_TEST, AfxSigCmd_v, (static_cast< AFX_PMSG > (&CMainDlg::OnBtnTest)) },
        { 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
    };
    static const AFX_MSGMAP messageMap =
    {
        &TheBaseClass::GetThisMessageMap, &_messageEntries[0]
    };
    return &messageMap;
}
View Code

其为类定义文件中的宏DECLARE_MESSAGE_MAP()声明的两个函数的实现。_messageEntries数组中每个AFX_MSGMAP_ENTRY对象元素对应了每个消息绑定的处理函数,且处理函数在

类定义文件中也已声明(以afx_msg开头)。这里我们完善了消息的种类,增加了WM开头的命令消息WM_COMMAND和自定义消息UM_TEST。

结构体AFX_MSGMAP_ENTRY信息如下:

struct AFX_MSGMAP_ENTRY
{
    UINT nMessage;   // windows message
    UINT nCode;      // control code or WM_NOTIFY code
    UINT nID;        // control ID (or 0 for windows messages)
    UINT nLastID;    // used for entries specifying a range of control id's
    UINT_PTR nSig;       // signature type (action) or pointer to message #
    AFX_PMSG pfn;    // routine to call (or special value)
};
原文地址:https://www.cnblogs.com/shuzhongke/p/15425265.html