对于正在学习C++的同学们来说,MFC是一个比较有难度的知识点,所以今天我就给大家来分享一下,在MFC中,消息机制的内容,希望能对大家有所帮助咯。
对这方面感兴趣或者想学习C/C++可以加群:558502932
一.mfc中消息映射机制
消息循环的使用
1,必须是CCmdTarget的子类
2.在类中需要定义一个宏
DECLARE_MESSAGE_MAP()
3.在类外需要实现一个宏
BEGIN_MESSAGE_MAP(当前类类型,基类类型)
ON_MESSAGE(WM_CREATE,OnCreate)//消息映射
END_MESSAGE_MAP()
对这方面感兴趣或者想学习C/C++可以加群:558502932
4宏代码解析
structAFX_MSGMAP{
constAFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
//基类消息映射的入口地址,指向基类的AFX_MSGMAP
constAFX_MSGMAP_ENTRY* lpEntries;
//当前类消息映射的入口地址,指向_messageEntries[]的首地址
};
structAFX_MSGMAP_ENTRY{
UINT nmessage; // 窗口消息ID
UINT nCode; // 通知码
UINT nID; // 控件id/命令的ID
UINT nLastID; // 最后一个控件id
UINT_PTR nSig; //消息处理函数的类型
AFX_PMSG pfn; // 消息处理函数地址
};
DECLARE_MESSAGE_MAP()
替换 如下
protected:
staticconstAFX_MSGMAP* PASCAL GetThisMessageMap(); //获取当前类/基类的映射信息
virtualconstAFX_MSGMAP* GetMessageMap() const; // 得到当前类AFX_MSGMAP指针
BEGIN_MESSAGE_MAP(CDannyFrameWnd, CFrameWnd)
替换如下
constAFX_MSGMAP* CDannyFrameWnd::GetMessageMap() const {
return GetThisMessageMap(); }
constAFX_MSGMAP* PASCALCDannyFrameWnd::GetThisMessageMap()
{
staticconstAFX_MSGMAP_ENTRY _messageEntries[] =
{
END_MESSAGE_MAP替换如下
{ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } //结构体的结束
};
staticconstAFX_MSGMAP messageMap = {
&CFrameWnd::GetThisMessageMap, //父类的结构体指针AFX_MSGMAP
&_messageEntries[0]//数组首地址
}; return &messageMap; }//返回当前messageMap
对这方面感兴趣或者想学习C/C++的可以加群:558502932
//伪代码分析消息映射的调用
AfxWndProc
{
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);//父类指针指向子类对象
ASSERT();//断言—小括号中一定为真
AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
{
pWnd->WindowProc(nMsg, wParam, lParam)//调用的是cwnd的消息处理函数
{
OnWndMsg(message , wParam, lParam, &lResult))//cwnd
{
union MessageMapFunctions mmf;//很多函数的定义
mmf.pfn = 0;
const AFX_MSGMAP* pMessageMap = GetMessageMap();//链表头
for (; pMessageMap->pfnGetBaseMap != NULL;
pMessageMap = (*pMessageMap->pfnGetBaseMap)())
{
if ((lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,
message, 0, 0)) != NULL)//从当前类的数组中获取是否有massgae消息,如果有 的话 直接goto 跳出for如果没找到,继续从父类的数组中查找
mmf.pfn = lpEntry->pfn;
switch (lpEntry->nSig)
{
case AfxSig_l_w_l:
lResult = (this->*mmf.pfn_l_w_l)(wParam, lParam);
}
}
}
}