威尼斯www.9778.com-威尼斯正版官方网站

求助:MFC静态嵌套拆分窗口的问题

日期:2019-12-25编辑作者:编程人生

在初始分隔四个视图,然后左上视图是树状结构,通过节点改变左下和右下视图;;;;左下视图可以输入数字,并在右下视图中textout显示出来。可是,我发现根本显示不出来,查了一下,发现没有关联到document。但是一般view创建后,不是自动关联到document吗?请问我这个该如何关联呢,代码如下:mainframe.cppvoidCMainFrame::SwitchToView(intnViewType){CView*pView=(CView*)m_wndSplitter1.GetPane(1,0);//CRectrcRight,rcFrame;//pView-GetClientRect(rcRight);//GetClientRect(rcFrame);CRectrt;GetClientRect(rt);switch(nViewType){caseViewD://CListPaneView{if(!pView-IsKindOf(RUNTIME_CLASS(CViewD))){m_wndSplitter1.DeleteView(1,0);m_wndSplitter1.CreateView(1,0,RUNTIME_CLASS(CViewD),CSize(rt.Width()/5,rt.Height()/10),NULL);m_wndSplitter1.RecalcLayout();/*m_pLefBottomView=(CViewC*)m_wndSplitter.GetPane(1,0);*/m_wndSplitter2.DeleteView(1,0);m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CViewD),CSize(rt.Width()*4/5,rt.Height()/10),NULL);m_wndSplitter2.RecalcLayout();/*m_pLefBottomView=(CViewC*)m_wndSplitter.GetPane(1,1);*/}break;}caseViewC://CEditPaneView{if(!pView-IsKindOf(RUNTIME_CLASS(CViewC))){//删除旧的视图m_wndSplitter1.DeleteView(1,0);//创建新的视图m_wndSplitter1.CreateView(1,0,RUNTIME_CLASS(CViewC),CSize(rt.Width()/5,rt.Height()/10),NULL);//调整分布m_wndSplitter1.RecalcLayout();/*m_pLefBottomView=(CViewC*)m_wndSplitter.GetPane(1,0);*/m_wndSplitter2.DeleteView(1,0);m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CViewB),CSize(rt.Width()*4/5,rt.Height()/10),NULL);m_wndSplitter2.RecalcLayout();/*m_pLefBottomView=(CViewC*)m_wndSplitter.GetPane(1,1);*/}break;}default:break;}}右下角视图:voidCViewB::OnDraw(CDC*pDC){CKnifeTestDoc*pDoc=(CKnifeTestDoc*)this-GetDocument();pDC-TextOut(100,10,pDoc-m_docstr1);pDC-TextOut(250,10,pDoc-m_docstr2);.....}左下角的视图参数可以保存到doc中,但是右下角视图没有关联到document。。。是哪里出问题了呢?诚心感谢~

MFC视图切换大全总结,mfc视图大全

单纯视图之间的切换

单文档多视图切换是我在学习MFC中遇到的一个老大难问题,在今天总算是一一破解了。我觉得视图切换分为三个等级,第一是在未切分窗格的情况下切换视图类;第二是在分割窗格的一个窗格内实行视图切换;第三是在分割窗格和未分割之间的切换和视图切换。

在MFC创建SDI的伊始,MFC默认的视图类是CView,如果CView满足你的需求,可以直接单击finish,如果你不想让CView成为你的默认视图类,你可以在下图这个地方修改。

如果你忘记了修改默认的视图类这也没关系,我们可以在代码中改变:

在App类里面有个函数叫InitInstance(),在这里面有一段代码

CSingleDocTemplate* pDocTemplate; 
pDocTemplate = new CSingleDocTemplate( 
IDR_MAINFRAME, 
RUNTIME_CLASS(Cprogram8Doc), 
RUNTIME_CLASS(CMainFrame), 
RUNTIME_CLASS(CView1)); //这里更改你的默认视图类,注意不要忘记包含头文件哦 
if (!pDocTemplate) 
return FALSE; 
AddDocTemplate(pDocTemplate);

说完了默认视图类的更改,我们现在进入主题。

1、首先创建你需要切换的视图类,AddClass进入或者创建一个控件然后AddClass创建控件关联类,后者适用于Form之类的控件。

2、控制之处,比如菜单项单击、单击鼠标什么的,我是使用菜单项来切换窗口的

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这个函数主要用于视图切换

在这个函数中主要做以下几个动作:

1、获得当前视图类指针和需要转换的视图类指针,如果是第一次使用需要New一个,并且与文档类关联;

2、改变活动视图;

3、显示新视图和隐藏旧视图;

4、设置控件ID;

5、调整框架视图。

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 

在看网上其他人的帖子的时候发现在RecalcLayout(); 前面还要加一句delete pOldActiveView;我自己觉得这样有些浪费资源,视图类创建完成了隐藏起来,用的时候重新显示。这样的方法应该比每次使用都要创建好一些。小弟不才,有讨论的朋友可以联系我。

带有分割窗格的视图切换

切换视图第二层就是带有分割窗格的视图切换

分割窗格的视图切换,我觉得难点是不容易在有限区域进行视图切换。

1、首先分割窗格,这里我不多解释,详情看下面链接;

2、再给每个视图一个唯一的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一个新视图,就覆盖掉前一个视图,最终显示的是最后一个视图,前面的视图只是隐藏起来,等到使用的时候显示出来就好了。返回值要覆盖返回到基类的语句return CFrameWndEx::OnCreateClient(lpcs, pContext);将这句话注解,然后return true;

3、在哪里激活切换功能自己设计,我使用的是菜单;

4、响应主要包括下面几个步骤:

1、首先获得窗格中的当前视图;

2、使用IsKindOf判断这个类是否是将要切换到的类;

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);

