收藏 分享(赏)

文档与视图的建立和关联.doc

上传人:dzzj200808 文档编号:2320202 上传时间:2018-09-10 格式:DOC 页数:8 大小:36.50KB
下载 相关 举报
文档与视图的建立和关联.doc_第1页
第1页 / 共8页
文档与视图的建立和关联.doc_第2页
第2页 / 共8页
文档与视图的建立和关联.doc_第3页
第3页 / 共8页
文档与视图的建立和关联.doc_第4页
第4页 / 共8页
文档与视图的建立和关联.doc_第5页
第5页 / 共8页
点击查看更多>>
资源描述

1、文档与视图的建立和关联本文讨论一下单文档与多视的问题,主要介绍一下笔者在学习 VC+6.0 过程中探索出的一些个人经验,并给出了实现它们的的主要程序框架。 一建立文档与视图: 在 Projects 选 MFC Appwizard(exe) ,键入工程名,点 ok 后选单文档,选择默认值,在第四步时,在Advanced里的 Window Styles 的 Use split window 前打 。 二文档多视: 当我们需要从不同的角度来看单文档的内容时,这就要我们实现多视了,多视有两种实 现方案:静态的和动态的。这就根据不同的需要来实现了。动态的方法一般在程序中已经实现了,自动生成的源代码: B

2、OOL CMainFrame:OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) return m_wndSplitter.Create(this, 2, 2, / TODO: adjust the number of rows, columns CSize(10, 10), / TODO: adjust the minimum pane size pContext); 而静态的方法却麻烦一点,下面我详细介绍一下: 首先我们先插入一个类:class CMyView : public ClistView 在 Main

3、Frm.cpp 加入 #include “MyView.h“ 在 MainFrm.h 中声明 CSplitterWnd m_splitterWnd; /声明分隔器对象,已经自动生成了。 在函数 CMainFrame:OnCreateClient 里加入下面一些代码,只要把原有的代码删去。 If(!m_splitterWnd.CreateStatic(this,1,2,WS_CHILD | WS_VISIBLE)/一行两列 return false;/不成功就返回 else m_splitterWnd.CreateView(0,1,RUNTIME_CLASS(CMyEditView),CSize

4、(100,300),pContext); m_splitterWnd.CreateView(0,0,RUNTIME_CLASS(CMyView),CSize(100,100),pContext); / CmyEditView 和 CmyView 是自己定义的视图类。 /CSize(100,300)是初始化时的大小 return TRUE;/成功的返回值 这样程序一旦执行就会把窗口分割成左右两部分。 但是有时我们需要实现这样的功能:一旦发出一个消息时,我要使其中的一个视图消失,研究一下,可以删去或者隐藏这个视图,相对应恢复时就要重建或者显示这个视图,具体的实现在后面再详解吧! 由于我们有时分割视

5、图,不是很有规则的 1*2,3*1,2*2 等形式,而是在分割的视图里再分割,如图: 视图二 CviewView2 视图一 CviewView1 视图三 CviewView3 声明一个分隔器对象:在 MainFrm.h 中声明 CSplitterWnd m_splitterWnd1 代码为: m_wndSplitter1.CreateStatic( / 创建各个视 m_wndSplitter.CreateView(0, 1,RUNTIME_CLASS(CviewView1), CSize(0, 0), pContext); m_wndSplitter1.CreateView(0, 0,RUNT

6、IME_CLASS(CviewView2), CSize(0, 0), pContext); m_wndSplitter1.CreateView(1, 0, RUNTIME_CLASS(CviewView3), CSize(0, 0), pContext); 如果使用自由定义的视图大小来实现呢? SIZE size; CRect rect; GetClientRect( size.cx = rect.right/2 size.cy = rect.bottom/2; 只要把 size 放在 Csize(0,0)所在的位置就可以了,用这个方法我们就可以在程序中自由地实现视图窗口大小的变化了。 到了

7、这里又有一个问题提出来了,我们不光删去或者隐藏视图,有时只是简单的视图之间的切换,也可以说有的一个框架包含多个视,而在任何时刻只能显示其中的一个视,还是后面再说吧! 三 获得视图指针。 获取视图的指针作为单独的一点来讲,自然有它的重要性,视图与文档,特别在文档与不相干的视图间,视图与视图间的消息传递及互相之间的调用函数或者变量的时候就要获取视图或文档的指针。 a) 获取文档的指针: 与文档相连的视图可以直接获取,这里就不说了,但与文档一点关系都没有的视图要想获取文档的指针就不可以直接获取了。 CMyEditDoc * pDoc=(class CMyEditDoc *)Getdocument);

8、 上面就是获取的方法。 b) 获得视图指针: i. 在其中的一个视图中获取其它视图的指针: CMainFrame* MainFrame1=(CMainFrame*)this-GetParent()-GetParent(); CMyEditView* pView=(CMyEditView*)MainFrame1-m_wndSplitter.GetPane(0,1); This 指针代表当前视图的指针,它通过获取 CmainFrame 的指针再去获取视图的指针,这样有个好处在于可以获得任意视图的指针。 还有一种方案可以实现,但是它有个缺点,你只能把获得的指针作为 Cview 的指针看待,这样你就不

