小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

怎樣在一個(gè)Pane中顯示多種View

 Frank_Chia 2010-07-15
---- 在MS Windows 中,一個(gè)窗口可以分割成若干個(gè)子窗口,每一個(gè)子窗口稱作一個(gè)窗片(pane),每個(gè)窗片可以獨(dú)立控制,這給界面設(shè)計(jì)提供了很大的方便。

---- 利用VC 可以很方便地實(shí)現(xiàn)分割窗口。分割的方法有兩種:動(dòng)態(tài)和靜態(tài)。動(dòng)態(tài)分割時(shí)可以根據(jù)用戶的需要分割成數(shù)目不同的窗片,但所有窗片的屬性和父窗口都是一樣的;而靜態(tài)分割的窗片的數(shù)目在程序中指定,運(yùn)行時(shí)是固定的,但每個(gè)窗片可以有各自不同類型的視(View),因此其使用范圍更為廣泛。本文所討論的問(wèn)題僅限于靜態(tài)分割。

---- 窗片中視的類型大多是在主窗口的創(chuàng)建過(guò)程中指定的。這也就意味著,一個(gè)窗片雖然可以顯示任意類型的視,但是這種類型一旦確定,在程序運(yùn)行過(guò)程中就難以改變。

---- 一、我要的是這樣的!

---- 但是我們有時(shí)確實(shí)需要改變一個(gè)窗片所顯示的視的類型,也就是說(shuō),需要讓一個(gè)窗片顯示多種類型的視。例如一個(gè)窗口被分割成兩部分,一邊是命令窗口,另一邊是工作窗口,根據(jù)命令窗口中發(fā)出的不同命令,需要變換不同的工作類型,這就需要工作窗口中能夠顯示多種類型的視窗,那么,如何做到這一點(diǎn)呢?

---- 二、你可以這樣做!

---- 從圖1 中可以看到,本程序共有三個(gè)視類,分別是:

---- ? 命令視類CCmdView:用來(lái)控制右邊窗片中不同視的顯示;

---- ? 選項(xiàng)按鈕視類CRdiView:顯示在右窗片中的選項(xiàng)視類;

---- ? 檢查按鈕視類CChkView:顯示在右窗片中的檢查視類。

---- 這三個(gè)視類都是CFormView 的子類。

---- 下面我們來(lái)看如何在右窗片內(nèi)進(jìn)行兩類視間的切換。實(shí)際上,由視A 切換到視B 的原理很簡(jiǎn)單,那就是:

---- 1. 從窗片中刪除視A;

---- 2. 往窗片中添加視B。

---- 步驟1 的實(shí)現(xiàn)非常簡(jiǎn)單,僅用一條語(yǔ)句即可:

---- m_wndSplitter.DeleteView(0, 1);

---- 但它是必不可少的,因?yàn)槟悴荒茏屢粋€(gè)窗片同時(shí)包含兩個(gè)視。我本來(lái)希望往一個(gè)窗片中添加新的視時(shí),VC 會(huì)自動(dòng)將原來(lái)的視刪掉,可是它不干。

---- 我們來(lái)看如何實(shí)現(xiàn)步驟2,當(dāng)一個(gè)窗片是空的時(shí)候,怎樣往里面添加一個(gè)視呢?其實(shí)這樣的功能在程序里我們已經(jīng)用過(guò)了,看下面的語(yǔ)句:

BOOL CMainFrame::OnCreateClient
(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
……
if (!m_wndSplitter.CreateView(0, 0,
pContext->m_pNe ewClass,
size,
pContext))
……
}
---- 是的,用的就是CSplitterWnd::CreateView(),要注意的是它共有五個(gè)參數(shù),其中前兩個(gè)用來(lái)指定分割窗口的窗片,第三個(gè)用來(lái)指定視的類型,第四個(gè)指定視的大小。最后的一個(gè)我們暫時(shí)用不上,用空值NULL 就可以了。

