dedecms织梦内容管理系统    
首页 | java | C/C++ | PHP | 操作系统 | ajax | 脚本编程 | 安全技术 | 本站下载页 | flex | CRM | 专题 | QQ群 | 测试中心 | 会员中心 | 积分规则
  当前位置:主页>C/C++>文章内容
使用VC6.0实现窗口的任意分割
来源: vckbase 作者: 张中庆 <

  一、关于CSplitterWnd类

  我们在使用CuteFtp或者NetAnt等工具的时候,一般都会被其复杂的界面所吸引,在这些界面中窗口被分割为若干的区域,真正做到了窗口的任意分割。 那么我们自己如何创建类似的界面,也实现窗口的任意的分割呢 ?在VC6.0中这就需要使用到CSplitterWnd类。CSplitterWnd看上去像是一种特殊的框架窗口,每个窗口都被相同的或者不同的视图所填充。当窗口被切分后用户可以使用鼠标切分条来调整窗口的相对尺寸。虽然VC6.0支持从AppWizard中创建分割窗口,但是自动加入的分割条总是不能让我们满意,因此我们还是通过手工增加代码来熟悉这个类。

  CSplitterWnd的构造函数主要包括下面三个。

BOOL Create(CWnd* pParentWnd,int nMaxRows,int nMaxCols,SIZE sizeMin,CCreateContext* pContext,DWORD dwStyle,UINT nID);
  功能描述:该函数用来创建动态切分窗口。 参数含义:pParentWnd 切分窗口的父框架窗口。 nMaxRows,nMaxCols是创建的最大的列数和行数。 sizeMin是窗格的现实大小。 pContext 大多数情况下传给父窗口。 nID是字窗口的ID号.
BOOL CreateStatic(CWnd* pParentWnd,int nRows,int nCols,DWORD dwStyle,UINT nID) 
  功能描述:用来创建切分窗口。 参数含义同上。
BOOL CreateView (int row,int col,CruntimeClass* pViewClass,SIZE sizeinit,CcreateContext* pContext);
  功能描述:为静态切分的窗口的网格填充视图。在将视图于切分窗口联系在一起的时候必 须先将切分窗口创建好。

  参数含义:同上。

  从CSplitterWnd源可以看出不管是使用动态创建Create还是使用静态创建CreateStatic,在函数中都调用了一个保护函数CreateCommon,从下面的CreateCommon函数中的关键代码可以看出创建CSplitterWnd的实质是创建了一系列的MDI子窗口。
DWORD dwCreateStyle = dwStyle & ~(WS_HSCROLL|WS_VSCROLL);

if (afxData.bWin4) 

       dwCreateStyle &= ~WS_BORDER; //create with the same wnd-class as MDI-Frame (no erase bkgnd) 

if (!CreateEx(0, _afxWndMDIFrame, NULL, dwCreateStyle, 

          0, 0, 0, 0,pParentWnd->m_hWnd, (HMENU)nID, NULL)) 

       return FALSE; // create invisible 

          
  二、创建嵌套分割窗口

  2.1创建动态分割窗口

  动态分割窗口使用Create方法。下面的代码将创建2x2的窗格。
m_wndSplitter.Create(this,2,2,CSize(100,100),pContext);
  但是动态创建的分割窗口的窗格数目不能超过2x2,而且对于所有的窗格,都必须共享同一个视图,所受的限制也比较多,因此我们不将动态创建作为重点。我们的主要精力放在静态分割窗口的创建上。

  2.2创建静态分割窗口


  与动态创建相比,静态创建的代码要简单许多,而且可以最多创建16x16的窗格。不同的窗格我们可以使用CreateView填充不同的视图。

  在这里我们将创建CuteFtp的窗口分割。CuteFtp的分割情况如下:

CCuteFTPView
CView2
CView3
CView4

  创建步骤:

  ▲ 在创建之前我们必须先用AppWizard生成单文档CuteFTP,生成的视类为 CCuteFTPView.同时在增加三个视类或者从视类继承而来的派生类CView2,CView3 CView4.

  ▲ 增加成员:

  在Cmainfrm.h中我们将增加下面的代码:

CSplitterWnd wndSplitter1;
CSplitterWnd wndSplitter2;

  ▲ 重载CMainFrame::OnCreateClient()函数:
BOOL CMainFrame::OnCreateClient( LPCREATESTRUCT  /*lpcs*/, CCreateContext* pContext) 

{ //创建一个静态分栏窗口,分为三行一列 

     if(m_wndSplitter1.CreateStatic(this,3,1)==NULL) 

              return FALSE;

  //将CCuteFTPView连接到0行0列窗格上

     m_wndSplitter1.CreateView(0,0,RUNTIME_CLASS(CCuteFTPView),CSize(100,100), pContext); 

     m_wndSplitter1.CreateView(2,0,RUNTIME_CLASS(CView4),CSize(100,100),pContext); 

  //将CView4连接到0行2列

     if(m_wndSplitter2.CreateStatic(&m_wndSplitter,1,2,WS_CHILD|WS_VISIBLE, 

          m_wndSplitter.IdFromRowCol(1, 0))==NULL) 

               return FALSE; //将第1行0列再分开1行2列 

  //将CView2类连接到第二个分栏对象的0行0列

          m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CView2),CSize(400,300),pContext); 

  //将CView3类连接到第二个分栏对象的0行1列

          m_wndSplitter2.CreateView(0,1,RUNTIME_CLASS(CView3),CSize(400,300),pContext); 

               return TRUE; 

} 
  2.3实现各个分割区域的

  ■有文档相连的视图之间的通信

  由AppWizard生成的CCuteFTPView是与文档相连的,同时我们也让CView2与文档相连,因此我们需要修改CCuteFTPApp的InitInstance()函数,我们将增加下面的部分。
