CView派生自CWnd
CWnd* CFrameWnd::CreateView(CCreateContext* pContext, UINT nID)
{
ASSERT(m_hWnd != NULL);
ASSERT(::IsWindow(m_hWnd));
ASSERT(pContext != NULL);
ASSERT(pContext->m_pNewViewClass != NULL);
// Note: can be a CWnd with PostNcDestroy self cleanup
CWnd* pView = (CWnd*)pContext->m_pNewViewClass->CreateObject();
if (pView == NULL)
{
TRACE1("Warning: Dynamic create of view type %hs failed./n",
pContext->m_pNewViewClass->m_lpszClassName);
return NULL;
}
ASSERT_KINDOF(CWnd, pView);
// views are always created with a border!
if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0,0,0,0), this, nID, pContext))
{
TRACE0("Warning: could not create view for frame./n");
return NULL; // can't continue without a view
}
if (afxData.bWin4 && (pView->GetExStyle() & WS_EX_CLIENTEDGE))
{
// remove the 3d style from the frame, since the view is
// providing it.
// make sure to recalc the non-client area
ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED);
}
return pView;
}
BOOL CWnd::Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd, UINT nID,
CCreateContext* pContext)
{
// can't use for desktop or pop-up windows (use CreateEx instead)
ASSERT(pParentWnd != NULL);
ASSERT((dwStyle & WS_POPUP) == 0);
return CreateEx(0, lpszClassName, lpszWindowName,
dwStyle | WS_CHILD,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(), (HMENU)nID, (LPVOID)pContext);
}
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
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;
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);
#ifdef _DEBUG
if (hWnd == NULL)
{
TRACE1("Warning: Window creation failed: GetLastError returns 0x%8.8X/n",
GetLastError());
}
#endif
if (!AfxUnhookWindowCreate())
PostNcDestroy(); // cleanup if CreateWindowEx fails too soon
if (hWnd == NULL)
return FALSE;
ASSERT(hWnd == m_hWnd); // should have been set in send msg hook
return TRUE;
}
BOOL CView::PreCreateWindow(CREATESTRUCT & cs)
{
ASSERT(cs.style & WS_CHILD);
if (cs.lpszClass == NULL)
{
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
}
if (afxData.bWin4 && (cs.style & WS_BORDER))
{
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
}
return TRUE;
}
对于CView: CView本身也派生自CWnd
由于CreateView或者其他函数会调用CWnd::Create
CWnd::CreateEx
CMyView只要virtual PreCreateWindow
::CreateWindowEx() -> WM_CREATE消息
这样就产生主窗口了
接着View里面要其他特殊的设置,那么virtual OnCreate函数,自然是窗口已经产生了,来产生其他的View中特有的元素,用OnCreate
以上步骤完成后,WM_PAINT
那么 CmyView Virual OnDraw
所以一般自己的View类 Virtual PreCreateWindow(style)和 OnDraw (绘制)函数
如果View里面有些其他的特殊的元素的话,那么去Virtual OnCreate()函数 (初始化View里面的内容,如ImageList ,TreeCtrl)