VC++6.0 单文档拆分与多视图通信(含DEMO)

学习VC也有一段时间了,总体感觉“太难、太复杂”,和C#、VB等其他可视化开发环境相比,上手比较难。正好有同学让我帮忙做一个VC作业,答应了,不过真没什么信心,不过花了一天的时间总算搞定。好了,闲话少说,来看看具体是什么东东。

题目:建一个单文档窗口,将视口切分成两个,一个放滑动条,另一个画图(随便画,矩形什么的都行),用窗口中的滑动条控制另一个窗口图形的大小和颜色。

分析:该题目主要是运用VC6.0的单文档拆分技术然后两个视图之间进行通信,一个View控制另一个View,另外还要用到滑动条类CSliderCtrl,绘图功能等。这还挺有难度。

下面先看我做的Demo:

下面介绍具体的实现过程:

一、实现单文档的拆分

1、首先创建一个单文档工程Demo

在利用类向导创建一个CControlView类,由于我们要添加如滑动条之类的控件,所以我们让CControlView类派生自CFromView类。

2、切分窗口

使用CSplitterWnd类进行切分,关于CSplitterWnd类的用法可参考VC6.0实现窗口的任意分割及视图间通信(转载)一文,这里不作具体讲解。在CMainFrame类中添加一个成员变量(具体数量视你拆分的窗口数量而定)CSplitterWnd  m_wndsplitter,然后在OnCreateClient函数中添加如下代码

1. BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
2. {
3.  // TODO: Add your specialized code here and/or call the base class
4.  m_wndsplitter.CreateStatic(this,1,2);
5.  m_wndsplitter.CreateView(0,0,RUNTIME_CLASS(CControlView),CSize(300,300),pContext);
6.  m_wndsplitter.CreateView(0,1,RUNTIME_CLASS(CDemoView),CSize(150,200),pContext);
7.  return TRUE;
8. }

Build 运行,我们可以看到这是程序会报错,错误提示如下:

C:/Users/Outshine/Desktop/Demo/MainFrm.cpp(114) : error C2653: 'CControlView' : is not a class or namespace name
C:/Users/Outshine/Desktop/Demo/MainFrm.cpp(114) : error C2065: 'classCControlView' : undeclared identifier
C:/Users/Outshine/Desktop/Demo/MainFrm.cpp(115) : error C2653: 'CDemoView' : is not a class or namespace name
C:/Users/Outshine/Desktop/Demo/MainFrm.cpp(115) : error C2065: 'classCDemoView' : undeclared identifier
Error executing cl.exe.
Creating browse info file...

Demo.exe - 4 error(s), 0 warning(s)
为什么呢?主要是缺少包含文件,我们在MainFrm.cpp文件中加入#include "DemoView.h"、#include "ControlView.h"即两个View类的头文件,这时我们在Build,仍然会出现错误,这个原因我在以前的博文中已经说明过,大家可参考VC中出现error C2143: syntax error : missing ';' before '*'错误的解决方案一文,有详细说明。好了,这些问题都解决了Build成功,运行就出现了单文档的拆分效果。

二、在CDemoView类中添加画图程序

由于最后实现的是CControlView类视图控制CDemoView类视图画图改变图形属性的效果,所以我们只需要在CDemoView中添加一个画图函数,在CControlView类中根据消息响应来调用这个画图函数即可,考虑一下,程序需要实现改变图形形状,图形大小,图形颜色等熟悉,所以画图函数需要三个参数UINT DrawType,CRect Rect,COLORREF RGB。下面是画图函数DrawImage的定义:

? 01. void CDemoView::DrawImage(UINT DrawType,CRect Rect,COLORREF RGB)
02. {
03.  this->Invalidate();
04.  this->UpdateWindow();
05.  CClientDC dc(this);
06.  CPen pen(PS_SOLID,10,RGB);
07.  dc.SelectObject(&pen);
08.  CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
09.  dc.SelectObject(pBrush);
10.  switch(DrawType)
11.  {
12.  case 1:
13.   dc.Rectangle(Rect);
14.   break;
15.  case 2:
16.   dc.Ellipse(Rect);
17.   break;
18.  }
19. }

三、在CControlView类中添加滑动条等控件

具体添加控件如上图所示,单选按钮控制画图形状,滑动条控制图形大小和图形颜色。

四、添加消息响应事件关联

为了实现CControlView类视图控制CDemoView类视图改变图形的属性。我们需要为单选按钮、滑动条添加消息响应。单选按钮具体见源文件,我们来看一下滑动条消息响应事件的添加:

1、添加相关变量

