如何在MFC單文檔中創(chuàng )建多視圖 2009-03-19 21:16
分類(lèi):VC++字號:
大大
中中 小
基本步驟如下:
1.首先創(chuàng )建一個(gè)MFC單文檔應用程序。
2.添加4個(gè)MFC類(lèi)TopLView、BottomLView、TopRView、BottomRView,基類(lèi)為CView。
3.添加一個(gè)MFC類(lèi)CControlForm,基類(lèi)為CFormView,對話(huà)框ID默認。
4.創(chuàng )建一個(gè)切分類(lèi),如MySplitter,基類(lèi)為CSplitterWnd(默認基類(lèi)選項中無(wú)此類(lèi),自己添加即可)。
5.在框架類(lèi)Cmainframe的頭文件中,添加2個(gè)MySplitter的變量(因為下面要進(jìn)行兩次切分操作)。
6.重寫(xiě)框架類(lèi)Cmainframe的OnCreateClient函數,如下:
//第一次靜態(tài)切分CreateStatic,一行兩列
if (!m_wndSplitter.CreateStatic(this,1,2))
return FALSE;
//第二次靜態(tài)切分(將第一次切分后的第二列再分為2*2)及所有的子視圖創(chuàng )建(CreateView函數)。
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CControlForm), CSize(100, 100), pContext) ||
!m_wndSplitter2.CreateStatic(&m_wndSplitter,2,2,WS_CHILD|WS_VISIBLE,m_wndSplitter.IdFromRowCol(0, 1))|| !m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(TopLView), CSize(350, 240), pContext) ||
!m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(BottomLView), CSize(350, 240), pContext) ||
!m_wndSplitter2.CreateView(0, 1, RUNTIME_CLASS(TopRView), CSize(350, 240), pContext) ||
!m_wndSplitter2.CreateView(1, 1, RUNTIME_CLASS(BottomRView), CSize(350, 240), pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
}
// return CFrameWnd::OnCreateClient(lpcs, pContext); //注釋掉原有的響應函數
注意:記得在Mainfrm.h中添加以上五個(gè)視圖類(lèi)的頭文件:
#include "CControlForm.h"
#include "TopLView.h"
#include "TopRView.h"
#include "BottomLView.h"
#include "BottomRView.h"
6. 切分視圖完成,結果如下:
其中,最左的視圖為FormView類(lèi)型,操作類(lèi)似對話(huà)框(可以在Resource-Dialog看到其對應的對話(huà)框資源);右邊四個(gè)的操作則類(lèi)似普通視圖。
補充內容:
a. 此時(shí)創(chuàng )建的各個(gè)子視圖之間的分割條可以拖動(dòng),以改變視圖其大小。如果想固定分割條,則需要重載MySplitter類(lèi)的鼠標響應函數??梢酝ㄟ^(guò)一個(gè)Bool型變量來(lái)控制是否可以拖動(dòng)分割條:
if (Isvisable) //Isvisable在構造函數中已被初始為FALSE
{
CSplitterWnd::OnLButtonDown(nFlags, point);
}
b. 還可以通過(guò)重載MySplitter類(lèi)的OnDrawSplitter函數來(lái)改變分割條的樣式。以下為該函數代碼:
{
#define LP RGB(128,128,128)
#define RB RGB(192,192,192)
//如果pDC 為 NULL則僅使分割窗口區域無(wú)效
if (pDC == NULL)
{
RedrawWindow(rect, NULL, RDW_INVALIDATE|RDW_NOCHILDREN);
return;
}
ASSERT_VALID(pDC);
CRect rc = rect;
switch(nType)
{
case splitBorder:
//重畫(huà)分割窗口邊界
pDC->Draw3dRect(rc,LP,LP);
rc.InflateRect(-1,-1);
pDC->Draw3dRect(rc,RB,RB);
return;
case splitBox:
pDC->Draw3dRect(rc,LP,LP);
rc.InflateRect(-1,-1);
pDC->Draw3dRect(rc,LP,LP);
rc.InflateRect(-1,-1);
pDC->FillSolidRect(rc,RGB(128,128,128));
pDC->Draw3dRect(rc,RB,RB);
return;
case splitBar:
//重畫(huà)分割條
pDC->FillSolidRect(rc,RGB(192,192,192));
rc.InflateRect(-1,-1);
pDC->Draw3dRect(rc,RB,RB);
return;
default:
ASSERT(FALSE);
}
//填充中間的部分
pDC->Draw3dRect(rect, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
}
注:以上程序在vs2008上調試成功。