• 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;
    }

  • 相关阅读:
    javascript/jquery操作cookie
    更改IE/FireFox查看源代码的默认编辑器,比如notepad++
    javascript refresh page 几种页面刷新的方法
    C# Enum,Int,String的互相转换 枚举转换
    js中两个感叹号的作用
    JQuery操作iframe
    JQuery判断一个元素下面是否有内容或者有某个标签
    Meta标签详解
    五一放假回校,真爽
    ASP.NET错误处理(一)摘自MSDN
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6157178.html
Copyright © 2020-2023  润新知