AddDocTemplate (new CMultiDocTemplate(IDR_VIEW2TYPE, 

          

          RUNTIME_CLASS(CMainDoc), 

          RUNTIME_CLASS(CMDIChildWnd), 

          RUNTIME_CLASS(CView2))); 
  我们现在来实现CCuteFTPView与CView2之间的通信。由于跟文档类相连的视图类 是不能安全的与除文档类之外的其余的视图类通信的。因此我们只能让他们都与文档 类通信。在文档中我们设置相应的指针以用来获的各个视图。我们重载 CCuteFTPView::OnOpenDocument()函数。

CCuteFTPView* pCuteFTPView;
CView2* pView2; POSITION pos; CView* pView; while(pos!=NULL) { pView=GetNextView(pos); if(pView->IsKindOf(RUNTIME_CLASS(CCuteFTPView))==NULL) pCuteFTPView=(CCuteFTPView*)pView; else(pView->IsKindOf(RUNTIME_CLASS(CCuteFTPView))==NULL) pView2=(CView2*)pView; }
  这样我们在文档类中就获的了跟它相连的所有的视图的指针。

  如果需要在 CCuteFTPView中调用CView2中的一个方法DoIt()则代码如下:
CCuteFTPDoc* pDoc=GetDocument();
CView2* pView2=pDoc->pView3;
pView3.DoIt();
  ■无文档视图与文档关联视图之间的通信

  CView3和CView4都是不与文档相关联的。我们现在实现CView3与CView2的通信.正如前面所说,CView2只能安全的与CCuteFTPDoc通信,因此,CView3如果需要跟CView2通信,也必须借助于文档类。因此程序的关键是如何在CView3中获得文档的指针。视图类中没有这样的类成员可以用来直接访问文档类。但是我们知道在主窗口类MainFrame中我们可以获得程序的任意窗口类的指针。因此我们只要获得程序主窗口了的指针,就可以解决问题了。代码实现在CView3中访问CView2中的DoIt()方法。

  CView3中的代码如下:
CMainFrame* MainFrame=(CMainFrame*)this->GetParent()->GetParent(); 

          

          CCuteFTPDoc* Doc=(CCuteFTPDoc*)MainFrame->GetActiveDocument();

          if(Doc!=NULL) Doc->DoIt(); 

          

          CCuteFTPDoc中的相应的处理函数DoIt()代码如下: 

          

          CView2* pView2; 

          POSITION pos; 

          CView* pView; 

          while(pos!=NULL) 

          { 

                  pView=GetNextView(pos);

                  if(pView->IsKindOf(RUNTIME_CLASS(CView2))==NULL) 

                  pView2=(CView2*)pView; 

          } 

          pView2->DoIt(); 
  无文档关联视图之间的通信

  CView3和CView4都是不跟文档相连的,如何实现他们之间的通信呢。 正如我们在上面所说的那样,由于在主框架中我们可以访问任意的视图,因此我们的主要任 务还是在程序中获得主框架的指针。在CView3中访问CView4中的方法DoIt()。
CMainFrame* MainFrame=(CMainFrame*)this->GetParent()->GetParent(); 

          

          CView4* View4=(CView4*)MainFrame->m_wndSplitter1.GetPane(2,0); 

          View4->DoIt(); 
  到现在我们已经实现了CuteFTP的主窗口的框架并且能够实现他们之间相互通信的框架。 同样的我们可以实现其他的一些流行界面例如NetAnts,Foxmail的分割。
共2页。 1 :

上一篇:摆脱DLL"地狱"的困扰之获取进程的命令行   下一篇:VC和Delphi程序只运行一个实例的方法
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论
  热点文章
·C语言学习
·C语言指针
·C语言数组排序小结
·c语言 最简单的推箱子游戏
·c语言 全国计算机编程大赛复赛试
·c语言 全国计算机编程大赛复赛试
·c++ 数组与指针
·C++中的内存管理(new、delete、
·如何用C语言开发DSP嵌入式系统
·如何用C语言开发DSP嵌入式系统
·Linux下C语言编程
·学习arm的话先看哪本书?
  相关文章
·摆脱DLL"地狱"的困扰之获取进程
·VC和Delphi程序只运行一个实例的
·实现MFC扩展DLL中导出类和对话框
·解读VC++编程中的文件操作API和C
·掀起你的盖头来——谈VC++对象模
·VC中利用原始套接字实现网络监听
·双缓冲技术及其在VC的GDI环境下
·基于Visual C++6.0的声音文件操
·VC中用DAO实现树型控件的数据库
·用VC++制作播放AVI视频流的动画
·深入浅出VC++串口编程之短信应用
·利用MFC文档视图框架编写打印程
  相关信息
copy right @ 百家拳软件项目研究室 2007 辽ICP备07011763