日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MFC视图切换大全总结

發(fā)布時(shí)間:2024/4/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC视图切换大全总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

單純視圖之間的切換

單文檔多視圖切換是我在學(xué)習(xí)MFC中遇到的一個(gè)老大難問題,在今天總算是一一破解了。我覺得視圖切換分為三個(gè)等級,第一是在未切分窗格的情況下切換視圖類;第二是在分割窗格的一個(gè)窗格內(nèi)實(shí)行視圖切換;第三是在分割窗格和未分割之間的切換和視圖切換。

在MFC創(chuàng)建SDI的伊始,MFC默認(rèn)的視圖類是CView,如果CView滿足你的需求,可以直接單擊finish,如果你不想讓CView成為你的默認(rèn)視圖類,你可以在下圖這個(gè)地方修改。

如果你忘記了修改默認(rèn)的視圖類這也沒關(guān)系,我們可以在代碼中改變:

在App類里面有個(gè)函數(shù)叫InitInstance(),在這里面有一段代碼

CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(Cprogram8Doc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CView1)); //這里更改你的默認(rèn)視圖類,注意不要忘記包含頭文件哦
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);

說完了默認(rèn)視圖類的更改,我們現(xiàn)在進(jìn)入主題。

1、首先創(chuàng)建你需要切換的視圖類,AddClass進(jìn)入或者創(chuàng)建一個(gè)控件然后AddClass創(chuàng)建控件關(guān)聯(lián)類,后者適用于Form之類的控件。

2、控制之處,比如菜單項(xiàng)單擊、單擊鼠標(biāo)什么的,我是使用菜單項(xiàng)來切換窗口的

void CMainFrame::OnView1()
{
// TODO: Add your command handler code here

SwitchToForm(IDD_FORMVIEW1);

}

void CMainFrame::OnView2()
{
// TODO: Add your command handler code here

SwitchToForm(IDD_FORMVIEW2);

}

3、SwitchToForm這個(gè)函數(shù)主要用于視圖切換

在這個(gè)函數(shù)中主要做以下幾個(gè)動(dòng)作:

1、獲得當(dāng)前視圖類指針和需要轉(zhuǎn)換的視圖類指針,如果是第一次使用需要New一個(gè),并且與文檔類關(guān)聯(lián);

2、改變活動(dòng)視圖;

3、顯示新視圖和隱藏舊視圖;

4、設(shè)置控件ID;

5、調(diào)整框架視圖。

void CMainFrame::SwitchToForm(int nForm)
{
CView *pOldActiveView=GetActiveView(); //1
CView *pNewActiveView=(CView*)GetDlgItem(nForm);
if(NULL==pNewActiveView)
{
switch(nForm)
{
case IDD_FORMVIEW1:
pNewActiveView=(CView*)new CView1;
break;
case IDD_FORMVIEW2:
pNewActiveView=(CView*)new CView2;
break;
case IDD_FORMVIEW3:
pNewActiveView=(CView*)new CView3;
break;
case IDD_FORMVIEW4:
pNewActiveView=(CView*)new CView4;
break;
default:
break;
}
CCreateContext context;
context.m_pCurrentDoc=pOldActiveView->GetDocument();
pNewActiveView->Create(NULL,NULL,WS_CHILD | WS_BORDER,CFrameWnd::rectDefault,this,nForm,&context);
pNewActiveView->UpdateData();
}
SetActiveView(pNewActiveView); //2
pNewActiveView->ShowWindow(SW_SHOW); //3
pOldActiveView->ShowWindow(SW_HIDE);
if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CView1)) //4
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW1);
else if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CView2))
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW2);
else if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CView3))
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW3);
else if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CView4))
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW4);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
RecalcLayout(); //5
}
在看網(wǎng)上其他人的帖子的時(shí)候發(fā)現(xiàn)在RecalcLayout(); 前面還要加一句delete pOldActiveView;我自己覺得這樣有些浪費(fèi)資源,視圖類創(chuàng)建完成了隱藏起來,用的時(shí)候重新顯示。這樣的方法應(yīng)該比每次使用都要?jiǎng)?chuàng)建好一些。小弟不才,有討論的朋友可以聯(lián)系我。