9、能实现特殊视图的功能了。 CMyEditDoc * pDoc=Getdocument); CView * pView; POSITION pos=pDoc-GetFirstViewPosition(); if(pos!=NULL) pView=pDoc-GetNextView(pos); 在里加入多个 pView=pDoc-GetNextView(pos);(原因我也说不出来)就可以获得你所要得视图。 如果你在开始就定义你所接触视图的指针,只不过没有初始化而已,就方面了好多。 m_pEditViewright =( CMyEditView* )m_splitterWnd.GetPane(0,1

10、);/ m_pEditViewright 已定义。 ii. 在 CmainFrame 获取视图的指针: CMyEditView* pView=(CMyEditView*)this-m_wndSplitter.GetPane(0,1); 这样就行了,同样在文档里获取视图的方法也可以类似,这里就不重复了,但我强调一点要注意头文件的加入。 四 单文档多视的实现: a) 单框架窗口中的多视: 获取你要处理的两个视图指针: pViewAdd,pViewRemove: / 显示活动视而隐藏非活动视 pViewAdd-ShowWindow(SW_SHOW); pViewRemove-ShowWindow(S

11、W_HIDE); / 将新的活动视连接到文档,并断开原来的视与文档的连接。 pDoc-AddView(pViewAdd); pDoc-RemoveView(pViewRemove); SetActiveView(pViewAdd); RecalcLayout();/告知当前分割窗口,重新显示。 方法二你可以把其中的一个视图移到看不到的地方,活动视变换时就是移动的变换。 方法三你可以先删去其中的一个视图,需要时再重建,然后删去那个视图。 这两个方案在下面再详细说明吧! b) 单文档分割视图的某分割区的多视的实现 i. 移动视图 获取视图指针 pView pView-SetWindowPos(0,

12、 0, 1000, 1500, 1000, SWP_SHOWWINDOW); 这样移动后在当前窗口下你一般是看不到你移动的视图,但当你改变窗口的大小时,有什么情况发生,没有达到你的期望吧,行,你在 OnSize 这个函数里加入一些代码,比较简单我就不说了。 ii. 删除视图 m_wndSplitter1.DeleteView(0,0); / 删除原来的视 运行一下程序还可以,发现我们删除的视图上点击无事件发生,而且出现中断程序。显然只有这句话还不行的,这就要按照你的要求把窗口重新分割一下或者使用一个新的视图来填充一下。 重新分割可以用 CMainFrame:OnCreateClient 里的代

13、码的方法实现它,在这里我就不重复了。 五视图间的通信: 在前面我已经把获取视图的指针作为一大点来解释,其实在不要讲很多大家就会明白的,因为你不管是关联还是不关联的视图,你只要获取它的指针就可以对它进行任意的操作,甚至它的私有函数(当然不能直接了) 。下面我就举一例。 在 CviewView1 里加入一个公共函数 void simple(); 如果你要实现的一些功能就可以写在这个函数里 void CviewView1:simple() CClientDC dc(this); dc.TextOut(0,0,“我要实现视图间的通信,我一定会成功的!“); void CviewView2:OnLBut

14、tonDblClk(UINT nFlags, CPoint point) CMainFrame* MainFrame1=(CMainFrame*)this-GetParent()-GetParent(); CMyEditView* pView=(CMyEditView*)MainFrame1-m_wndSplitter.GetPane(0,1); pView-simple(); 六CSplitterWnd 的扩展: 为什么要扩展 CSplitterWnd 呢?这是从整个界面来想的,当你分割窗口之后就不希望拖动分割条时它位置的改变,你也需要在分割条上有希望的颜色的出现,这时就要扩展 CSplit

15、terWnd 一下,其实扩展东西很多,我也只简单说一下吧! 不希望通过拖动分割条来调节窗口的大小,你就要锁定分割条,根据你的需要让 CWnd 窗口蔽掉这些消息 void CSplitterWnd:onMouseMove(UINT nFlags,CPoint point) CWnd:onMouseMove (nFlags,point); 七使用视图控件。 在 VC+里的 MFC 提供了三个视图控件:图象列表控件,列表视图控件,树型视图控件。 图象列表控件和列表视图控件都使用的类:CListCtrl。 树型视图控件使用的类:CTreeCtrl。 具体的控件功能不是本文所讨论的范围。 使用视图控件我

16、们可以不向上面那样要分割窗口,你能够在视图里直接添加视图控件,但是很显然有个缺陷:只有上面三个控件,这样它的使用范围很小,有时很难达到多种视图的混用。 CListCtrl m_ListView; CTreeCtrl m_TreeView; 在你向导生成的视图里定义这两个变量,然后在你需要的地方使用下面的函数: BOOL Create( DWORD dwStyle, const RECT const RECT l wParam 参数是发送消息的控件 ID,如果不来自控件,那么该参数为 NULL。 l LParam 是指向通知消息结构(NMHDR)的指针,它包含当前的通知代码和某些其他信息。 l

17、PResult 参数是指向 LRESULT 变量的指针,如果消息被处理,该变量用于存放结果代码。 BOOL CView:OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) / TODO: Add your specialized code here and/or call the base class TV_DISPINFO *tv_dispinfo=(TV_DISPINFO *)lParam; if (tv_dispinfo-hdr.code=NM_CLICK) 这就是一个这种消息机制的简单的例子,你要实现的功能就放在 if 后的

18、里。 八文档与视图的一种常见出错的处理: error C2143: syntax error : missing ; before * error C2501: CMyViewDoc : missing storage-class or type specifiers error C2501: Getdocument#39; : missing storage-class or type specifiers 这种错误一般出现在视图的公共变量函数的定义处: CMyViewDoc* Getdocument); 我刚学 VC 不久,而且不习惯看英文,所以也不知道它出错的原因在哪里,有谁知道不忘告诉我一声了。 我一般这样处理之后就好了,先在定义前面加“/”,把它屏蔽掉,按 F7,再把“/”去掉,按 F7,一看没错了,真的很神了。我在怀疑是不是 VC+6.0 的一个小小的 BUG。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报