使用SDK实现MFC模式的处理方法(一)
一.起子
没有,想用SDK而已, 程序看的清爽. 讨厌mfc许多麻烦的代码.有时候明明很简单,却只好用mfc,不爽.
二.构想
如果你尝试模仿mfc, 你就会发现似乎有一道过不去的坎, 你想实现自己的CWnd, CDialog, 可是发现很难实现复用. 因为你的"CWnd,CDialog"似乎必须要有一个尾巴, 这个尾巴就是WndProc, 一个被要求是__stdcall 的函数.
假设,你实现了你的基类: CMyWindow, 然后你的程序中有两个窗口: CPigWnd 和 CWolfWnd. 你如何使用一个WndProc来处理两个窗口? 你的基类设计也已经失败了.
实际上,mfc使用了一种 很麻烦的技术实现如何让每一个类只与一个窗口句柄想关联, 而mfc只有一个WndProc,叫什么AfxWndProc之类的, 在这个AfxWndProc中, 他会检查 HWND hwnd 参数, 然后通过 FromHandle() ,使hwnd 转换为CWnd, 然后才调用CWnd类的消息处理函数. 这个是非常麻烦的过程, 想想看MFC把hwnd都存在一个表格中, 然后需要的时候通过HashTable来定位. 从这点看,不得不说SDK的实现非常优雅,准确的说,很纯洁.
其实在::CreateWindowEx 中有一个 LPVOID lpParam参数,允许用户传递一个值和hwnd捆绑起来, 许多人就这样实现了捆绑.如果真的那么完美就好了, 可问题是这个参数只在WM_CREATE消息时才传递出来, 也就是说只有在这个时候CMyWindow才有机会和句柄绑定, 可是在WM_CREATE之前的消息对于CMyWindow来说都不可见(尽管这些消息也许并不重要,可是最为一个基类,这样的缺陷还是致命的)
怎么办? 如果有一个WndProc能有一个this指针,指向各自的类,那该有多好啊~
这是一个称为动态函数的技术,
1.我们事先制造一个WndProc的模板,里面有一个叫pThis的指针,他有一个特征值.
2.CMyWindow在构造时, 复制WndProc的模板, 然后把pThis的值,改写成CMyWindow实例的this指针.
3.在CreateWindow时, WNDPROC 就使用CMyWindow的WndProc.
通过这几步, 很完满的实现了句柄与类的绑定, 相信也比MFC的实现清晰许多,(我一直觉得,MFC是M$的技术人员卖弄技术的产品)