AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > VC编程

文档与视图的建立和关联

51自学网 2015-08-30 http://www.wanshiok.com

 

四.  单文档多视的实现:

a)     单框架窗口中的多视:

获取你要处理的两个视图指针: pViewAdd,pViewRemove:

// 显示活动视而隐藏非活动视
  pViewAdd->ShowWindow(SW_SHOW);
  pViewRemove->ShowWindow(SW_HIDE);
  // 将新的活动视连接到文档,并断开原来的视与文档的连接。
  pDoc->AddView(pViewAdd);
  pDoc->RemoveView(pViewRemove);
  SetActiveView(pViewAdd);
  RecalcLayout();//告知当前分割窗口,重新显示。

方法二你可以把其中的一个视图移到看不到的地方,活动视变换时就是移动的变换。

方法三你可以先删去其中的一个视图,需要时再重建,然后删去那个视图。

这两个方案在下面再详细说明吧!

b)    单文档分割视图的某分割区的多视的实现

             i.       移动视图

获取视图指针pView

  pView->SetWindowPos(0, 0, 1000, 1500, 1000, SWP_SHOWWINDOW);

这样移动后在当前窗口下你一般是看不到你移动的视图,但当你改变窗口的大小时,有什么情况发生,没有达到你的期望吧,行,你在OnSize这个函数里加入一些代码,比较简单我就不说了。

            ii.       删除视图

m_wndSplitter1.DeleteView(0,0); // 删除原来的视

运行一下程序还可以,发现我们删除的视图上点击无事件发生,而且出现中断程序。显然只有这句话还不行的,这就要按照你的要求把窗口重新分割一下或者使用一个新的视图来填充一下。

重新分割可以用CMainFrame::OnCreateClient里的代码的方法实现它,在这里我就不重复了。

五.视图间的通信:
在前面我已经把获取视图的指针作为一大点来解释,其实在不要讲很多大家就会明白的,因为你不管是关联还是不关联的视图,你只要获取它的指针就可以对它进行任意的操作,甚至它的私有函数(当然不能直接了)。下面我就举一例。

在CviewView1里加入一个公共函数void simple();

如果你要实现的一些功能就可以写在这个函数里

void CviewView1::simple()

{

    CClientDC dc(this);

dc.TextOut(0,0,"我要实现视图间的通信,我一定会成功的!");

}

void CviewView2::OnLButtonDblClk(UINT nFlags, CPoint point)

{

CMainFrame* MainFrame1=(CMainFrame*)this->GetParent()->GetParent();

CMyEditView* pView=(CMyEditView*)MainFrame1->m_wndSplitter.GetPane(0,1);

pView->simple();

}

六.CSplitterWnd的扩展:

为什么要扩展CSplitterWnd呢?这是从整个界面来想的,当你分割窗口之后就不希望拖动分割条时它位置的改变,你也需要在分割条上有希望的颜色的出现,这时就要扩展CSplitterWnd一下,其实扩展东西很多,我也只简单说一下吧!

不希望通过拖动分割条来调节窗口的大小,你就要锁定分割条,根据你的需要让CWnd窗口蔽掉这些消息

void CSplitterWnd::onMouseMove(UINT nFlags,CPoint point)
{
 CWnd::onMouseMove (nFlags,point);
}

七.使用视图控件。

在VC++里的MFC提供了三个视图控件:图象列表控件,列表视图控件,树型视图控件。
图象列表控件和列表视图控件都使用的类:CListCtrl。

树型视图控件使用的类:CTreeCtrl。

具体的控件功能不是本文所讨论的范围。

使用视图控件我们可以不向上面那样要分割窗口,你能够在视图里直接添加视图控件,但是很显然有个缺陷:只有上面三个控件,这样它的使用范围很小,有时很难达到多种视图的混用。

CListCtrl m_ListView;

CTreeCtrl m_TreeView;

在你向导生成的视图里定义这两个变量,然后在你需要的地方使用下面的函数:

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

const RECT& rect就是它的位置,选择适当的地方就能实现分割条的一些功能。

其实这些方面不是难点,关键在于如何获得它,产生消息映射是最为困难的地方。在这里你就无法使用以前的消息传递方法,首先我们来简单地理解一下消息机制,由于不同的消息是由操作系统的不同部分或是有应用程序来控制的。当鼠标左键在单击时,这个点击区窗口就收到WM_LBUTTONDOWN消息并处理它,通常它产生一个消息发送给它的主窗口(包含它的窗口),报告“我被单击了。”Win32常用控件将WM_NOTIFY通知发送给它的父窗口,作为应答,MFC调用CWnd::OnNotify()方法来处理这些消息,可以为控件的所有者类重载CWnd::OnNotify()方法。

virtual BOOL CWnd::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult );

l     wParam参数是发送消息的控件ID,如果不来自控件,那么该参数为NULL。

l     LParam是指向通知消息结构(NMHDR)的指针,它包含当前的通知代码和某些其他信息。

l     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后的{}里。

八.文档与视图的一种常见出错的处理:

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。

 
 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。

上一篇:动态子类化CComboBox以得到子控件EDIT及LISTBOX  下一篇:VC++中的数据类型