mfc窗口注册、创建
!pThread->InitInstance()中只是
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();中进行了显示窗口及更新窗口,而注册窗口类和创建窗口是在哪里进行的? 展开
首先从CXXXApp::InitInstance调用LoadFrame
BOOL CMyApp::InitInstance()
{
// ......
// 创建主 MDI 框架窗口
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
// ......
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// 调度在命令行中指定的命令。如果
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
if (!ProcessShellCommand(cmdInfo)) return FALSE;
}
LoadFrame是虚函数,没有被重写,所以调用CMDIFrameWnd::LoadFrame
BOOL CMDIFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
CWnd* pParentWnd, CCreateContext* pContext)
{
if (!CFrameWnd::LoadFrame(nIDResource, dwDefaultStyle,
pParentWnd, pContext))
return FALSE;
继续调用CFrameWnd::LoadFrame
BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
CWnd* pParentWnd, CCreateContext* pContext)
{
//。。。
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
// 。。。
if (!Create(lpszClass, strTitle, dwDefaultStyle, rectDefault,
pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext))
{
这里能看到 AfxDeferRegisterClass 和 Create
这里的Create调用了CFrameWnd::Create,其他的Create还有CMDIChildWnd和CWnd的
里面调用到CreateEx,CreateEx几乎没有被重写,调用的是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)
{
//。。。
if (!PreCreateWindow(cs))
{
PostNcDestroy();
return FALSE;
}
AfxHookWindowCreate(this);
HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
接着调用PreCreateWindow后就是用CreateWindowEx创建窗口
BOOL CMDIFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.lpszClass == NULL)
{
VERIFY(AfxDeferRegisterClass(AFX_WNDMDIFRAME_REG));
cs.lpszClass = _afxWndMDIFrame;
}
return TRUE;
}
这里也有个AfxDeferRegisterClass,它被宏替换后是AfxEndDeferRegisterClass,里面就是注册窗口类的代码
其他类型的窗口也类似,就算LoadFrame没有的话,PreCreateWindow也会调用注册
另外如果是单文档的话,没有主框架,靠的是InitInstance里的ProcessShellCommand
cmdInfo构造时默认是FileNew
BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)
{
BOOL bResult = TRUE;
switch (rCmdInfo.m_nShellCommand)
{
case CCommandLineInfo::FileNew:
if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
OnFileNew();
这里发送ID_FILE_NEW,就算失败也手动调用OnFileNew
之后就也是创建窗口
建议你装vs2003或以后版本,用 转到定义 检查代码就很容易看到了,vc6之前的版本可能有时不太好用
另外对于MFC建议你弄本《深入浅出MFC》看看
你可以看看BEGIN_MESSAGE_MAP的宏定义,及CWnd所提供的函数接口。
求详细!!
详细点的都在MSDN上面,这个英文片段阐述了,CWnd如何利用AfxRegisterWndClass来注册窗口类、
The attributes of a CWnd object, like anHWND handle in Windows, are stored in two places: the window object and theWNDCLASS. The name of the WNDCLASS is passed to general window creation functionssuch as CWnd::Create and CFrameWnd::Create in the lpszClassName parameter.
This WNDCLASS must be registered throughone of four means:
Implicitly by using a MFC providedWNDCLASS.
Implicitly by subclassing a Windows control(or some other control).
Explicitly by calling the MFC AfxRegisterWndClass or AfxRegisterClass.
Explicitly by calling the Windows routineRegisterClass.