上面的全部是准备工作,下面才是真正的切换;

4、删除原有视图

5、创建当前视图

6、调整框架

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(); 
}

仔细一看,貌似这个还要比单纯视图切换还要简单一些,这也没办法,CSplitterWnd提供了这么一个便捷的方法。

带分割视图与未分割视图之间的切换

这个是三部曲中我认为最难的,并不是说程序有多么难,只是想到这个切分方式真的不容易,今天就把这三部曲的最后一曲分享给大家,也为互联网做一点贡献。

首先说一下程序的思想,为分割窗口层专门独立创建一个基于CFrameWnd的类,然后在这里面写分割视图的代码,再与其他未分割的视图类进行切换。

下面我们来看一下实现的过程:

1、创建一个基于CFrameWnd的派生类CSplitterFrame;

2、添加要填充分割窗口的视图类和与分割视图切换的视图类;

3、为这个派生类重载OnCreateClient函数,构造分割视图

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;

这里我不解释了,想必大家都很熟悉了,这里我要说一点我自己犯过的错误。我本来想在这里GetClientRect获得窗口大小,但失败了,左思右想不明白,后来才发现,这又不是CMainFrame,所以根本不能获得,要是用API函数。

4、在CMainFrame类里面添加框架和视图类指针变量

CSplitterFrame *m_pSplitterFrame; //分割视图框架指针 
CView *m_pView; //单独视图类,基于CView类 
CView *m_pForm; //单独视图类,基于CFormView类 
int m_nCurrentID; //记录当前视图

5、在CMainFrame类里面重载OnCreateClient函数,创建视图及分割框架

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; //设置默认视图类 
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、创建视图切换函数

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、创建调用方法

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); 
}

单纯视图之间的切换 单文档多视图切换是我在学习MFC中遇到的一个老大难问题,在今天总算是一一破解...

图片 1

代码如下:CRectrc;GetClientRect(rc);m_wndSplitter1.CreateView(0,0,RUNTIME_CLASS(CMusicPlayer1View),CSize(0,70),pContext);//为相应的窗格指定视图类m_wndSplitter2.CreateStatic(m_wndSplitter1,1,3,WS_CHILD|WS_VISIBLE,m_wndSplitter1.IdFromRowCol(1,0));m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CMusicPlayer1View),CSize(rc.Width()/3,0),pContext);m_wndSplitter2.CreateView(0,1,RUNTIME_CLASS(CMusicPlayer1View),CSize(rc.Width()/3,0),pContext);m_wndSplitter2.CreateView(0,2,RUNTIME_CLASS(CMusicPlayer1View),CSize(rc.Width()/3,0),pContext);returnTRUE;帮忙看下,当我嵌套时,总会出现这样的报错,是代码哪里出问题了?

本文由威尼斯www.9778.com发布于编程人生,转载请注明出处:求助:MFC静态嵌套拆分窗口的问题

关键词:

一步一步学多线程-Timer,多线程-timer

if(g_cdma.ConnectCom(_T("COM"))){HRESULThr;IConnectionPointContainer*pConnectionPointContainer=NULL;IConnectionPoint*pConnectionPoint=NULL;hr=g_cdma.m_...

详细>>

使用Real vnc做远程协助,怎么将受控端返回的远程桌面显示到自

公司最近做远程协助,使用RealVNC的源代码做,源代码返回的是一个win32窗口,我想把win32的窗口,弄成MFC窗口的子窗口...

详细>>

matlab与vs混合编程问题

为什么点了之后只有哪里错了? 用matlab生成的mydecimate.h中有externLIB_myDecimate_C_APIboolMW_CALL_CONVmyDecimateInitialize(void)在主...

详细>>

32 Top命令

环境说明:1.该进程被PCI设备的中断程序调用,运行在内核态,大概2ms调度一次。2.该进程中创建了两个共享内存(SE...

详细>>