MFC WindowProc AfxWndProc lpfnWndProc
来源:互联网 发布:内网管理软件排名 编辑:程序博客网 时间:2024/06/07 03:16
2010-04-29 11:08
MFC的窗口类(如CWnd)与窗口过程。
Windows是基于事件机制的,任何窗口都能发送和处理消息,每一个窗口都对应着自己的消息处理函数,即通常所说的窗口过程(WindowProc)。窗口过程通常是在WNDCLASSEX的lpfnWndProc变量中指定的,然后调用RegisterClassEx注册窗口类,lpfnWndProc要求是全局的或是类的静态成员,而MFC的窗口和类对象是一一对应的,在类中定义的窗口过程(CWnd::WindowProc)并非类的静态成员,那么窗口消息是怎样传给窗口对象的WindowProc函数去处理的呢?MFC中定义了一个全局的AfxWndProc函数,AfxWndProc是MFC中所有的窗口共用的窗口过程。这里要注意在AfxEndDeferRegisterClass中注册窗口类时并没有把AfxWndProc赋给lpfnWndProc,而是把DefWindowProc赋给了lpfnWndProc。真正把AfxWndProc指定为窗口过程的是在CWnd::CreateEx函数中,CWnd::CreateEx中先后调用了SetWindowsHookEx、CreateWindowEx和UnhookWindowsHookEx,SetWindowsHookEx安装了一个WH_CBT类型的钩子,在调用CreateWindowEx时(在CreateWindowEx返回之前)窗口会发送WM_CREATE、 WM_NCCREATE等消息,钩子过程CBTProc会在窗口消息WM_CREATE、 WM_NCCREATE等发送前被调用,并提前得到窗口的句柄值。钩子过程CBTProc的任务是把窗口句柄赋给窗口对象(CWnd::m_hWnd),并调用SetWindowLong把窗口过程替换成AfxWndProc(如是控件还要保留原窗口过程,用CallWindowProc进行默认处理)。在这有人可能会问,为什么不在AfxEndDeferRegisterClass中直接指定AfxWndProc呢?当然是有原因的:其一是控件的窗口过程必须用SetWindowLong来替换,其二是消息WM_CREATE、 WM_NCCREATE等是在CreateWindowEx返回前发送的,CWnd::WindowProc在处理这些消息时CWnd::m_hWnd必须是已经被初始化的,这个就是由前面的CBTProc完成的。
好现在我们只要关注AfxWndProc了。AfxWndProc是如何把消息分配给各个窗口对象的窗口过程的呢?在MFC中有一个全局的映射表(还没到消息映射,呵呵),这个表是窗口句柄到窗口对象的映射(即通过窗口句柄就能找到窗口对象的地址),找到了窗口对象就可以把消息处理的任务交给CWnd::WindowProc了(调用pWnd- >WindowProc)。
Windows是基于事件机制的,任何窗口都能发送和处理消息,每一个窗口都对应着自己的消息处理函数,即通常所说的窗口过程(WindowProc)。窗口过程通常是在WNDCLASSEX的lpfnWndProc变量中指定的,然后调用RegisterClassEx注册窗口类,lpfnWndProc要求是全局的或是类的静态成员,而MFC的窗口和类对象是一一对应的,在类中定义的窗口过程(CWnd::WindowProc)并非类的静态成员,那么窗口消息是怎样传给窗口对象的WindowProc函数去处理的呢?MFC中定义了一个全局的AfxWndProc函数,AfxWndProc是MFC中所有的窗口共用的窗口过程。这里要注意在AfxEndDeferRegisterClass中注册窗口类时并没有把AfxWndProc赋给lpfnWndProc,而是把DefWindowProc赋给了lpfnWndProc。真正把AfxWndProc指定为窗口过程的是在CWnd::CreateEx函数中,CWnd::CreateEx中先后调用了SetWindowsHookEx、CreateWindowEx和UnhookWindowsHookEx,SetWindowsHookEx安装了一个WH_CBT类型的钩子,在调用CreateWindowEx时(在CreateWindowEx返回之前)窗口会发送WM_CREATE、 WM_NCCREATE等消息,钩子过程CBTProc会在窗口消息WM_CREATE、 WM_NCCREATE等发送前被调用,并提前得到窗口的句柄值。钩子过程CBTProc的任务是把窗口句柄赋给窗口对象(CWnd::m_hWnd),并调用SetWindowLong把窗口过程替换成AfxWndProc(如是控件还要保留原窗口过程,用CallWindowProc进行默认处理)。在这有人可能会问,为什么不在AfxEndDeferRegisterClass中直接指定AfxWndProc呢?当然是有原因的:其一是控件的窗口过程必须用SetWindowLong来替换,其二是消息WM_CREATE、 WM_NCCREATE等是在CreateWindowEx返回前发送的,CWnd::WindowProc在处理这些消息时CWnd::m_hWnd必须是已经被初始化的,这个就是由前面的CBTProc完成的。
好现在我们只要关注AfxWndProc了。AfxWndProc是如何把消息分配给各个窗口对象的窗口过程的呢?在MFC中有一个全局的映射表(还没到消息映射,呵呵),这个表是窗口句柄到窗口对象的映射(即通过窗口句柄就能找到窗口对象的地址),找到了窗口对象就可以把消息处理的任务交给CWnd::WindowProc了(调用pWnd- >WindowProc)。
- MFC WindowProc AfxWndProc lpfnWndProc
- MFC 消息机制 AfxWndProc->AfxCallWndProc->WindowProc->OnWndMsg
- MFC 消息机制 AfxWndProc->AfxCallWndProc->WindowProc->OnWndMsg
- MFC WindowProc
- MFC Windowproc函数
- MFC中的消息处理/AfxWndProc/WM_COMMAND路由
- 为什么MFC的窗口程序都是 AfxWndProc
- WindowProc()
- mfc 通过消息映射调度消息 虚函数 WindowProc
- WindowProc函数
- CWnd::WindowProc
- mainwndproc 、 windowproc与wndproc
- windowproc与defwindowproc
- 重写WindowProc函数
- DefWindowProc WindowProc TranslateMessage PreTranslateMessage
- PreTranslateMessage 和 windowProc
- CWnd::WindowProc的理解
- 谈谈WindowProc的使用
- 2011年Android Binder机制学习笔记之一
- win7下安装rose2003报错:Error 1904. rose.exe failed to register
- poj 2018
- JSDB初体验
- SQL提高性能的方法总结
- MFC WindowProc AfxWndProc lpfnWndProc
- .SVN清理脚本
- poj 3878 zoj 3391 haunted graveyard
- 编译程序出现 undefined reference to `__gxx_personality_v0' 错误
- Linux Server无法启动NaviAgent
- virt-manager进入Xen虚拟机domU的图形界面
- srvctl 命令详解
- 杀掉某一进程的vbs程序
- 设置Xen domU虚拟机网络使其连接外部机器