C++--CSplitterWnd::CreateView创建CListView创建过程的调试摘抄
一、调用过程
1 Call CObject* CRuntimeClass::CreateObject()
1.1 Call CObject::operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
1.2 Call CCtrlView::CCtrlView(LPCTSTR lpszClass, DWORD dwStyle)
1.2.1 CCtrlView::CCtrlView(LPCTSTR lpszClass, DWORD dwStyle)
1.2.1.1..........
1.2.2 Call CCtrlView::CCtrlView(LPCTSTR lpszClass, DWORD dwStyle)'code
2 DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER;
Call pWnd->Create(NULL, NULL, dwStyle,rect, this, IdFromRowCol(row, col), pContext)
2.1 CWnd::CreateEx
2.1.1 构造默认CREATESTRUCT cs
2.1.2 BOOL CListView::PreCreateWindow(CREATESTRUCT& cs)
2.1.2.1 BOOL CCtrlView::PreCreateWindow(CREATESTRUCT& cs)
2.1.2.1.1 cs.lpszClass = "SysListView32"
if ((cs.style | WS_BORDER) == AFX_WS_DEFAULT_VIEW)
cs.style = m_dwDefaultStyle & (cs.style | ~WS_BORDER);
2.1.2.1.2 return CView::PreCreateWindow(cs);
2.1.3 call CreateWindowEx API
2.1.3.1 Before returning, CreateWindow sends a WM_CREATE message to the window procedure,
CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
2.1.3.1.1// allow other subclassing to occur first
pWndInit->PreSubclassWindow();
2.1.3.1.2 根据消息映射调用int CListView::OnCreate(LPCREATESTRUCT lpcs)
二、CreateView代码摘抄
/////////////////////////////////////////////////////////////////////////////
// CSplitterWnd default creation of parts
// You must create ALL panes unless DYNAMIC_SPLIT is defined!
// Usually the splitter window is invisible when creating a pane
BOOL CSplitterWnd::CreateView(int row, int col,
CRuntimeClass* pViewClass, SIZE sizeInit, CCreateContext* pContext)
{
#ifdef _DEBUG
ASSERT_VALID(this);
ASSERT(row >= 0 && row < m_nRows);
ASSERT(col >= 0 && col < m_nCols);
ASSERT(pViewClass != NULL);
ASSERT(pViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd)));
ASSERT(AfxIsValidAddress(pViewClass, sizeof(CRuntimeClass), FALSE));
if (GetDlgItem(IdFromRowCol(row, col)) != NULL)
{
TRACE(traceAppMsg, 0, "Error: CreateView - pane already exists for row %d, col %d./n",
row, col);
ASSERT(FALSE);
return FALSE;
}
#endif
// set the initial size for that pane
m_pColInfo[col].nIdealSize = sizeInit.cx;
m_pRowInfo[row].nIdealSize = sizeInit.cy;
BOOL bSendInitialUpdate = FALSE;
CCreateContext contextT;
if (pContext == NULL)
{
// if no context specified, generate one from the currently selected
// client if possible
CView* pOldView = (CView*)GetActivePane();
if (pOldView != NULL && pOldView->IsKindOf(RUNTIME_CLASS(CView)))
{
// set info about last pane
ASSERT(contextT.m_pCurrentFrame == NULL);
contextT.m_pLastView = pOldView;
contextT.m_pCurrentDoc = pOldView->GetDocument();
if (contextT.m_pCurrentDoc != NULL)
contextT.m_pNewDocTemplate =
contextT.m_pCurrentDoc->GetDocTemplate();
}
pContext = &contextT;
bSendInitialUpdate = TRUE;
}
CWnd* pWnd;
TRY
{
pWnd = (CWnd*)pViewClass->CreateObject();
if (pWnd == NULL)
AfxThrowMemoryException();
}
CATCH_ALL(e)
{
TRACE(traceAppMsg, 0, "Out of memory creating a splitter pane./n");
// Note: DELETE_EXCEPTION(e) not required
return FALSE;
}
END_CATCH_ALL
ASSERT_KINDOF(CWnd, pWnd);
ASSERT(pWnd->m_hWnd == NULL); // not yet created
DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER;
// Create with the right size (wrong position)
CRect rect(CPoint(0,0), sizeInit);
if (!pWnd->Create(NULL, NULL, dwStyle,
rect, this, IdFromRowCol(row, col), pContext))
{
TRACE(traceAppMsg, 0, "Warning: couldn't create client pane for splitter./n");
// pWnd will be cleaned up by PostNcDestroy
return FALSE;
}
ASSERT((int)_AfxGetDlgCtrlID(pWnd->m_hWnd) == IdFromRowCol(row, col));
// send initial notification message
if (bSendInitialUpdate)
pWnd->SendMessage(WM_INITIALUPDATE);
return TRUE;
}
三、其他相关代码摘抄
CObject* CRuntimeClass::CreateObject()
{
ENSURE(this);
if (m_pfnCreateObject == NULL)
{
TRACE(traceAppMsg, 0,
_T("Error: Trying to create object which is not ")
_T("DECLARE_DYNCREATE /nor DECLARE_SERIAL: %hs./n"),
m_lpszClassName);
return NULL;
}
CObject* pObject = NULL;
TRY
{
pObject = (*m_pfnCreateObject)();//Call New Operator and Constructor
}
END_TRY
return pObject;
}
CObject::operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
{
return ::operator new(nSize, _AFX_CLIENT_BLOCK, lpszFileName, nLine);
}
_AFXCVIEW_INLINE CListView::CListView() : CCtrlView(WC_LISTVIEW,
AFX_WS_DEFAULT_VIEW)
{ }
CCtrlView::CCtrlView(LPCTSTR lpszClass, DWORD dwStyle)
{
m_strClass = lpszClass;
m_dwDefaultStyle = dwStyle;
}