當使用者需要同時對文當的不同部分進行編輯時,常常會用到切分視窗;這些視窗可以都是相同的視,或者乙個視窗為列表視,而另乙個為樹型檢視。應用程式框架有多種方式來表示多檢視,切分視窗是其中的方式之一。
一、引用
當使用者需要同時對文當的不同部分進行編輯時,常常會用到切分視窗;這些視窗可以都是相同的視,或者乙個視窗為列表視,而另乙個為樹型檢視。應用程式框架有多種方式來表示多檢視,切分視窗是其中的方式之一。
切分視窗分為動態切分視窗和靜態切分視窗,它們都是由csplitterwnd類(mfc類庫)來實現的,在這兩種表示方式中,建立同一檢視類的物件是比較容易的(cview),而在同一應用程式使用兩個或更多的檢視類(如:clistview、ctreeview等),相對來說則要困難一些。
動態切分功能多應用在編輯文字類的軟體中,在實際的開發中,我們經常要用到的是靜態切分功能。靜態切分視窗是指在視窗建立時,切分視窗的窗格就已經建立好了,且窗格的數量和順序不會改變,窗格為乙個分隔條所分隔,使用者可以拖動分隔條調整相應窗格的大小。靜態切分視窗最多支援16行´16列的窗格,而且不同的窗格往往使用不同的檢視類。本文主要闡述靜態切分視窗。
二、例項
以單文件sdi應用程式為例,在框架客戶區實現三叉切分視窗,且每個窗格使用不同的檢視 。
實現步驟:
2、 使用new class對話方塊新增新的檢視類:
cinfoview 基類為列表檢視類clistview
clineview 基類為表單檢視類cformview
cmyeditview 基類為編輯檢視類ceditview
要點:在新增clineview之前,需要先建立乙個對話模板資源,id為idd_formview,
3、 在框架視窗類cmainframe中宣告乙個csplitterwnd類的成員變數m_wndsplitter1,用於第一次切分。
4、 使用classwizard為框架視窗類新增oncreateclient函式。
注意:oncreateclient函式的呼叫在oncreate函式之後,在構造檢視物件和產生檢視視窗之前。
5、 在oncreateclient函式中呼叫csplitterwnd::createstatic,產生靜態切分。該函式的原形如下:
bool createstatic( cwnd* pparentwnd, int nrows, int ncols, dword dwstyle =
ws_child | ws_visible, uint nid = afx_idw_pane_first );
函式有5個引數,意義如下:
● pparentwnd:切分視窗的父視窗指標
● nrows:水平方向分隔視窗的數目
● ncols:垂直方向分隔視窗的數目
● dwstyle:切分視窗的風格
● nid:子視窗的id值,預設為系統定義的afx_idw_pane_first
返回值:如果建立成功,返回非零值(true),否則返回0(false)。
m_wndsplitter1.createstatic(this, 2,1); // 切分為2行1列
6、 使用createview產生每個檢視視窗
virtual bool createview( int row, int col, cruntimeclass* pviewclass, size sizeinit, ccreatecontext* pcontext );
函式有5個引數,意義如下:
● row:窗格的行標,從0開始
● col:窗格的列標,從0開始
● pviewclass:檢視的執行期類cruntimeclass指標,可以用巨集runtime_class獲得
● sizeinit:乙個size(或者csize)型別的資料,指定窗格的初始大小
● pcontext:一般是由父視窗傳遞過來,包含視窗的建立資訊
返回值:如果建立成功,返回非零值(true),否則返回0(false)。
oncreateclient函式的全部**:
bool cmainframe::oncreateclient(lpcreatestruct lpcs, ccreatecontext* pcontext)
// todo: add your specialized code here and/or call the base class
crect rect;
getclientrect(&rect);
//產生第一次靜態切分
m_wndsplitter1.createstatic(this, //父視窗指標
2, // 切分的行數
1); // 切分的列數
//為第乙個窗格產生檢視
m_wndsplitter1.createview(0,0, // 窗格的行、列序數
runtime_class(ctestview),//檢視類
csize(rect.width(),rect.height()-rect.height()/5),//初始化大小
pcontext);//父視窗的建立引數
//為第二個窗格產生檢視
m_wndsplitter1.createview(1,0,
runtime_class(cmyeditview),
csize(rect.width(),rect.height()/5),
pcontext);
return true;//不再呼叫基類的oncreateclient函式
//return cframewnd::oncreateclient(lpcs, pcontext);
在這裡需注意3點:
① 必須為每個靜態切分窗格建立檢視視窗,不能漏掉乙個;
② 必須包含相應的類的標頭檔案,在mainfrm.cpp檔案的開始包含一下頭檔案:
#include "testview.h"
#include "myeditview.h"
③產生靜態切分後,就不能呼叫預設的基類的oncreateclient函式。
7、 在檢視視窗類ctestview中宣告乙個csplitterwnd類的成員變數m_wndsplitter2,用於第二次切分。
8、 使用classwizard為檢視視窗類ctestview新增oncreate函式,在該函式中呼叫createstatic函式和createview函式,類似cmainframe::oncreateclient函式中的呼叫
**如下:
int ctestview::oncreate(lpcreatestruct lpcreatestruct)
if (cview::oncreate(lpcreatestruct) == -1)
return -1;
// todo: add your specialized creation code here
crect rect;
getclientrect(&rect);
//獲得視窗的建立資訊指標
ccreatecontext *pcontext = (ccreatecontext*) lpcreatestruct->lpcreateparams;
//產生二次靜態切分
m_wndsplitter2.createstatic(this,1, 2);
//為第乙個窗格產生檢視
m_wndsplitter2.createview(0,0,// 窗格的行、列序數
runtime_class(clineview),//檢視類
csize(rect.width()/4,rect.height()),//初始化大小
pcontext);//父視窗的建立引數
//為第二個窗格產生檢視
m_wndsplitter2.createview(0,1,
runtime_class(cinfoview),
csize(1,1),
pcontext);
return 0;
注意:二次切分的父視窗是第一次切分的第乙個窗格,其檢視類是ctestview
9、使用classwizard為檢視視窗類ctestview新增onsize函式,在該函式中呼叫子函式
switchview(),子函式的**如下:
void ctestview::switchview()
crect rect;
getclientrect(&rect);
int cx = rect.width();
int cy = rect.height();
m_wndsplitter2.movewindow(-2,-2,cx,cy+3);
m_wndsplitter2.setcolumninfo(0, cx/4,0);
m_wndsplitter2.setcolumninfo(1, cx-cx/4, 0);
m_wndsplitter2.recalclayout();
該子函式主要用於設定二次切分後的各列資訊,通過csplitterwnd::setcolumninfo函式實現,原型為:void setcolumninfo( int col, int cxideal, int cxmin );
由3 個引數,意義如下:
● col:切分視窗的列標識
● cxideal:列的實際寬度,單位為畫素
● cxmin:列的最小寬度,單位為畫素
本示例的執行結果如下:
三、總結
切分視窗的形式和每個窗格所使用的檢視類可以根據實際需要來確定,以滿足程式的不同應用。本示例使用了三叉切分,檢視類使用了列表檢視類clistview、表單檢視類cformview、編輯檢視類ceditview,在vc++6.0下除錯通過。
三叉切分的方法並不唯一,本文例項是我在實際開發中總結的一種方法,讀者可以通過本例舉一反三,掌握切分視窗與多檢視相結合的精髓所在
學做事,先學做人
經理很關照我,我很感謝經理。其實,有乙個好的領導,只要好好幹,他是一定會知道的。但是,要改變客戶的看法,看來還真的很難。在客戶面前不可以太謙虛,太過謙虛,他們反覺得我們無能。做事先做人,一點都沒錯啊。感覺自己太嫩了,這一切還得慢慢磨練。希望多看數,多學習,多仔細觀察生活,觀察周圍成功的人,不斷提高自...
B 學密碼學真的得學程式
b 學密碼學真的得學程式 time limit 1000msmemory limit 65536kb64bit io format lld llu submit status practice sdutoj 2464 description 話說,上次zyj同學最終在眾位瑪麗亞的幫助下搞定了那個神奇...
學密碼學一定得學程式
time limit 1000ms memory limit 65536k 曾經,zyj同學非常喜歡密碼學。有一天,他發現了乙個很長很長的字串s1。他很好奇那代表著什麼,於是神奇的wl給了他另乙個字串s2。但是很不幸的是,wl忘記跟他說是什麼意思了。這個時候,zyj不得不求助與偉大的zp。zp笑了笑...