VC单文档切分动态更换

网事如风

拒绝浮躁,记录技术人生中的点滴,希望能和偶然来到这里的你共同进步。

歪酷博客
<< <2004 十一月> >>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<script language=javascript src="VC单文档切分动态更换多视图代码分析 - 网事如风 - 歪酷博客 Ycul Blog - 记录我们的时代.files/uni-calendar.js"></script> <script language=javascript> var strBlogID = ""; var strDatesHasPost = "2004-8-17,2004-8-18,2004-8-27,2004-8-31,2004-9-1,2004-9-3,2004-9-8,2004-9-10,2004-9-13,2004-9-15,2004-9-20,2004-9-21,2004-9-22,2004-9-29,2004-10-10,2004-10-14,2004-10-15,2004-10-18,2004-10-20,2004-10-21,2004-10-22,2004-10-25,2004-10-26,2004-10-28,2004-10-29,2004-11-1,2004-11-3,2004-11-4,2004-11-5,2004-11-9,2004-11-10,2004-11-12,2004-11-15,2004-11-16,2004-11-18,2004-11-19,2004-11-23,2004-11-24,2004-11-25,"; showCalendar(2004,11); </script>

<script language=Javascript> function check_followups() { if (this.document.followups_form.name.value == "") { alert("请输入姓名"); this.document.followups_form.name.focus(); return false; } if (this.document.followups_form.email.value != "") { if (check_email(this.document.followups_form.email.value) == false) { alert("请输入正确的电邮地址"); this.document.followups_form.email.focus(); return false; } } if (this.document.followups_form.content.value == "") { alert("请输入评论内容"); this.document.followups_form.content.focus(); return false; } holdtext.innerText = document.followups_form.content.value; Copied = holdtext.createTextRange(); Copied.execCommand('Copy'); alert("为了确保你的评论免受网络等意外原因造成的损失,我们已经将其复制到你系统的剪贴板上。/n/n一旦失败,请不要慌张,使用粘贴功能(在编辑框中按下CTRL+V)即可找回。"); this.document.followups_form.submit(); } function check_email(str) { var pattern = /^([a-zA-Z0-9_]|/-|/.)+@(([a-zA-Z0-9_]|/-)+/.)+[a-zA-Z]{2,4}$/; return pattern.test(str); } </script>

VC单文档切分动态更换多视图代码分析
汤米 @ 2004-09-21 14:39

     最近iMaker2000的界面设计所用的是Doc/View结构,涉及到Single Document的多视图带切分的切换。呵呵,光是述说都有点拗口了。VC做界面的确是麻烦啊,不过做好了我相信要比VB或者DELPHI要好,灵活度也会更好。不过就工程角度来说,VC做界面学学也就行了,如果要大规模的做,还是简单快捷的工具比较好。
     在网上找了很久相关的代码,最后终于在CodeGure上面找到了一个实现了相应功能的Project。一看时间,晕!98年的,算了,能实现功能就行了。
     建立View的过程就不多说了,这里主要说说怎么样切换的。
     不带切分的切换比较普遍了,VC技术内幕就有一个详细的代码,我待会会把代码也一起贴出来。
     带切分的主要的函数有2个,一个是建立时候的函数,一个是切换的函数,两个基本上很类似,这里分析一下切换的函数:
void CMainFrame::OnSwitchView1()
{
// TODO: Add your command handler code here
CRect cr;
GetClientRect(&cr);//取得客户区的显示区域
CSize paneSize1(3*cr.Width()/4, cr.Height());//设定新view大小
CCreateContext Context;//声明视图文档联系结构并设定其内容
Context.m_pNewViewClass=RUNTIME_CLASS(CSwitchView1);
Context.m_pCurrentDoc=((CSwitchApp*)AfxGetApp())->m_pDoc;
Context.m_pCurrentFrame=this;
Context.m_pNewDocTemplate=Context.m_pCurrentDoc->GetDocTemplate();
Context.m_pLastView=(CView*)m_wndSplitter.GetPane(0,0);
m_wndSplitter.DeleteView(0, 1);//删除第1行第2列的View
m_wndSplitter.CreateView(0, 1,RUNTIME_CLASS(CSwitchView1),paneSize1, &Context);//动态创建View1
CSwitchView1 *pView=(CSwitchView1*)m_wndSplitter.GetPane(0,1);//得到切分窗口的指针
pView->GetParentFrame()->RecalcLayout();//重绘主窗口
m_wndSplitter.RecalcLayout();//重绘分隔条窗口
pView->OnInitialUpdate();//估计是一些初始化的操作
m_wndSplitter.SetActivePane(0,1);//激活新的分隔区域
}

不带切分的代码如下:
void CMainFrame::SwitchToView(int nForm)
{
//CDocument* pDoc = GetActiveDocument();
   CView *pOldActiveView=GetActiveView();             //保存旧视图
   CView *pNewActiveView=(CView*)GetDlgItem(nForm);   //取得新视图
   if(pNewActiveView==NULL)
   {
       switch(nForm)
       //这些ID是对话框的标志符,但也可以用其他的标志
       {
       case IDD_DIALOG1 :
           pNewActiveView=(CView*)new TForm;
           break;
       case IDD_FORMVIEW :
           pNewActiveView=(CView*)new TForm2;
           break;
       }
       CCreateContext context;   //将文挡和视图相连
       context.m_pCurrentDoc=pOldActiveView->GetDocument();
pNewActiveView->Create(NULL, NULL, WS_BORDER|WS_CHILD ,
           CFrameWnd::rectDefault, this, nForm, &context);


       pNewActiveView->OnInitialUpdate();
   }
   SetActiveView(pNewActiveView);        //改变活动的视图
   pNewActiveView->ShowWindow(SW_SHOW);  //显示新的视图
   pOldActiveView->ShowWindow(SW_HIDE);  //隐藏旧的视图

   if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(TForm))