利用ClassWizard添加相关变量,滑动条添加CSliderCtrl类型的变量,如CSliderCtrl  m_Slider_Len等,具体变量类型如下图所示:

2、关联一个消息响应事件

同样利用ClassWizard添加消息响应,选中Objects ID 中选择 IDC_SLIDER_LEN,Message Map中选中NM_CUSTOMDRAW 添加编辑,下面是消息响应函数OnCustomdrawSliderLen的具体实现:

01. void CControlView::OnCustomdrawSliderLen(NMHDR* pNMHDR, LRESULT* pResult) 
02. {
03.  // TODO: Add your control notification handler code here
04.  m_Slider_Len.SetRange(150,500);
05.  m_Slider_Wid.SetRange(150,500);
06.  m_Slider_R.SetRange(0,255);
07.  m_Slider_G.SetRange(0,255);
08.  m_Slider_B.SetRange(0,255);
09.  UpdateData(true);
10.  m_len=m_Slider_Len.GetPos();
11.  m_wid=m_Slider_Wid.GetPos();
12.  m_red=m_Slider_R.GetPos();
13.  m_green=m_Slider_G.GetPos();
14.  m_blue=m_Slider_B.GetPos();
15.  Rect=CRect(100,100,m_len,m_wid);
16.  RGB=RGB(m_red,m_green,m_blue);
17.  UpdateData(false);
18.  *pResult = 0;
19. }

注意:为了使多个滑动条同时关联OnCustomdrawSliderLen函数,需要修改映射表,将controlView.cpp中的映射表

BEGIN_MESSAGE_MAP(CControlView, CFormView)
 //{{AFX_MSG_MAP(CControlView)
 ON_BN_CLICKED(IDC_RECT, OnRect)
 ON_BN_CLICKED(IDC_ELLI, OnElli)
 ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_LEN,IDC_SLIDER_WID, OnCustomdrawSliderLen)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

修改为

BEGIN_MESSAGE_MAP(CControlView, CFormView)
 //{{AFX_MSG_MAP(CControlView)
 ON_BN_CLICKED(IDC_RECT, OnRect)
 ON_BN_CLICKED(IDC_ELLI, OnElli)
 ON_NOTIFY_RANGE(NM_CUSTOMDRAW, IDC_SLIDER_LEN,IDC_SLIDER_WID, OnCustomdrawSliderLen)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

这时,我们Build运行程序,发现,拖动滑动条已经能够改变编辑框中的数字了,说明消息响应添加成功。但如何控制CDemoView类视图实现画图呢?

四、实现视图间通信

视图间通信方式有多种,可参考VC6.0实现窗口的任意分割及视图间通信(转载)一文,下面是具体源码,不多说了。

1. CMainFrame * pMainFrm = (CMainFrame*)AfxGetMainWnd(); 
2. CDemoView *m_this = (CDemoView*)pMainFrm->m_wndsplitter.GetPane(0,1);
3. m_this->DrawImage(m_nDrawType,Rect,RGB);     //为CDemoView设置图像样式,当然了要在CDemoView类中添加一个DrawImage函数

实现视图通信后的OnCustomdrawSliderLen函数。

01. void CControlView::OnCustomdrawSliderLen(NMHDR* pNMHDR, LRESULT* pResult) 
02. {
03.  // TODO: Add your control notification handler code here
04.  m_Slider_Len.SetRange(150,500);
05.  m_Slider_Wid.SetRange(150,500);
06.  m_Slider_R.SetRange(0,255);
07.  m_Slider_G.SetRange(0,255);
08.  m_Slider_B.SetRange(0,255);
09.  UpdateData(true);
10.  m_len=m_Slider_Len.GetPos();
11.  m_wid=m_Slider_Wid.GetPos();
12.  m_red=m_Slider_R.GetPos();
13.  m_green=m_Slider_G.GetPos();
14.  m_blue=m_Slider_B.GetPos();
15.  Rect=CRect(100,100,m_len,m_wid);
16.  RGB=RGB(m_red,m_green,m_blue);
17.  UpdateData(false);
18.  CMainFrame * pMainFrm = (CMainFrame*)AfxGetMainWnd(); 
19.  CDemoView *m_this = (CDemoView*)pMainFrm->m_wndsplitter.GetPane(0,1);
20.  m_this->DrawImage(m_nDrawType,Rect,RGB);     //为CDemoView设置图像样式,当然了要在CDemoView类中添加一个DrawImage函数

好了就写到这里了,欢迎大家批评留言。

最后是Demo的下载地址:VC++6.0 单文档拆分与多视图通信(含滑动条改变图像颜色实例)

相关文章:

VC6.0实现窗口的任意分割及视图间通信(转载)

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值