MFC窗口的创建过程详细解析
关于MFC的窗口创建过程一直感觉比较神秘,那么我们来看下MFC中的窗口创建到底是一个什么过程(窗口创建前的窗口类准备就直接忽略了,与标准Win32窗口类准备大同小异)。MFC中窗口创建主要涉及三个重要的函数,分别是CWnd::CreateEx(或者CWnd::Create)、AfxHookWindowCreate、AfxCbtFilterHook函数,首先是大概介绍下MFC的窗口创建过程,当CWnd::CreateEx被调用时,CWnd::CreateEx在调用API函数::CreateWindowEx创建窗口前会通过调用AfxHookWindowCreate安装一个名为_AfxCbtFilterHook的线程钩子,并将需要创建的窗口的CWnd指针保存到线程状态结构中,在API函数::CreateWindowEx真正创建窗口前AfxCbtFilterHook会被调用,AfxCbtFilterHook会执行子类化操作,把要创建的窗口的窗口过程子类化为线程状态结构中的窗口过程(AfxGetModuleState()->m_pfnAfxWndProc),即MFC的标准窗口过程,这样MFC的窗口(CWnd及其派生类)都可以通过消息映射机制接收和响应包括从创建开始的各种各样的消息。(关于AfxCbtFilterHook可以参考MSDN中关于SetWindowsHookEx的解释。)
1. CWnd::CreateEx
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
{
// allow modification of several common create parameters
准备一个结构给PreCreateWindow函数使用,这样就允许应用程序在创建窗口前修改窗口创建参数,比如给cs.lpszClass重新指定一个窗口类给CreateWindow函数。
CREATESTRUCT cs;
cs.dwExStyle = dwExStyle;
cs.lpszClass = lpszClassName;
cs.lpszName = lpszWindowName;
cs.style = dwStyle;
cs.x = x;
cs.y = y;
cs.cx = nWidth;
cs.cy = nHeight;
cs.hwndParent = hWndParent;
cs.hMenu = nIDorHMenu;
cs.hInstance = AfxGetInstanceHandle();
cs.lpCreateParams = lpParam;
//