帶有分割窗格的視圖切換

切換視圖第二層就是帶有分割窗格的視圖切換

分割窗格的視圖切換,我覺得難點(diǎn)是不容易在有限區(qū)域進(jìn)行視圖切換。

1、首先分割窗格,這里我不多解釋,詳情看下面鏈接;

2、再給每個(gè)視圖一個(gè)唯一的ID號;

m_splitter.CreateStatic(this,1,2);
m_splitter.CreateView(0,0,RUNTIME_CLASS(CTree1),CSize(100,100),pContext);
m_splitter.CreateView(0,1,RUNTIME_CLASS(CForm1),CSize(100,100),pContext);
CWnd *pWnd=m_splitter.GetPane(0,1);
m_pViews[0]=(CView*)m_splitter.GetPane(0,1);
pWnd->SetDlgCtrlID(IDD_FORM1);
pWnd->ShowWindow(SW_HIDE);
m_splitter.CreateView(0,1,RUNTIME_CLASS(CForm2),CSize(100,100),pContext);
pWnd=m_splitter.GetPane(0,1);
m_pViews[1]=(CView*)m_splitter.GetPane(0,1);
pWnd->SetDlgCtrlID(m_splitter.IdFromRowCol(0,1));
pWnd->ShowWindow(SW_SHOW);
RedrawWindow();
return true;

注:我這里CreateView一個(gè)新視圖,就覆蓋掉前一個(gè)視圖,最終顯示的是最后一個(gè)視圖,前面的視圖只是隱藏起來,等到使用的時(shí)候顯示出來就好了。返回值要覆蓋返回到基類的語句return CFrameWndEx::OnCreateClient(lpcs, pContext);將這句話注解,然后return true;

3、在哪里激活切換功能自己設(shè)計(jì),我使用的是菜單;

4、響應(yīng)主要包括下面幾個(gè)步驟:

1、首先獲得窗格中的當(dāng)前視圖;

2、使用IsKindOf判斷這個(gè)類是否是將要切換到的類;

3、獲得框架長寬和窗格長寬;

CView *pView=(CView*)m_splitter.GetPane(0,1); //1
m_bTest=pView->IsKindOf(RUNTIME_CLASS(CForm2)); //2
CRect rcFrame,rcClient; //3
m_splitter.GetClientRect(&rcClient);
GetClientRect(&rcFrame);

上面的全部是準(zhǔn)備工作,下面才是真正的切換;

4、刪除原有視圖

5、創(chuàng)建當(dāng)前視圖

6、調(diào)整框架

if(m_bTest)
{
m_splitter.DeleteView(0,1);
m_splitter.CreateView(0,1,RUNTIME_CLASS(CForm1),CSize(rcClient.Width(),rcFrame.Height()),NULL);
m_splitter.RecalcLayout();
}
else
{
m_splitter.DeleteView(0,1);
m_splitter.CreateView(0,1,RUNTIME_CLASS(CForm2),CSize(rcClient.Width(),rcFrame.Height()),NULL);
m_splitter.RecalcLayout();
}

仔細(xì)一看,貌似這個(gè)還要比單純視圖切換還要簡單一些,這也沒辦法,CSplitterWnd提供了這么一個(gè)便捷的方法。

帶分割視圖與未分割視圖之間的切換

這個(gè)是三部曲中我認(rèn)為最難的,并不是說程序有多么難,只是想到這個(gè)切分方式真的不容易,今天就把這三部曲的最后一曲分享給大家,也為互聯(lián)網(wǎng)做一點(diǎn)貢獻(xiàn)。

首先說一下程序的思想,為分割窗口層專門獨(dú)立創(chuàng)建一個(gè)基于CFrameWnd的類,然后在這里面寫分割視圖的代碼,再與其他未分割的視圖類進(jìn)行切換。

下面我們來看一下實(shí)現(xiàn)的過程:

1、創(chuàng)建一個(gè)基于CFrameWnd的派生類CSplitterFrame;

2、添加要填充分割窗口的視圖類和與分割視圖切換的視圖類;

3、為這個(gè)派生類重載OnCreateClient函數(shù),構(gòu)造分割視圖