---- 這樣我們就可以編寫(xiě)視切換的代碼了。因?yàn)橐暻袚Q要操縱m_wndSplitter,而它是主窗口的成員,因此切換過(guò)程最好設(shè)計(jì)為主窗口的成員函數(shù)。但是切換命令是CCmdView 接受的,因而可以讓CCmdView 接受到視更改消息后,將消息傳給主窗口,由主窗口完成視更改。具體的代碼是這樣的:

---- 命令視類中的消息映射:

BEGIN_MESSAGE_MAP(CCmdView, CFormView)
……
ON_BN_CLICKED(IDC_CHECK, OnSwitchToCheckView)
ON_BN_CLICKED(IDC_RADIO, OnSwitchToRadioView)
……
END_MESSAGE_MAP()

命令視類中的消息響應(yīng):
void CCmdView::OnSwitchToCheckView()
{
AfxGetApp()->m_pMainWnd->
SendMessage(WM_COMMAND, ID_CHECK);
}

void CCmdView::OnSwitchToRadioView()
{
AfxGetApp()->m_pMainWnd->
SendMessage(WM_COMMAND, ID_RADIO);
}

主窗口中的消息映射:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
……
ON_COMMAND(ID_CHECK, OnSwitchToCheckView)
ON_COMMAND(ID_RADIO, OnSwitchToRadioView)
……
END_MESSAGE_MAP()

主窗口中的消息響應(yīng):
void CMainFrame::OnSwitchToCheckView()
{
m_wndSplitter.DeleteView(0, 1);
m_wndSplitter.CreateView(0, 1,
RUNTIME_CLASS(CChkView),
CSize(0, 0),
NULL);
m_wndSplitter.RecalcLayout();
}

void CMainFrame::OnSwitchToRadioView()
{
m_wndSplitter.DeleteView(0, 1);
m_wndSplitter.CreateView(0, 1,
RUNTIME_CLASS(CRdiView),
CSize(0, 0),
NULL);
m_wndSplitter.RecalcLayout();
}
---- 好啦,運(yùn)行一下這個(gè)程序,感覺(jué)是否不錯(cuò)?看來(lái)大功告成了,可是……

---- 三、還有一個(gè)問(wèn)題

---- 在運(yùn)行我們辛辛苦苦編出來(lái)的程序時(shí),回頭看看VC 的調(diào)試窗口,你會(huì)發(fā)現(xiàn)有很多行這樣的話:

---- Create view without document.

---- 這是說(shuō)我們創(chuàng)建了視,可是沒(méi)有相應(yīng)的文檔。好在這只是警告信息,不是什么錯(cuò)誤,如果你不需要相應(yīng)的文檔,就完全不用去管它。可是,VC 中一種很重要的結(jié)構(gòu)就是文檔- 視結(jié)構(gòu),利用這種結(jié)構(gòu),對(duì)數(shù)據(jù)操縱起來(lái)非常方便。如果需要建立與視相對(duì)應(yīng)的文檔,應(yīng)該怎么辦呢?

---- 這就涉及到VC 中文檔- 視結(jié)構(gòu)的知識(shí),不過(guò)不用怕麻煩,與本文有關(guān)的就只有這么兩點(diǎn)而已:

---- 1. 利用VC 創(chuàng)建的應(yīng)用程序一般都會(huì)管理一些文檔模板(Document Template),文檔類和視類的對(duì)應(yīng)關(guān)系就是在文檔模板里描述的。

---- 2. 一個(gè)文檔可以有多個(gè)視,創(chuàng)建視的時(shí)候,需要根據(jù)文檔和視的對(duì)應(yīng)關(guān)系,給出它所依附的文檔。

---- 怎樣實(shí)現(xiàn)上述第一點(diǎn)呢?

---- 首先建立相應(yīng)的文檔類:CRdiDoc 和CChkDoc。

