监控系统界面问题:在基于对话框的工程中如何实现多画面切换 监控系统界面问题:在基于对话框的工程中,想要在一个控件中实现多画面,并用按钮选择切换1/4/9/16画面。请高手指点,越详细越好!分不够再加。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 从CWnd派生一个类,在该类中实现1/4/9/16界面的分隔! to Hopping(♂风中尘埃♂):多谢!能否再具体一点!? 从CWnd派生一个类,然后注意分隔线、大小、索引。然后生成16个类对象,Create它们,显示1画面,就ShowWindow(SW_HIDE)其他15个画面,显示4画面,就ShowWindow(SW_HIDE)其他12个画面。注意切换时的MoveWindow。具体较为复杂,坐标要考虑仔细,大致思路就是这样,看看有没有帮助。 画面用CWND类处理,在控件中根据需要的个数创建 不知可否用控件Picture,通过按钮来控制picture显示的个数,4画面的显示4个大的picture,16画面的显示16个小的picture。当你在那个画面上连上摄像机的同时就让那个picture不显示,当关闭摄像机连接时再让pictrue显示出来。 谢谢各位!to bulesnow(benben):你好,这几天休息,回家了。 用VC5开发监控界面的方法 南京师范大学物理系 伶俐 黄斌 顾敏芬 VC5开发工具提供了现成的窗口、控制与工具条的制作手段,大大简化了界面的开发 过程,并且使得开发出的界面具有组态软件风格,使用起来方便、灵活、简单易学。 本文以一实例介绍如何实现三个独立的分离窗口:监视窗口,控制窗口和动画窗口, 并以图1中的进水和温度值传递为例,介绍如何实现控制功能和不同窗口间的数据共享, 并介绍实现无闪烁动画的方法。 (图略) 如图1,将工作台分离成为三个窗口,动画窗口用于模拟锅炉的进、出水、升温的画 面显示,其中的画面与系统采集的数据相对应。控制窗口用于实现预设温度值,调节水位、 控制加热、暂停等功能。监视窗口用来实时跟踪采样的温度值,作出温度--时间曲线。 一、创立分离窗口 要实现多窗口显示,必须使用CSplitterWnd类,将窗口分成三个子窗口,然后将各个 功能类与窗口联系起来。在创建应用程序时,在第一步中选择Single Document Interface, 并 选用中文字库,在第4步中按下Advanced,选择Use Split Window选项。设定应用程序名 为Animation。目前我们只有一个视类CAnimationView,它将与动画窗口对应,此外我们 还要生成具有对话功能的监视窗口(对应CShowView类)和控制窗口(对应 CControlView 类)。在Resource View中调出上下文菜单并选择Insert,选择属性为IDD_FORMVIEW,创 建监视对话框IDD_SHOWVIEW和控制对话框IDD_CONTROLVIEW,并单击鼠标右键在 Properties选择项中选择中文字库。然后编辑IDD_CONTROLVIEW:利用VC5提供的控件 生成器生成ID名为IDC_SETTEMPERATURE的文字编辑域,并生成Caption为"设置温 度初始值"。再利用button生成器,生成控件IDC_WATERIN,IDC_CONFIRM,Caption 分别为"进水"和"确认"。再利用ClassWizard,创建基于CFormView类的新类,分别为 CShowView和CControlView类,并将它们与刚创建的两个对话框联系。 在CMainFrame类中,重载OnCreateClient()函数创建三个静态分离窗口,先在 MainFrame.h中声明所需变量: protected: CSplitterWnd m_wndSplitter2; 转入MainFrame.cpp程序,在开头处包含头文件"ShowView.h",向下找到函数 OnCreateClient(),添加如下代码,生成两个窗口,三个视图: BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT/*lpcs*/,CCreateContext* pContext) { //先分裂成两个窗口,一行两列 if(!m_wndSplitter.CreateStatic(this,1,2)) { TRACE0("Failed to CreateStaticSplitter\n"); return FALSE; } // 加上动画窗口,将其放在左边 if(!m_wndSplitter.CreateView(0,0,pContext->m_pNewViewClass,CSize(425,50),pContext)) { TRACE0("Failed to create first pane\n"); return FALSE; } //将第二个窗口再一分为二 if(!m_wndSplitter2.CreateStatic( &m_wndSplitter, //原来的m_wndSplitter是父指针,m_wndSplitter2是子指针 2,1, //窗口分为两行,一列 WS_CHILD|WS_VISIBLE|WS_BORDER,m_wndSplitter.IdFromRowCol(0,1))) { TRACE0("Failed to create nested splitter\n"); return FALSE; } //增加两个视图,并调整视图大小 if(!m_wndSplitter2.CreateView(0,0, RUNTIME_CLASS(CShowView),CSize(0,175),pContext)) { TRACE0("Failed to create second pane\n"); return FALSE; } if(!m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CControlView), CSize(0,0),pContext)) { TRACE0("Failed to create third pane\n"); return FALSE; } return TRUE; } 再转入Animation.cpp中,修改InitInstance()函数,将其中的m_pMainWnd->ShowWindow (SW_SHOW),改为m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);至此,我们 可以生成图1的界面框架。 二、动画显示窗口的实现 动画是通过调用一幅幅的图片来实现的,因此先将所需的画面载入资源BITMAP中, 并按顺序编辑它们的ID号,然后在定时器中,每隔一定的时间调用一次动画函数。第一 步先生成定时器,用ClassWizard给CAnimationView添加消息处理程序:OnCreate()函数 对应于消息WM_CREATE,OnTimer()函数对应于消息WM_TIMER。编辑函数OnCreate(), 生成每隔0.1秒的时钟。 int CAnimationView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CView::OnCreate(lpCreateStruct)= = -1) return -1; SetTimer(2,100,NULL); //产生每隔0.1秒的时钟 return 0; } 在函数OnTimer()中,调用动画服务函数ServicedAnimation(),该函数根据系统情况作出 无闪烁动画,并可以根据不同的功能,选择画面。 void CAnimationView::OnTimer(UINT nIDEvent) { CClientDC ClientDC(this); ServicedAnimation(&ClientDC); //调用动画服务函数 CView::OnTimer(nIDEvent); } ServicedAnimation()用于检查系统的时钟,并能计算从发生最后一个动画事件开始计算 起所经过的时间,然后这个函数检查本帧动画的延迟时间,并决定是否到达了另一次更新 的时间,若到了另一次更新的时间,那么m_nCurrentFrame变量就增加,此时若进水标志 成功,则调用DrawWaterinAnimation(),开始新一帧动画画面。如果由于其它原因造成了 到达ServicedAnimation()函数的延迟也计算在内。 先在CAnimationView中,定义变量: public: DWORD mLastEventServiced; BOOL m_bPause, m_bDone; //暂停、动画终点标志 int m_nCurrentFrame, m_nFrame; //当前的动画帧数,总动画帧数 构造函数中,添加: CAnimationView::CAnimationView() { mLastEventServiced=0; m_bPause=FALSE; m_bDone=FALSE; m_nCurrentFrame=0; m_nFrame=100; //图画的帧数设为100幅 } 编辑ServicedAnimation()函数: void CAnimationView::ServicedAnimation(CDC* pDC) { DWORD Elapsed=0L; DWORD FirstSample=::GetTickCount(); DWORD WorkValue=mLastEventServiced; CAnimationDoc *pDoc=(CAnimationDoc*) GetDocument(); ASSERT(pDoc->IsKindOf(TUNTIME_CLASS(CAnimationDoc))); if(m_bPause||m_bDone) return; //如果动画被暂停或结束,就返回 while(FirstSample!=WorkValue) { WorkValue++; Elapsed++; } //如果Elapsed达到其阈值点,并满足或超过这帧动画的延迟值,则可进入下一个代码 //信息块,这样,动画顺序将移动到下一帧: if(Elapsed>=1L) //设置每帧动画的延迟值都为1 { m_nCurrentFrame++; if(m_nCurrentFrame>=m_nFrame) { m_nCurrentFrame=0; //将要开始时,应把帧记数置于零 if(!pDoc->m_bWaterInFlagDoc) { m_nCurrentFrame=m_nFrame-1; m_bDone=TRUE; } if(pDoc->m_bWaterInFlagDoc&&!m_bDone) { DrawAnimationWaterIn(pDC); m_bWaterInFlagDoc=FALSE; mLastEventServicced=::GetTickCount(); // 把系统当前的时钟记录下来 } } } DrawAnimationWaterIn()为显示不同的进水水位的画面的函数,要连续显示画面,应将 一幅幅位图声明成一个静态数组。 Static int bitmapswaterin[]= {IDB_WATERIN1, IDB_WATERIN2 ...... IDB_WATERIN100}; 利用ClassWizard声明CAnimationView的变量: protected: CBitmap bmpWI[100]; CDC dcMemWI[100]; BITMAP bmWI; 在CAnimationView的构造函数里添加如下语句: for(int i=0;i<100;i++) { bmpWI[i].LoadBitmap(bitmapswaterin[i]); bmpWI[i].GetObject(sizeof(BITMAP),&bmWI[i]); } 编辑DrawAnimationWaterIn()函数,在此函数中,应重新声明bmpWI[100],dcMemWI[100] 为局部变量,这样当重新调用同一幅位图时,可以及时刷新内存,不会引起冲突。 void CAnimationView: DrawAnimationWaterIn(CDC* pDC) { CBITMAP bmpWI[100]; CDC dcMemWI[100]; CRect rect; GetClientRect(rect); //选择当前用户使用的矩形视窗 dcMemWI[m_nCurrentFrame].CreateCompatibleDC(pDC); //在内存中准备图象 bmpWI[m_nCurrentFrame].LoadBitmap(bitmapsWaterIn[m_nCurrentFrame]);// 装载一个 //由lpszResourcceName标识的位图资源,并将它连接到CBitmap对象上 CBitmap *pOldBitmapIn=dcMemWI[m_nCurrentFrame].SelectObject (&bmpWI[m_nCurrentFrame] ); //将GDI对象选入设备描述表 pDC->BitBlt((recct.right-bmWI[m_nCurrentFrame].bmWidth)/2, (rect.bottom-bmWI[m_nCurrentFrame].bmHeight)/2,//位图放在视窗正中 bmWI[m_nCurrentFrame].bmWidth,bmWI[m_nCurrentFrame].bmHeight, &dcMemWI[m_nCurrentFrame],0,0,SRCCOPY);//显示位图 dcMemWI[m_nCurrentFrame].SelectObject(pOldBitmapIn); } 三、控制窗口功能的实现 利用ClassWizard中的Member Variables标签为CControlView增加成员变量。 控件 控件ID 类型 成员 预设温度值 IDC_SETTEMPERATURE int m_nSetTemperature 在CControlView中增加消息处理函数: 对象 对象ID 函数 消息 进水按键 IDC_WATERIN OnWaterIn() BN_CLICKED 确认按键 IDC_CONFIRM OnComfirm() BN_CLICKED 下面以输入预设温度值和进水响应为例,来讲述如何实现控制功能。当控制视窗 (CControlView类)中预置温度设定之后,按下确认键即响应消息OnConfirm(),在监视视窗 (CShowView类)中的状态监测图中画一条预设温度的横线。当控制视窗(CControlView 类)中按下进水键,便在动画视图(CAnimationView类)有进水动画产生。 这时控制视图要向监视视图、动画视图传送数据,但它们之间无法直接实现数据共享。 MFC类库中CDocument类及其派生类用来管理工作数据,它能够读写和存储视图所要观 察和处理的数据,并可以同时拥有多个视图。所以,此处用CDocument的派生类 CAnimationDoc作为数据传输的中介,来实现不同视窗之间的数据传递。 预置温度(变量名为m_nSetTemperature)的数据传送示意图如图2所示。 m_nSetTemperature m_nSetTemperatureDoc 图2 省略 在CAnimationDoc中,设置公共变量: public: int m_nSetTemperatureDoc; //用来传递m_nSetTemperature的Document派生类变量 BOOL m_bSetTemperatureFlagDoc; //温度设置成功标志 BOOL m_bWaterInFlagDoc; //进水标志 在CAnimationDoc的构造函数中初始化变量: CAnimationDoc::CAnimationDoc() { m_nSetTemperatureDoc=0; m_bSetTemperatureFlagDoc=FALSE; m_bWaterInFlagDoc=FALSE; } 编辑CControlView的OnConfirm()函数: void CControlView::OnConfirm() { CAnimationDoc* pDoc=(CAnimationDoc*) GetDocument(); ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));//找到当前的 //CDocument类 UpdateData(); //更新视图数据 pDoc->m_nSetTemperatureDoc=m_nSetTemperature; pDoc->m_bSetTemperatureFlagDoc=TRUE; //预设温度成功标志 } 编辑CControlView的OnWaterIn()函数: void CControlView::OnWater() { CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument(); ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc))); pDoc->m_bWaterInFlagDoc=TRUE; //进水响应成功 } 最后在ControlView.cpp的开头包含"AnimationDoc.h"。 然后转入CShowView中,为了要能达到实时监测的目的,数据的接收要做在定时器中,这 样才可以不断地检测是否有新的数据输入。检测到温度设置标志后,画一条横线。 void CShowView::OnTimer(UINT nIDEvent) { CClientDC dc(this); CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument(); ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc))); UpdateData(); If(pDoc->m_bSetTemperatureFlagDoc) { dc.MoveTo(0,145-pDoc->m_nSetTemperatureDoc); dc.LineTo(400,145-pDoc->m_nSetTemperatureDoc); //画一条横线 pDoc->m_bSetTemperatureFlagDoc=FALSE; //保证只做一次 } CFormView::OnTimer(nIDEvent); } 同样,在CAnimationView中,编辑OnTimer()函数调用的过程ServicedAnimation(),检 测到进水键响应成功后,调用进水动画例程DrawAnimationWaterIn()。 四、监视窗口功能的实现 温度、水位跟踪实现的原理类似于控制功能,它实现的是CAnimatinDoc与CShowView 类之间的数据传递,当系统采样的温度与水位变化时,CShowView中的m_nTemperature(温 度变量)即随之变化,在利用MoveTo()与LineTo()函数,便可将其画在图上。再把这些做 在定时器当中,就可以实时监测。 参考文献: 1、《Visual C++5开发人员指南》David Bennett机械工业出版社 2、《Visual C++4开发人员指南》Scott Stanfield机械工业出版社 3、《MFC开发人员参考手册》 Robert D. Thompson机械工业出版社 to wdshrsh1977(猛汉要):谢谢 我们暂时用硬件完成压缩功能,直接采集摄像机过来的视频,以后要做基于MPEG4的,你们呢? [email protected] to bugyouth(有痔青年) : 你的资料我都有看过,和我的要求有所不同,不过还是非常感谢你。 http://expert.csdn.net/Expert/topic/1842/1842622.xml?temp=.9849665要分的进来 基于对话框 GetDlgItem debug assertion failed 两个进程,利用Event同步不起作用 VC6.0 一次能申请多大连续空间 这个加载资源的函数,是否有内存泄露? 使用ADO连接各种数据库的连接串怎么写? 如何才能任意改动对话框中控件的TAB顺序??????????????????? <<windows核心编程》光盘上的例子为什么编译通不过 谁能帮我实现双向链表的几个功能,感谢!!! 100分求助!!! 菜鸟提问???高分回报! List control控件的使用方法?? 如何用vc读写execel文件?
多谢!能否再具体一点!?
然后生成16个类对象,Create它们,显示1画面,就ShowWindow(SW_HIDE)其他15个画面,显示4画面,就ShowWindow(SW_HIDE)其他12个画面。
注意切换时的MoveWindow。具体较为复杂,坐标要考虑仔细,大致思路就是这样,看看有没有帮助。
to bulesnow(benben):你好,这几天休息,回家了。
黄斌
顾敏芬 VC5开发工具提供了现成的窗口、控制与工具条的制作手段,大大简化了界面的开发
过程,并且使得开发出的界面具有组态软件风格,使用起来方便、灵活、简单易学。 本文以一实例介绍如何实现三个独立的分离窗口:监视窗口,控制窗口和动画窗口,
并以图1中的进水和温度值传递为例,介绍如何实现控制功能和不同窗口间的数据共享,
并介绍实现无闪烁动画的方法。
(图略) 如图1,将工作台分离成为三个窗口,动画窗口用于模拟锅炉的进、出水、升温的画
面显示,其中的画面与系统采集的数据相对应。控制窗口用于实现预设温度值,调节水位、
控制加热、暂停等功能。监视窗口用来实时跟踪采样的温度值,作出温度--时间曲线。 一、创立分离窗口 要实现多窗口显示,必须使用CSplitterWnd类,将窗口分成三个子窗口,然后将各个
功能类与窗口联系起来。在创建应用程序时,在第一步中选择Single Document Interface, 并
选用中文字库,在第4步中按下Advanced,选择Use Split Window选项。设定应用程序名
为Animation。目前我们只有一个视类CAnimationView,它将与动画窗口对应,此外我们
还要生成具有对话功能的监视窗口(对应CShowView类)和控制窗口(对应 CControlView
类)。在Resource View中调出上下文菜单并选择Insert,选择属性为IDD_FORMVIEW,创
建监视对话框IDD_SHOWVIEW和控制对话框IDD_CONTROLVIEW,并单击鼠标右键在
Properties选择项中选择中文字库。然后编辑IDD_CONTROLVIEW:利用VC5提供的控件
生成器生成ID名为IDC_SETTEMPERATURE的文字编辑域,并生成Caption为"设置温
度初始值"。再利用button生成器,生成控件IDC_WATERIN,IDC_CONFIRM,Caption
分别为"进水"和"确认"。再利用ClassWizard,创建基于CFormView类的新类,分别为
CShowView和CControlView类,并将它们与刚创建的两个对话框联系。 在CMainFrame类中,重载OnCreateClient()函数创建三个静态分离窗口,先在
MainFrame.h中声明所需变量: protected:
CSplitterWnd m_wndSplitter2;
转入MainFrame.cpp程序,在开头处包含头文件"ShowView.h",向下找到函数
OnCreateClient(),添加如下代码,生成两个窗口,三个视图:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT/*lpcs*/,CCreateContext* pContext)
{
//先分裂成两个窗口,一行两列
if(!m_wndSplitter.CreateStatic(this,1,2))
{
TRACE0("Failed to CreateStaticSplitter\n");
return FALSE;
} // 加上动画窗口,将其放在左边
if(!m_wndSplitter.CreateView(0,0,pContext->m_pNewViewClass,CSize(425,50),pContext))
{
TRACE0("Failed to create first pane\n");
return FALSE;
} //将第二个窗口再一分为二
if(!m_wndSplitter2.CreateStatic(
&m_wndSplitter, //原来的m_wndSplitter是父指针,m_wndSplitter2是子指针
2,1, //窗口分为两行,一列
WS_CHILD|WS_VISIBLE|WS_BORDER,m_wndSplitter.IdFromRowCol(0,1)))
{
TRACE0("Failed to create nested splitter\n");
return FALSE;
} //增加两个视图,并调整视图大小
if(!m_wndSplitter2.CreateView(0,0,
RUNTIME_CLASS(CShowView),CSize(0,175),pContext))
{
TRACE0("Failed to create second pane\n");
return FALSE;
} if(!m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CControlView),
CSize(0,0),pContext))
{
TRACE0("Failed to create third pane\n");
return FALSE;
}
return TRUE;
} 再转入Animation.cpp中,修改InitInstance()函数,将其中的m_pMainWnd->ShowWindow
(SW_SHOW),改为m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);至此,我们
可以生成图1的界面框架。 二、动画显示窗口的实现 动画是通过调用一幅幅的图片来实现的,因此先将所需的画面载入资源BITMAP中,
并按顺序编辑它们的ID号,然后在定时器中,每隔一定的时间调用一次动画函数。第一
步先生成定时器,用ClassWizard给CAnimationView添加消息处理程序:OnCreate()函数
对应于消息WM_CREATE,OnTimer()函数对应于消息WM_TIMER。编辑函数OnCreate(),
生成每隔0.1秒的时钟。 int CAnimationView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CView::OnCreate(lpCreateStruct)= = -1)
return -1;
SetTimer(2,100,NULL); //产生每隔0.1秒的时钟
return 0;
}
在函数OnTimer()中,调用动画服务函数ServicedAnimation(),该函数根据系统情况作出
无闪烁动画,并可以根据不同的功能,选择画面。
void CAnimationView::OnTimer(UINT nIDEvent)
{
CClientDC ClientDC(this);
ServicedAnimation(&ClientDC); //调用动画服务函数
CView::OnTimer(nIDEvent);
}
ServicedAnimation()用于检查系统的时钟,并能计算从发生最后一个动画事件开始计算
起所经过的时间,然后这个函数检查本帧动画的延迟时间,并决定是否到达了另一次更新
的时间,若到了另一次更新的时间,那么m_nCurrentFrame变量就增加,此时若进水标志
成功,则调用DrawWaterinAnimation(),开始新一帧动画画面。如果由于其它原因造成了
到达ServicedAnimation()函数的延迟也计算在内。
先在CAnimationView中,定义变量:
public:
DWORD mLastEventServiced;
BOOL m_bPause, m_bDone; //暂停、动画终点标志
int m_nCurrentFrame, m_nFrame; //当前的动画帧数,总动画帧数
构造函数中,添加:
CAnimationView::CAnimationView()
{
mLastEventServiced=0;
m_bPause=FALSE;
m_bDone=FALSE;
m_nCurrentFrame=0;
m_nFrame=100; //图画的帧数设为100幅
}
编辑ServicedAnimation()函数:
void CAnimationView::ServicedAnimation(CDC* pDC)
{
DWORD Elapsed=0L;
DWORD FirstSample=::GetTickCount();
DWORD WorkValue=mLastEventServiced;
CAnimationDoc *pDoc=(CAnimationDoc*) GetDocument();
ASSERT(pDoc->IsKindOf(TUNTIME_CLASS(CAnimationDoc))); if(m_bPause||m_bDone) return; //如果动画被暂停或结束,就返回
while(FirstSample!=WorkValue)
{
WorkValue++;
Elapsed++;
}
//如果Elapsed达到其阈值点,并满足或超过这帧动画的延迟值,则可进入下一个代码
//信息块,这样,动画顺序将移动到下一帧:
if(Elapsed>=1L) //设置每帧动画的延迟值都为1
{
m_nCurrentFrame++;
if(m_nCurrentFrame>=m_nFrame)
{
m_nCurrentFrame=0; //将要开始时,应把帧记数置于零
if(!pDoc->m_bWaterInFlagDoc)
{
m_nCurrentFrame=m_nFrame-1;
m_bDone=TRUE;
}
if(pDoc->m_bWaterInFlagDoc&&!m_bDone)
{
DrawAnimationWaterIn(pDC);
m_bWaterInFlagDoc=FALSE;
mLastEventServicced=::GetTickCount(); // 把系统当前的时钟记录下来
}
}
}
DrawAnimationWaterIn()为显示不同的进水水位的画面的函数,要连续显示画面,应将
一幅幅位图声明成一个静态数组。 Static int bitmapswaterin[]= {IDB_WATERIN1,
IDB_WATERIN2 ...... IDB_WATERIN100}; 利用ClassWizard声明CAnimationView的变量:
protected:
CBitmap bmpWI[100];
CDC dcMemWI[100];
BITMAP bmWI;
在CAnimationView的构造函数里添加如下语句:
for(int i=0;i<100;i++)
{
bmpWI[i].LoadBitmap(bitmapswaterin[i]);
bmpWI[i].GetObject(sizeof(BITMAP),&bmWI[i]);
} 编辑DrawAnimationWaterIn()函数,在此函数中,应重新声明bmpWI[100],dcMemWI[100]
为局部变量,这样当重新调用同一幅位图时,可以及时刷新内存,不会引起冲突。
void CAnimationView: DrawAnimationWaterIn(CDC* pDC)
{
CBITMAP bmpWI[100];
CDC dcMemWI[100];
CRect rect;
GetClientRect(rect); //选择当前用户使用的矩形视窗
dcMemWI[m_nCurrentFrame].CreateCompatibleDC(pDC); //在内存中准备图象
bmpWI[m_nCurrentFrame].LoadBitmap(bitmapsWaterIn[m_nCurrentFrame]);// 装载一个
//由lpszResourcceName标识的位图资源,并将它连接到CBitmap对象上
CBitmap *pOldBitmapIn=dcMemWI[m_nCurrentFrame].SelectObject
(&bmpWI[m_nCurrentFrame] ); //将GDI对象选入设备描述表
pDC->BitBlt((recct.right-bmWI[m_nCurrentFrame].bmWidth)/2,
(rect.bottom-bmWI[m_nCurrentFrame].bmHeight)/2,//位图放在视窗正中
bmWI[m_nCurrentFrame].bmWidth,bmWI[m_nCurrentFrame].bmHeight,
&dcMemWI[m_nCurrentFrame],0,0,SRCCOPY);//显示位图
dcMemWI[m_nCurrentFrame].SelectObject(pOldBitmapIn);
}
利用ClassWizard中的Member Variables标签为CControlView增加成员变量。
控件
控件ID
类型
成员
预设温度值
IDC_SETTEMPERATURE
int
m_nSetTemperature
在CControlView中增加消息处理函数:
对象
对象ID
函数
消息
进水按键
IDC_WATERIN
OnWaterIn()
BN_CLICKED
确认按键
IDC_CONFIRM
OnComfirm()
BN_CLICKED 下面以输入预设温度值和进水响应为例,来讲述如何实现控制功能。当控制视窗
(CControlView类)中预置温度设定之后,按下确认键即响应消息OnConfirm(),在监视视窗
(CShowView类)中的状态监测图中画一条预设温度的横线。当控制视窗(CControlView
类)中按下进水键,便在动画视图(CAnimationView类)有进水动画产生。 这时控制视图要向监视视图、动画视图传送数据,但它们之间无法直接实现数据共享。
MFC类库中CDocument类及其派生类用来管理工作数据,它能够读写和存储视图所要观
察和处理的数据,并可以同时拥有多个视图。所以,此处用CDocument的派生类
CAnimationDoc作为数据传输的中介,来实现不同视窗之间的数据传递。
预置温度(变量名为m_nSetTemperature)的数据传送示意图如图2所示。
m_nSetTemperature m_nSetTemperatureDoc
图2 省略 在CAnimationDoc中,设置公共变量:
public:
int m_nSetTemperatureDoc; //用来传递m_nSetTemperature的Document派生类变量
BOOL m_bSetTemperatureFlagDoc; //温度设置成功标志
BOOL m_bWaterInFlagDoc; //进水标志 在CAnimationDoc的构造函数中初始化变量:
CAnimationDoc::CAnimationDoc()
{
m_nSetTemperatureDoc=0;
m_bSetTemperatureFlagDoc=FALSE;
m_bWaterInFlagDoc=FALSE;
}
编辑CControlView的OnConfirm()函数:
void CControlView::OnConfirm()
{
CAnimationDoc* pDoc=(CAnimationDoc*) GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));//找到当前的
//CDocument类
UpdateData(); //更新视图数据
pDoc->m_nSetTemperatureDoc=m_nSetTemperature;
pDoc->m_bSetTemperatureFlagDoc=TRUE; //预设温度成功标志
}
编辑CControlView的OnWaterIn()函数:
void CControlView::OnWater()
{
CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));
pDoc->m_bWaterInFlagDoc=TRUE; //进水响应成功
}
最后在ControlView.cpp的开头包含"AnimationDoc.h"。
然后转入CShowView中,为了要能达到实时监测的目的,数据的接收要做在定时器中,这
样才可以不断地检测是否有新的数据输入。检测到温度设置标志后,画一条横线。
void CShowView::OnTimer(UINT nIDEvent)
{
CClientDC dc(this);
CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));
UpdateData();
If(pDoc->m_bSetTemperatureFlagDoc)
{
dc.MoveTo(0,145-pDoc->m_nSetTemperatureDoc);
dc.LineTo(400,145-pDoc->m_nSetTemperatureDoc); //画一条横线
pDoc->m_bSetTemperatureFlagDoc=FALSE; //保证只做一次
}
CFormView::OnTimer(nIDEvent);
}
同样,在CAnimationView中,编辑OnTimer()函数调用的过程ServicedAnimation(),检
测到进水键响应成功后,调用进水动画例程DrawAnimationWaterIn()。
四、监视窗口功能的实现 温度、水位跟踪实现的原理类似于控制功能,它实现的是CAnimatinDoc与CShowView
类之间的数据传递,当系统采样的温度与水位变化时,CShowView中的m_nTemperature(温
度变量)即随之变化,在利用MoveTo()与LineTo()函数,便可将其画在图上。再把这些做
在定时器当中,就可以实时监测。 参考文献:
1、《Visual C++5开发人员指南》David Bennett机械工业出版社
2、《Visual C++4开发人员指南》Scott Stanfield机械工业出版社
3、《MFC开发人员参考手册》 Robert D. Thompson机械工业出版社
我们暂时用硬件完成压缩功能,直接采集摄像机过来的视频,以后要做基于MPEG4的,你们呢?
[email protected]
你的资料我都有看过,和我的要求有所不同,不过还是非常感谢你。
要分的进来