MFC中視圖分割(靜態分割和動態分割)和視圖間消息傳遞

MFC中視圖分割是界面開發當中首先要解決的問題,在此做簡單總結。

在此,拿一個工程InfoClt做例:

工程中文件如下:

現在要對主視圖做分割,分割的兩部分分別是InfoCltView、SockView。

分割代碼如下:

MainFrm.h

[html] view plaincopy
  1. <span style="font-size:18px;">#define PanelWidth 310</span>  
[html] view plaincopy
  1. <span style="font-size:18px;">...</span>  
[html] view plaincopy
  1. <span style="font-size:18px;">BOOL m_bSplitterCreated;  
  2. CSplitterWnd m_Splitter;</span>  
[html] view plaincopy
  1. <span style="font-size:18px;">....  
  2. virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);  
  3. afx_msg void OnSize(UINT nType, int cx, int cy);</span>  
[html] view plaincopy
  1. <span style="font-size:18px;">....  
  2. </span>  

MainFrm.cpp

[html] view plaincopy
  1. <span style="font-size:18px;">BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)  
  2. {  
  3.     if (m_Splitter.CreateStatic(this,1,2))  
  4.     {  
  5.         CSize size;  
  6.         CRect cltRect;  
  7.         GetClientRect(cltRect);  
  8.         size.cx=cltRect.Width()-PanelWidth;  
  9.         size.cy=0;  
  10.         if (!m_Splitter.CreateView(0,0,RUNTIME_CLASS(CInfoCltView),  
  11.             size,pContext)) return FALSE;  
  12.         size.cx=0;  
  13.         size.cy=0;  
  14.         if (!m_Splitter.CreateView(0,1,RUNTIME_CLASS(CSockView),  
  15.             size,pContext)) return FALSE;  
  16.         else SetActiveView((CView*)m_Splitter.GetPane(0,0));  
  17.     }  
  18.     m_bSplitterCreated=TRUE;  
  19.     return(TRUE);  
  20. //  return CFrameWnd::OnCreateClient(lpcs, pContext);  
  21. } //End of OnCreateClient  
  22.   
  23. void CMainFrame::OnSize(UINT nType, int cx, int cy)  
  24. {  
  25.     CFrameWnd::OnSize(nType, cx, cy);  
  26.     int firstColWd;  
  27.     RECT cltRect;  
  28.     GetClientRect(&cltRect);  
  29.     firstColWd=cltRect.right-cltRect.left-PanelWidth;  
  30.     if (firstColWd<0firstColWd=0;  
  31.     if( m_bSplitterCreated )  //Splitter Created  
  32.     {  
  33.         m_Splitter.SetColumnInfo(0,firstColWd,firstColWd);  
  34.         m_Splitter.RecalcLayout();  
  35.     }  
  36. } //End of OnSize</span>  

視圖InfoCltView和視圖SockView之間的消息傳遞如下:

InfoCltView.h

[html] view plaincopy
  1. <span style="font-size:18px;">// Attributes  
  2. public:  
  3.     CInfoCltDoc* GetDocument() const;  
  4.   
  5. // Operations  
  6. public:  
  7.     void RedrawCurrentView(void);</span>  

InfoCltView.cpp

[html] view plaincopy
  1. <span style="font-size:18px;">CInfoCltDoc* CInfoCltView::GetDocument() const // non-debug version is inline  
  2. {  
  3.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CInfoCltDoc)));  
  4.     return (CInfoCltDoc*)m_pDocument;  
  5. }  
  6. #endif //_DEBUG  
  7.   
  8.   
  9. // CInfoCltView message handlers  
  10. void CInfoCltView::RedrawCurrentView(void)  
  11. {  
  12.     CDC *pDC=GetDC();  
  13.     pDC->TextOut(100,100,TEXT("Hello, TCP/IP"));  
  14.     ReleaseDC(pDC);  
  15. } //End of RedrawCurrentView</span>  

SockView.h

[html] view plaincopy
  1. <span style="font-size:18px;">public:  
  2.     CInfoCltDoc* GetDocument() const;</span>  

SockView.cpp

[html] view plaincopy
  1. <span style="font-size:18px;">CInfoCltDoc* CSockView::GetDocument() const // 非調試版本是內聯的  
  2. {  
  3.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CInfoCltDoc)));  
  4.     return (CInfoCltDoc*)m_pDocument;  
  5. }  
  6. #endif //_DEBUG  
  7.   
  8.   
  9. // CSockView message handlers  
  10.   
  11.   
  12. void CSockView::OnBnClickedButton1()  
  13. {  
  14.     // TODO: Add your control notification handler code here  
  15.     CInfoCltDoc *pDC=GetDocument();  
  16.     pDC->GetInfoCltView()->RedrawCurrentView();  
  17. }</span>  

InfoCltDoc.h

[html] view plaincopy
  1. <span style="font-size:18px;">// Operations  
  2. public:  
  3.     CInfoCltView* GetInfoCltView(void);  
  4.     CSockView* GetSockView(void);</span>  

InfoCltDoc.cpp

[html] view plaincopy
  1. <span style="font-size:18px;">// CInfoCltDoc commands  
  2. CInfoCltView* CInfoCltDoc::GetInfoCltView(void)  
  3. {  
  4.     for(POSITION pos=GetFirstViewPosition();pos!=NULL;)  
  5.     {  
  6.         CView* pView = GetNextView(pos);  
  7.         if (pView->IsKindOf(RUNTIME_CLASS(CInfoCltView)))  
  8.             return ((CInfoCltView*)pView);  
  9.     } //End of for pos  
  10.     return NULL;  
  11. } //End of GetInfoCltView  
  12.   
  13. CSockView* CInfoCltDoc::GetSockView(void)  
  14. {  
  15.     for(POSITION pos=GetFirstViewPosition();pos!=NULL;)  
  16.     {  
  17.         CView* pView = GetNextView(pos);  
  18.         if (pView->IsKindOf(RUNTIME_CLASS(CSockView)))  
  19.             return ((CSockView*)pView);  
  20.     } //End of for pos  
  21.     return NULL;  
  22. } //End of GetSockView</span>  

總的生成界面如下:


其中InfoCltView和SockView之間的信息交換用上述代碼中的“連接”按鈕來實現,預期效果應該是單擊連接時候在InfoCltView中顯示

RedrawCurrentView(void)函數內容“Hello, TCP/IP”。實際結果如下:

最後對InfoCltView視圖和SockView視圖的Document部分做下說明,如下圖:


這兩個視圖都是與InfoCltDoc做交互,通過InfoCltDoc獲得或發送消息給對方。

小結:雖然從大二就開始學習C++,但剛開始的時候對MFC這個概念沒有多大概念,加上後來小學期的走馬觀花,以致在日後的生活中寥寥草草,不堪入目,最近,發現身邊的人對這個問題不是很懂,故在此深夜寫此文章,以望共勉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章