MFC中視圖分割是界面開發當中首先要解決的問題,在此做簡單總結。
在此,拿一個工程InfoClt做例:
工程中文件如下:
現在要對主視圖做分割,分割的兩部分分別是InfoCltView、SockView。
分割代碼如下:
MainFrm.h
- <span style="font-size:18px;">#define PanelWidth 310</span>
- <span style="font-size:18px;">...</span>
- <span style="font-size:18px;">BOOL m_bSplitterCreated;
- CSplitterWnd m_Splitter;</span>
- <span style="font-size:18px;">....
- virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
- afx_msg void OnSize(UINT nType, int cx, int cy);</span>
- <span style="font-size:18px;">....
- </span>
MainFrm.cpp
- <span style="font-size:18px;">BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
- {
- if (m_Splitter.CreateStatic(this,1,2))
- {
- CSize size;
- CRect cltRect;
- GetClientRect(cltRect);
- size.cx=cltRect.Width()-PanelWidth;
- size.cy=0;
- if (!m_Splitter.CreateView(0,0,RUNTIME_CLASS(CInfoCltView),
- size,pContext)) return FALSE;
- size.cx=0;
- size.cy=0;
- if (!m_Splitter.CreateView(0,1,RUNTIME_CLASS(CSockView),
- size,pContext)) return FALSE;
- else SetActiveView((CView*)m_Splitter.GetPane(0,0));
- }
- m_bSplitterCreated=TRUE;
- return(TRUE);
- // return CFrameWnd::OnCreateClient(lpcs, pContext);
- } //End of OnCreateClient
- void CMainFrame::OnSize(UINT nType, int cx, int cy)
- {
- CFrameWnd::OnSize(nType, cx, cy);
- int firstColWd;
- RECT cltRect;
- GetClientRect(&cltRect);
- firstColWd=cltRect.right-cltRect.left-PanelWidth;
- if (firstColWd<0) firstColWd=0;
- if( m_bSplitterCreated ) //Splitter Created
- {
- m_Splitter.SetColumnInfo(0,firstColWd,firstColWd);
- m_Splitter.RecalcLayout();
- }
- } //End of OnSize</span>
視圖InfoCltView和視圖SockView之間的消息傳遞如下:
InfoCltView.h
- <span style="font-size:18px;">// Attributes
- public:
- CInfoCltDoc* GetDocument() const;
- // Operations
- public:
- void RedrawCurrentView(void);</span>
InfoCltView.cpp
- <span style="font-size:18px;">CInfoCltDoc* CInfoCltView::GetDocument() const // non-debug version is inline
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CInfoCltDoc)));
- return (CInfoCltDoc*)m_pDocument;
- }
- #endif //_DEBUG
- // CInfoCltView message handlers
- void CInfoCltView::RedrawCurrentView(void)
- {
- CDC *pDC=GetDC();
- pDC->TextOut(100,100,TEXT("Hello, TCP/IP"));
- ReleaseDC(pDC);
- } //End of RedrawCurrentView</span>
SockView.h
- <span style="font-size:18px;">public:
- CInfoCltDoc* GetDocument() const;</span>
SockView.cpp
- <span style="font-size:18px;">CInfoCltDoc* CSockView::GetDocument() const // 非調試版本是內聯的
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CInfoCltDoc)));
- return (CInfoCltDoc*)m_pDocument;
- }
- #endif //_DEBUG
- // CSockView message handlers
- void CSockView::OnBnClickedButton1()
- {
- // TODO: Add your control notification handler code here
- CInfoCltDoc *pDC=GetDocument();
- pDC->GetInfoCltView()->RedrawCurrentView();
- }</span>
InfoCltDoc.h
- <span style="font-size:18px;">// Operations
- public:
- CInfoCltView* GetInfoCltView(void);
- CSockView* GetSockView(void);</span>
InfoCltDoc.cpp
- <span style="font-size:18px;">// CInfoCltDoc commands
- CInfoCltView* CInfoCltDoc::GetInfoCltView(void)
- {
- for(POSITION pos=GetFirstViewPosition();pos!=NULL;)
- {
- CView* pView = GetNextView(pos);
- if (pView->IsKindOf(RUNTIME_CLASS(CInfoCltView)))
- return ((CInfoCltView*)pView);
- } //End of for pos
- return NULL;
- } //End of GetInfoCltView
- CSockView* CInfoCltDoc::GetSockView(void)
- {
- for(POSITION pos=GetFirstViewPosition();pos!=NULL;)
- {
- CView* pView = GetNextView(pos);
- if (pView->IsKindOf(RUNTIME_CLASS(CSockView)))
- return ((CSockView*)pView);
- } //End of for pos
- return NULL;
- } //End of GetSockView</span>
總的生成界面如下:
其中InfoCltView和SockView之間的信息交換用上述代碼中的“連接”按鈕來實現,預期效果應該是單擊連接時候在InfoCltView中顯示
RedrawCurrentView(void)函數內容“Hello, TCP/IP”。實際結果如下:
最後對InfoCltView視圖和SockView視圖的Document部分做下說明,如下圖:
這兩個視圖都是與InfoCltDoc做交互,通過InfoCltDoc獲得或發送消息給對方。
小結:雖然從大二就開始學習C++,但剛開始的時候對MFC這個概念沒有多大概念,加上後來小學期的走馬觀花,以致在日後的生活中寥寥草草,不堪入目,最近,發現身邊的人對這個問題不是很懂,故在此深夜寫此文章,以望共勉。