zz
prog 2007-05-20 23:45:16 閱讀16 評論0 字型大小:大中小 訂閱
最近想做一個視窗分割的東西,在網上找了一些資料,終於“比葫蘆 畫瓢”地做了一個稍微看得過去的。現將過程記錄上來以便以後查看,也讓大家分享。主要參考了http://www.czvc.com/view.asp?id=334,這是一個相當不錯的網站,本文並非完全照搬,對編譯過程中存在的錯誤進行了改正,也對自己之前看到的其他資料以及上文中存在的問題進行了重點說明,這也是我在初學過程中易犯的錯誤。
介面內共含有一個架構和五個視窗,視窗Left、視窗 Right、視窗Zoom、視窗Control和視窗 Info。視窗Left、 Right和 Zoom的基類都是CView;視窗Control和視窗Info窗都從CFormView派生出來。
為了實現上述功能,首先用AppWizard產生一單文檔應用程式,並自訂產生的預設視類為CZoomView 接下來,通過如下步驟,建立另外四個視窗:
1、用ClassWizard為應用程式建立一個新類CFixedSplitter,基類為CMDIChildWnd,然後在該類中將所有 CMDIChildWnd的地方替換為CsplitterWnd(因為ClassWizard不支援直接從CsplitterWnd類派生子類);
由CMDIChildWnd派生的新類CFixedSplitter裡邊的建構函式和解構函式都是保護成員,應在標頭檔中改為public,否則在CMainFrame構造時要出錯。
2、在CMainFrame類裡聲明分割視圖的變數:
CFixedSplitter SplitterH1; file://水平分割視窗1
CFixedSplitter SplitterH2; file://水平分割視窗2
CFixedSplitter SplitterV; file://垂直分割視窗
3、用ClassWizard為應用程式添加四個新類,其中CLeftView和CrightView從Cview類派生,CControlView和 CinfoView從CFormView類中派生;用資源管理員為兩個CFormView類指定相應的對話方塊資源;注意這裡一定要通過互動操作將兩對話方塊的風格(屬性)設定為WS_CHILD=On,WS_BORDER=Off,WS_VISIBLE=Off,WS_CAPTION=Off,即無標題、無邊框、不可見的子視窗,如果這項工作沒有作,編譯時間雖然能夠通過,但運行時將會出現斷言ASSERT錯誤;
4、在CMainFrame類的OnCreateClient函數中添加代碼,建立分割視圖
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
BOOL rtn=SplitterV.CreateStatic(this,1,2); //首先將視窗客戶區分割為一行兩列;
//將左客戶區再分割為三行一列,並以上面分割的左視窗作為父視窗;
SplitterH1.CreateStatic(&SplitterV, 3, 1, WS_CHILD | WS_VISIBLE | WS_BORDER, SplitterV.IdFromRowCol(0,0));
//將右客戶區再分割為兩行一列,並以上面分割的右視窗作為父視窗;
SplitterH2.CreateStatic(&SplitterV, 2, 1, WS_CHILD | WS_VISIBLE | WS_BORDER, SplitterV.IdFromRowCol(0,1));
//建立各自視圖,並調用RUNTIME_CLASS運行庫指定各視圖的管理類
SplitterH1.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(0, 0), pContext);
SplitterH1.CreateView(1, 0, RUNTIME_CLASS(CRightView), CSize(0, 0), pContext);
SplitterH1.CreateView(2, 0, RUNTIME_CLASS(CControlView), CSize(0,0), pContext);
SplitterH2.CreateView(0, 0, RUNTIME_CLASS(CZOOMView), CSize(0, 0), pContext);
//在ZOOMView.h中要加上#include "ZOOMDoc.h",否則會出現一個找不到CZOOMDoc*的錯誤
SplitterH2.CreateView(1, 0, RUNTIME_CLASS(CInfoView), CSize(0, 0), pContext);
//設定水平和垂直分割條的初始位置
SplitterV.SetColumnInfo(0,300,0);
SplitterH1.SetRowInfo(0,150,0);
SplitterH1.SetRowInfo(1,150,0);
SplitterH2.SetRowInfo(0,200,0);
return rtn; }
這樣編譯運行後,程式的介面基本上就有了模樣。但是當滑鼠移動到分割條位置始,滑鼠的形狀將會發生變化,呈現出拖動狀態的表徵圖,當按下滑鼠左鍵並進行拖動操作時,分割條的位置將隨滑鼠的移動發生變化。如果程式需要禁止分割條的移動操作,那麼還需要繼續以下操作:
在CfixedSplitteWnd類中重載以下函數,以禁止滑鼠拖動和游標變化:
void CFixedSplitterWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
CWnd::OnLButtonDown(nFlags, point); //最後修改成CWnd的函數
}
BOOL CFixedSplitterWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
return CWnd::OnSetCursor(pWnd, nHitTest, message);
}
void CFixedSplitterWnd::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd::OnMouseMove(nFlags, point);
}
接下來就可以象在多文檔重疊的視窗一樣,管理自己的各自視圖,每個視圖可以分別顯示各自的文檔內容,非常方便。 本程式在WindowsXP下Visual C++6.0環境中調試通