pOldActiveView->SetDlgCtrlID(IDD_DIALOG1);

else if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(TForm2))
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW);

   pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
   
   delete pOldActiveView;   //删除旧视图

RecalcLayout();          //调整框架窗口
}

比对一下可以看出,带切分的主要是通过m_wndSplitter这样一个成员进行操作,而不带切分的则是直接对整个View进行操作。(因为没有m_wndSplitter啊,呵呵。)

补充一下:刚刚调试了一下代码,有点波折,不过还是顺利通过了,其实代码可以简化很多。
void CMainFrame::OnSwitchView1()
{
m_wndSplitter.DeleteView(1, 0);
m_wndSplitter.CreateView(1, 0,
RUNTIME_CLASS(TForm2),
CSize(0, 0),
NULL);
m_wndSplitter.RecalcLayout();
}
当然,上面这个代码只涉及到了界面的切换,具体的程序中的应用很可能和文档有关,而且需要精确一点的控制,就需要看第一个函数了。注意我的View是纵向的2个,所以参数是1,0。

Trackback地址: http://www.yculblog.com/trackback/190403

 

评 论

红移 @ 2004-09-21 15:29 地址: http://dev365.yculblog.com/

路过。 看来楼主化了不少功夫。佩服。

微软开始淡化MFC了。给出一个小小的提示。 :)


汤米 @ 2004-09-21 16:55 电邮: dancejc@sina.com

怎么说呢?微软淡化MFC也许是为了加强.Net的推广吧,而且.Net是很大的一个平台,如果说要混饭吃当然迅速的转过去比较好,当时就做开发本身而言,研究一下 MFC也是很有乐趣的,也可以学到不少东西。
做开发的还是应该注重一个思想,至于具体用什么平台或者是什么语言,那反而是其次,你觉得呢?


汤米 @ 2004-09-22 10:42 电邮: dancejc@sina.com

思想就是:科技以人为本!

哈哈!


imag @ 2004-11-09 19:54

谢谢作者,解燃眉之急


lxd @ 2004-11-09 20:26

Context.m_pCurrentDoc=((CSwitchApp*)AfxGetApp())->m_pDoc;
这句中,“m_pDoc”变量是怎么定义的,编译器处错说没有该变量

以前的代码好象是《VC技术内幕》上面的,现在书我还给别人了,m_pDoc应该是App类里面一个Doc成员的指针,该句主要是让Context得到一个Doc的指针。具体实现可以看自己。

如果是单文档应该是不用更换的。

彭智 @ 2004-11-10 01:11 电邮: goodpz@tom.com

请问,怎么把一个formview加入到拆分窗口里面去?在Splitter.CreateView(1, 0,RUNTIME_CLASS(CView1), CSize(100, 100), pContext);里,如果CView1从CListView中继承来,程序就可以跑通,如果从CFormView继承来就跑不通,这是为什么?
请帮帮忙,急啊!

是会有这样的问题,记得以前我做的时候也是,CView的就很好换,CFormView的就要麻烦一点点。好象是改了一两个地方就可以了,是编译出错还是运行出错?如果是编译出错,把出错信息贴来看看。

彭智 @ 2004-11-13 21:45 电邮: goodpz@tom.com

现在可以了。但有其他两个问题:
1.我用的是你的DeleteView/CreateView来切换的,一个FormView和ListView之间的切换,但是有时候会有问题,内存读写错误。是不是DeleteView之前还要主动做其他的工作吗?
2. 用VC内幕中的方法来切换,因为我用了切分窗口,那么pNewActiveView->Create中的rect参数应该怎么改?我从GetPane后用GetWindowRect得到rect,结果新建的view还是占满了整个窗口,why?
thank

我以前实验切换的是两个FormView,都很正常,ListView没有试过,也不好多说什么。可能有一些View之间的不同点需要修改一下和设定一下。
第二个问题真的不清楚,因为没有做过,好象一般都是用的CFrameWnd::rectDefault。
希望你能解决问题。

彭智 @ 2004-11-14 13:41 电邮: goodpz@tom.com

碰到一个奇怪的问题,
新建一个SDI项目,添加MainFrame的OnContextMenu消息相应,添加如下代码:
CMenu menu;
ASSERT(menu.LoadMenu(IDR_MAINFRAME));
menu.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTALIGN|TPM_LEFTBUTTON  ,point.x,point.y,this);
debug编译,能弹出右键菜单,release编译,程序就死了
why?

大哥,离题太远了吧。

你 的 评 论
* 姓名
电邮
个人主页
* 评论
* 认证码
请输入你看到的数字
 

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对你不利的证据.

 

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定




<script type=text/javascript> </script> <script src="VC单文档切分动态更换多视图代码分析 - 网事如风 - 歪酷博客 Ycul Blog - 记录我们的时代.files/show_ads.js" type=text/javascript> </script>
网 志 分 类
· 所有网志 · Visual C++ · 经典C · 数码前沿 · 开发文摘 · 生活随笔 · 忆苦思甜 · 幽默妙文 · 未分类 ·
引 用 过 本 网 志 的 B l o g
搜 索
友 情 链 接
· 歪酷博客 · 管理我的Blog · iMake软件维护网站 · 我的相册 · dancejc的CN博客 · 狂风贝贝 ·

歪酷博客 歪酷博客

歪酷博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值