m_Splitter.CreateStatic(this,1,2);
m_Splitter.CreateView(0,0,RUNTIME_CLASS(CLeftTree),CSize(300,0),pContext);
m_Splitter.CreateView(0,1,RUNTIME_CLASS(CRightList),CSize(300,0),pContext);
return true;

這里我不解釋了,想必大家都很熟悉了,這里我要說一點(diǎn)我自己犯過的錯(cuò)誤。我本來想在這里GetClientRect獲得窗口大小,但失敗了,左思右想不明白,后來才發(fā)現(xiàn),這又不是CMainFrame,所以根本不能獲得,要是用API函數(shù)。

4、在CMainFrame類里面添加框架和視圖類指針變量

CSplitterFrame *m_pSplitterFrame; //分割視圖框架指針
CView *m_pView; //單獨(dú)視圖類,基于CView類
CView *m_pForm; //單獨(dú)視圖類,基于CFormView類
int m_nCurrentID; //記錄當(dāng)前視圖

5、在CMainFrame類里面重載OnCreateClient函數(shù),創(chuàng)建視圖及分割框架

CRect rcClient;
GetClientRect(&rcClient);
m_pView=new CViewShow;
m_pView->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW &~WS_BORDER,rcClient,this,NULL,pContext);
m_pView->ShowWindow(SW_SHOW);
m_pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pContext->m_pNewViewClass=(CRuntimeClass*)m_pView; //設(shè)置默認(rèn)視圖類
m_pForm=new CFormShow;
m_pForm->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW &~WS_BORDER,rcClient,this,IDD_FORMSHOW,pContext);
m_pForm->ShowWindow(SW_HIDE);
m_pSplitterFrame=new CSplitterFrame;
m_pSplitterFrame->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW &~WS_BORDER,rcClient,this,NULL,0,pContext);
m_pSplitterFrame->ShowWindow(SW_HIDE);
return true;

6、創(chuàng)建視圖切換函數(shù)

bool CMainFrame::Switch(int nID)
{
if(nID==m_nCurrentID)
return false;
switch(nID)
{
case IDD_FORMSHOW:
m_pForm->ShowWindow(SW_SHOW);
m_pForm->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
m_pView->ShowWindow(SW_HIDE);
m_pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST+2);
m_pSplitterFrame->ShowWindow(SW_HIDE);
m_pSplitterFrame->SetDlgCtrlID(AFX_IDW_PANE_FIRST+1);
m_nCurrentID=IDD_FORMSHOW;
break;
case AFX_IDW_PANE_FIRST+1:
m_pSplitterFrame->ShowWindow(SW_SHOW);
m_pSplitterFrame->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
m_pForm->ShowWindow(SW_HIDE);
m_pForm->SetDlgCtrlID(IDD_FORMSHOW);
m_pView->ShowWindow(SW_HIDE);
m_pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST+2);
m_nCurrentID=AFX_IDW_PANE_FIRST+1;
break;
case AFX_IDW_PANE_FIRST+2:
m_pView->ShowWindow(SW_SHOW);
m_pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
m_pForm->ShowWindow(SW_HIDE);
m_pForm->SetDlgCtrlID(IDD_FORMSHOW);
m_pSplitterFrame->ShowWindow(SW_HIDE);
m_pSplitterFrame->SetDlgCtrlID(AFX_IDW_PANE_FIRST+1);
m_nCurrentID=AFX_IDW_PANE_FIRST+2;
break;
default:
break;
}
RecalcLayout();
return true;
}

7、創(chuàng)建調(diào)用方法

void CMainFrame::OnForm()
{
// TODO: Add your command handler code here
Switch(IDD_FORMSHOW);
}
void CMainFrame::OnView()
{
// TODO: Add your command handler code here
Switch(AFX_IDW_PANE_FIRST+2);
}
void CMainFrame::OnSplitter()
{
// TODO: Add your command handler code here
Switch(AFX_IDW_PANE_FIRST+1);
}

轉(zhuǎn)載于:https://www.cnblogs.com/chenzuoyou/p/3342003.html

總結(jié)

以上是生活随笔為你收集整理的MFC视图切换大全总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。