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这个概念没有多大概念,加上后来小学期的走马观花,以致在日后的生活中寥寥草草,不堪入目,最近,发现身边的人对这个问题不是很懂,故在此深夜写此文章,以望共勉。