3.2一Wnd窗口基类的设计
来源:互联网 发布:excel2010软件下载 编辑:程序博客网 时间:2024/06/05 09:00
编写面向对象的Windows应用程序并不容易,主要是因为Windows API没有设计为支持面向对象的语言。例如,Windows消息处理函数属于全局函数,该函数中仅仅指明了窗口句柄,但没有指明传入窗口对象指针。同时,C++编译器不允许传入一个普通的成员函数做为回调函数。
我们可以采用一个变通的方法,在回调函数里设置一个虚成员函数,让该虚函数全权处理窗口消息。也就是说,这个虚成员函数成了真正的消息处理函数,之前的回调函数只是一个傀儡。因为C++类的成员函数为每一个函数调用传入一个隐藏的this指针,为实现这一点,回调函数里面需要一个 指向窗口对象的指针。MFC通过一个从HWND到CWnd对象指针的Map映射,把Win32窗口句柄转化为一个指向C++窗口对象的指针。
上述的解决方法是:在窗口创建完成后,将窗口对象指针保存在窗口类所指定的额外窗口数据结构中,然后回调函数从额外窗口数据结构中取出窗口对象指针,调用成员函数。整个流程图如下:SetWindowLong函数
函数功能:将窗口对象的this指针保存到窗口所关联的额外空间。HWND hWnd=::CreateWinodwEx(cs.dwExStyle,cs.lpszClass,cs.lpszName,cs.x,cs.y,cs.cx,cs.cy,cs.hwndParent,cs.hMenu,cs.hInstance,cs.lpCreateParams);assert(hWnd);m_hWnd=hWnd;SetWindowLong(m_hWnd,GWL_USERDATA,(LONG)this);//GWL_USERDATA //获得与窗口有关的32位值。每一个窗口均有一个由创建该窗口的应用程序使用的32位值。函数功能:窗口回调函数从窗口类相关联的额外空间中取出该窗口对象的指针。该对象指针调用一个虚成员函数,将窗口消息路由到WindowProc进行处理。从某种意义上来说,WindowProc成为了WinProc后面的真正执行者。
GetWindowLong
LRESULT CALLBACK QWnd::WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){QWnd* pWnd=(QWnd*)GetWindowLong(hWnd,GWL_USERDATA); //if(pWnd){return pWnd->WindowProc(uMsg,wParam,lParam);}return ::DefWindowProc(hWnd,uMsg,wParam,lParam);}WM_CREATE与WM_NCCREATE消息
调用CreateWindowEx后,会紧着调用SetWindowLong将窗口对象指针保存到窗口句柄所指定的额外地址空间中。但该函数调用过程中会产生WM_CREATE和WM_NCCREATE消息,因为在处理这两个消息的过程中还无法从额外的地址空间中获取窗口对象的指针,so这两个消息还无法处理,所以需要另行处理。this指针的传入
调用CreateWindowEx时,通过产生cs.lpCreateParms将this指针传入
// lpCreateParams 指向将被用于创建窗口的数据的指针
WindowProc消息处理
采用虚函数作为消息响应函数,相对于MFC来说:
优点:逻辑清晰,易懂,不需要再去实现消息映射宏。
缺点:虚函数表中需要记录函数的地址指针,每个函数指针占用4个字节,点用内存大。
0 0
- 3.2一Wnd窗口基类的设计
- 句柄Hwnd 与 窗口Wnd的联系
- MFC 句柄Hwnd 与 窗口Wnd的联系
- Wnd的MouseLeave消息
- 方法论·REVIEW·设计模式&C++&前Wnd
- MSTAR的Applet,ViewMgr(View)和WndMgr(Wnd)等
- 你能想象一个QQ对话窗口用了多少个WND句柄吗?
- 第十五周任务一(窗口设计三角形类)
- 第十五周C++任务一(窗口设计三角形类)
- VC++深入详解 - 窗口的创建 - 设计一个窗口类
- Windows程序设计里的窗口类(一)
- 一、窗口的创建
- 第三讲 窗口设计(一)
- 控制台窗口界面控制设计(一)
- Android应用程序窗口设计框架 一
- PC Camera 开发日志(二十三)------ WND的Z-Order
- 第十五周任务一 用MFC能设计最简单的窗口程序。
- 页面中小窗口的设计
- 【贪心】【noip模拟】皇后游戏
- 强连通分量
- iOS多线程的初步研究(二)-- 锁
- javascript 无缝滚动源码
- Linux 进程通信(System V)管道
- 3.2一Wnd窗口基类的设计
- JS将时间截转成时间格式
- iOS多线程的初步研究(三)-- NSRunLoop
- HDU 1596(find the safest road) 最短路(SPFA&FLOYD&Dijkstra)
- 存储过程(一) 基础语句块、参数、变量
- iOS多线程的初步研究(四)-- NSTimer
- hadoop全分布模式的详细操作
- Linux 进程通信(System V)消息队列
- hdu1864(最大报销额 DP动态规划)