44 VC++实现消息映射 - 雪炭网

VC++实现消息映射2015-02-05 14:28:40

( 还没有投票,继续加油! )
分享:
31.3K

VC++开发过程中,大家都会不可避免的遇到消息映射。对于像C++这样面向对象的编程语言,VC++中为何如此实现消息映射呢?

下面我们先来搞清楚Windows消息处理的逻辑处理:

一般来说一个包含了消息处理的Windows程序至少要包含两个函数

第一个:

int WINAPI WinMain(
 HINSTANCE hInstance,  // handle to current instance
 HINSTANCEhPrevInstance, // handle to previousinstance
 LPSTR lpCmdLine,   // command line
 int nCmdShow   // show state
);

第二个:

long FAR PASCAL WndProc(HWNDhWnd,WORD message,WORD wParam,LONG lParam);

我们不必纠缠程序实现的细节,只要明白在第一个函数WinMain中要注册WndProc函数,通俗一些的理解就是WinMain告诉Windows系统,听着,我知道你要产生很多消息,我这里有一个WndProc函数负责处理你传递来的各种消息。当然消息的格式都是系统规定好的。

其次要明白C++中是如何实现多态性的。

我们知道多态性实现的关键是晚绑定(或者称为后期绑定),其实质就是编译器并没有在编译期间指定调用函数的绝对地址,而是指定了某个类内部该函数的偏移地址。

为了实现上面的功能,编译器为我们作了手脚

1在每个带有虚函数的类中,编译器秘密放置了一个指针,称为Vpointer

2当系统运行时,为每个类创建一个VTABLE,其中包含了可以调用虚函数地址。

3  Vpointer出始化,指向VTABLE,通过在Vtable中偏移,来找到正确的需要调用的函数地址。


然后是MFCWindow API进行的封装

当我们利用MFC框架开发程序的时候,尤其是开发界面应用程序的时候,必定要用到CWnd或者派生于CWnd的类。根据面向对象的设计原则,对于CWnd的一些通用函数,例如窗口大学改变(OnSize,窗口移动(OnMove),最好是在CWnd中声明为虚函数,然后在继承的类里面重载他们。但是,这样以来,每个相关的派生类都要有一个Vpointer和一套记录Vtable,CWnd中通用函数是如此至多,CWnd的派生类也很多,必然会导致系统在运行是占用过多的资源(内存),这样显然是不合适的。

那么MFC是如何实现的呢?

答案就是在CWnd基类中尽可能的少用虚函数,采用消息映射机制来代替。

大家可以看一下CWnd的类中的函数,就会发现这一点。

CWnd::OnMove
afx_msg void OnMove( int x, int y );

上面这个函数就不是虚函数。

最后的问题消息映射是如何实现的呢?

用一句话说,就是利用宏定义来实现面向过程的消息处理。

例如在VC中有如下的消息映射宏。

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_COMMAND(ID_FONT_DROPDOWN, DoNothing)
END_MESSAGE_MAP()

经过编译后,代码被替换为如下形式(这只是作讲解,实际情况比这复杂得多):

//BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
CMainFrame::newWndProc(...)
{
switch(...)
{
//{{AFX_MSG_MAP(CMainFrame)
// ON_WM_CREATE()
case(WM_CREATE):
OnCreate(...);
break;
//}}AFX_MSG_MAP
// ON_COMMAND(ID_FONT_DROPDOWN, DoNothing)
case(WM_COMMAND):
if(HIWORD(wP)==ID_FONT_DROPDOWN)
{
DoNothing(...);
}
break;
//END_MESSAGE_MAP()
}
}


如此处理,VC++就消除了对部分虚拟函数的依赖,从而节省掉了内存空间的分配。







头像

snowcoal
  • 编程语言
  • VC++
  • 消息映射

收藏到我的私密空间

标题:VC++实现消息映射

作者:柳岸花明

你暂未登录,请登录后才可收藏至您的私密空间 确认取消
雪炭网

键盘操作 更便捷 -雪炭网雪中送炭-乐趣无限

如果本站的内容有幸帮助到了您,建议您了解一下当页的广告内容哦,我们的进步离不开您的支持,Thank you~