---- 其次是定義相應(yīng)的文檔模板,這是應(yīng)用類的成員變量。因?yàn)樵趧e的類中要使用它們,我們將之定義為公共類型:

class CViewSwitcherApp : public CWinApp
{
……
public:
CSingleDocTemplate* m_pRdiDocTemplate;
CSingleDocTemplate* m_pChkDocTemplate;
……
}
然后創(chuàng)建這兩個(gè)文檔模板,并加入到模板列表中:
BOOL CViewSwitcherApp::InitInstance()
{
……
m_pRdiDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CRdiDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CRdiView));
AddDocTemplate(m_pRdiDocTemplate);

m_pChkDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CChkDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CChkView));
AddDocTemplate(m_pChkDocTemplate);
……
}
---- 至于第二點(diǎn),是在創(chuàng)建視時(shí)完成的。還記得創(chuàng)建視的情況么?當(dāng)時(shí)有一個(gè)叫做pCreateContext 的參數(shù),我們將之置為空,這里就要用到它了。

---- pCreateContext 是一個(gè)指向被稱作" 創(chuàng)建上下文"(CreateContext) 結(jié)構(gòu)的指針,這個(gè)結(jié)構(gòu)中保存一些與創(chuàng)建視相關(guān)的內(nèi)容。在創(chuàng)建主窗口時(shí),系統(tǒng)會(huì)構(gòu)造這樣一個(gè)結(jié)構(gòu),并將它作為參數(shù)傳遞到與創(chuàng)建視有關(guān)的函數(shù)中。但現(xiàn)在我們不創(chuàng)建主窗口,因此不得不自己構(gòu)造這樣一個(gè)結(jié)構(gòu)。實(shí)際上,該結(jié)構(gòu)中我們所要使用的字段只有三個(gè):

---- 1. 新視所屬的文檔模板m_pNewDocTemplate;

---- 2. 新視的類型m_pNewViewClass;

---- 3. 新視所屬的文檔m_pCurrentDoc;

---- 其中僅有第三項(xiàng)需要新建,前兩項(xiàng)都是已知的,只要指定即可。以切換到選項(xiàng)視為例,修改后的代碼是:

void CMainFrame::OnSwitchToRadioView()
{
m_wndSplitter.DeleteView(0, 1);

CCreateContext createContext;
// 定義并初始化CreateContext
// 獲取新視所屬的文檔模板
CSingleDocTemplate* pDocTemplate =
((CViewSwitcherApp*)AfxGetApp())-> m_pRdiDocTemplate;
// 創(chuàng)建新文檔并初始化
CDocument* pDoc = pDocTemplate->CreateNewDocument();
pDoc->OnNewDocument();

// 設(shè)置CreateContext 相關(guān)字段
createContext.m_pNewViewClass = RUNTIME_CLASS(CChkView);
createContext.m_pCurrentDoc = pDoc;
createContext.m_pNewDocTemplate = pDocTemplate;

m_wndSplitter.CreateView(0, 1,
RUNTIME_CLASS(CRdiView),
CSize(0, 0),
&createContext);

m_wndSplitter.RecalcLayout();
}
---- 四、最后的修改

---- 為了使這個(gè)程序更符合要求,我們還要做一些與更換視無(wú)關(guān)的修改。在這個(gè)程序中我們一共定義了三種類型的文檔,程序啟動(dòng)時(shí)一般要新建一個(gè)文檔開(kāi)始工作,可是它不知道要選擇哪一種,就彈出一個(gè)對(duì)話框來(lái)詢問(wèn)。而這是我們不希望看到的。修改的方法是不讓VC 選擇新文檔類型,而我們指定創(chuàng)建哪一種類型的文檔,即把CViewSwitcherApp::CViewSwitcherApp() 中的語(yǔ)句

---- if (!ProcessShellCommand(cmdInfo)) return FALSE;

---- 更改為

---- m_pDocTemplate->OpenDocumentFile(NULL)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多