c界面设计.docx

上传人:b****6 文档编号:8758399 上传时间:2023-05-14 格式:DOCX 页数:20 大小:19.71KB
下载 相关 举报
c界面设计.docx_第1页
第1页 / 共20页
c界面设计.docx_第2页
第2页 / 共20页
c界面设计.docx_第3页
第3页 / 共20页
c界面设计.docx_第4页
第4页 / 共20页
c界面设计.docx_第5页
第5页 / 共20页
c界面设计.docx_第6页
第6页 / 共20页
c界面设计.docx_第7页
第7页 / 共20页
c界面设计.docx_第8页
第8页 / 共20页
c界面设计.docx_第9页
第9页 / 共20页
c界面设计.docx_第10页
第10页 / 共20页
c界面设计.docx_第11页
第11页 / 共20页
c界面设计.docx_第12页
第12页 / 共20页
c界面设计.docx_第13页
第13页 / 共20页
c界面设计.docx_第14页
第14页 / 共20页
c界面设计.docx_第15页
第15页 / 共20页
c界面设计.docx_第16页
第16页 / 共20页
c界面设计.docx_第17页
第17页 / 共20页
c界面设计.docx_第18页
第18页 / 共20页
c界面设计.docx_第19页
第19页 / 共20页
c界面设计.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

c界面设计.docx

《c界面设计.docx》由会员分享,可在线阅读,更多相关《c界面设计.docx(20页珍藏版)》请在冰点文库上搜索。

c界面设计.docx

c界面设计

用VisualC++开发监控界面的方法

作者:

伶俐黄斌顾敏芬eNet学院

 

 VisualC++开发工具提供了现成的窗口、控制与工具条的制作手段,大大简化了界面的开发过程,并且使得开发出的界面具有组态软件风格,使用起来方便、灵活、简单易学。

 

  本文以一实例介绍如何实现三个独立的分离窗口:

监视窗口,控制窗口和动画窗口,并以图1中的进水和温度值传递为例,介绍如何实现控制功能和不同窗口间的数据共享,并介绍实现无闪烁动画的方法。

 

  将工作台分离成为三个窗口,动画窗口用于模拟锅炉的进、出水、升温的画面显示,其中的画面与系统采集的数据相对应。

控制窗口用于实现预设温度值,调节水位、控制加热、暂停等功能。

监视窗口用来实时跟踪采样的温度值,作出温度--时间曲线。

 

一、创立分离窗口

 

  要实现多窗口显示,必须使用CSplitterWnd类,将窗口分成三个子窗口,然后将各个功能类与窗口联系起来。

在创建应用程序时,在第一步中选择SingleDocumentInterface,并选用中文字库,在第4步中按下Advanced,选择UseSplitWindow选项。

设定应用程序名为Animation。

目前我们只有一个视类CAnimationView,它将与动画窗口对应,此外我们还要生成具有对话功能的监视窗口(对应CShowView类)和控制窗口(对应CControlView类)。

在ResourceView中调出上下文菜单并选择Insert,选择属性为IDD_FORMVIEW,创建监视对话框IDD_SHOWVIEW和控制对话框IDD_CONTROLVIEW,并单击鼠标右键在Properties选择项中选择中文字库。

然后编辑IDD_CONTROLVIEW:

利用VisualC++提供的控件生成器生成ID名为IDC_SETTEMPERATURE的文字编辑域,并生成Caption为“设置温度初始值”。

再利用button生成器,生成控件IDC_WATERIN,IDC_CONFIRM,Caption分别为“进水”和“确认”。

再利用ClassWizard,创建基于CFormView类的新类,分别为CShowView和CControlView类,并将它们与刚创建的两个对话框联系。

 

在CMainFrame类中,重载OnCreateClient()函数创建三个静态分离窗口,先在MainFrame.h中声明所需变量:

 

protected:

 

CSplitterWndm_wndSplitter2;

 

转入MainFrame.cpp程序,在开头处包含头文件“ShowView.h”,向下找到函数

 

OnCreateClient(),添加如下代码,生成两个窗口,三个视图:

 

BOOLCMainFrame:

:

OnCreateClient(LPCREATESTRUCT/*lpcs*/,CCreateContext*pContext)

 

{

 

//先分裂成两个窗口,一行两列

 

if(!

m_wndSplitter.CreateStatic(this,1,2))

 

{

 

TRACE0("FailedtoCreateStaticSplitter\n");

 

returnFALSE;

 

}

 

//加上动画窗口,将其放在左边

 

if(!

m_wndSplitter.CreateView(0,0,pContext->m_pNewViewClass,CSize(425,50),pContext))

 

{

 

TRACE0("Failedtocreatefirstpane\n");

 

returnFALSE;

 

}

 

//将第二个窗口再一分为二

 

if(!

m_wndSplitter2.CreateStatic(

 

&m_wndSplitter,//原来的m_wndSplitter是父指针,m_wndSplitter2是子指针

 

2,1,//窗口分为两行,一列

 

WS_CHILD|WS_VISIBLE|WS_BORDER,m_wndSplitter.IdFromRowCol(0,1)))

 

{

 

TRACE0("Failedtocreatenestedsplitter\n");

 

returnFALSE;

 

}

 

//增加两个视图,并调整视图大小

 

if(!

m_wndSplitter2.CreateView(0,0,

 

RUNTIME_CLASS(CShowView),CSize(0,175),pContext))

 

{

 

TRACE0("Failedtocreatesecondpane\n");

 

returnFALSE;

 

}

 

if(!

m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CControlView),CSize(0,0),pContext))

 

{

 

TRACE0("Failedtocreatethirdpane\n");

 

returnFALSE;

 

}

 

returnTRUE;

 

}

 

再转入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秒的时钟。

 

intCAnimationView:

:

OnCreate(LPCREATESTRUCTlpCreateStruct)

 

{

 

if(CView:

:

OnCreate(lpCreateStruct)==-1)

 

return-1;

 

SetTimer(2,100,NULL);//产生每隔0.1秒的时钟

 

return0;

 

}

 

在函数OnTimer()中,调用动画服务函数ServicedAnimation(),该函数根据系统情况作出无闪烁动画,并可以根据不同的功能,选择画面。

 

voidCAnimationView:

:

OnTimer(UINTnIDEvent)

 

{

 

CClientDCClientDC(this);

 

ServicedAnimation(&ClientDC);//调用动画服务函数

 

CView:

:

OnTimer(nIDEvent);

 

}

 

ServicedAnimation()用于检查系统的时钟,并能计算从发生最后一个动画事件开始计算起所经过的时间,然后这个函数检查本帧动画的延迟时间,并决定是否到达了另一次更新的时间,若到了另一次更新的时间,那么m_nCurrentFrame变量就增加,此时若进水标志成功,则调用DrawWaterinAnimation(),开始新一帧动画画面。

如果由于其它原因造成了到达ServicedAnimation()函数的延迟也计算在内。

 

先在CAnimationView中,定义变量:

 

public:

 

DWORDmLastEventServiced;

 

BOOLm_bPause,m_bDone;//暂停、动画终点标志

 

intm_nCurrentFrame,m_nFrame;//当前的动画帧数,总动画帧数

 

构造函数中,添加:

 

CAnimationView:

:

CAnimationView()

 

{

 

mLastEventServiced=0;

 

m_bPause=FALSE;

 

m_bDone=FALSE;

 

m_nCurrentFrame=0;

 

m_nFrame=100;//图画的帧数设为100幅

 

}

 

编辑ServicedAnimation()函数:

 

voidCAnimationView:

:

ServicedAnimation(CDC*pDC)

 

{

 

DWORDElapsed=0L;

 

DWORDFirstSample=:

:

GetTickCount();

 

DWORDWorkValue=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()为显示不同的进水水位的画面的函数,要连续显示画面,应将一幅幅位图声明成一个静态数组。

 

Staticintbitmapswaterin[]={IDB_WATERIN1,

 

IDB_WATERIN2......IDB_WATERIN100};

 

利用ClassWizard声明CAnimationView的变量:

 

protected:

 

CBitmapbmpWI[100];

 

CDCdcMemWI[100];

 

BITMAPbmWI;

 

在CAnimationView的构造函数里添加如下语句:

 

for(inti=0;i<100;i++)

 

{

 

bmpWI[i].LoadBitmap(bitmapswaterin[i]);

 

bmpWI[i].GetObject(sizeof(BITMAP),&bmWI[i]);

 

}

 

编辑DrawAnimationWaterIn()函数,在此函数中,应重新声明bmpWI[100],dcMemWI[100]为局部变量,这样当重新调用同一幅位图时,可以及时刷新内存,不会引起冲突。

 

voidCAnimationView:

DrawAnimationWaterIn(CDC*pDC)

 

{

 

CBITMAPbmpWI[100];

 

CDCdcMemWI[100];

 

CRectrect;

 

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中的MemberVariables标签为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_nSetTemperaturem_nSetTemperatureDoc

 

在CAnimationDoc中,设置公共变量:

 

public:

 

intm_nSetTemperatureDoc;//用来传递m_nSetTemperature的Document派生类变量

 

BOOLm_bSetTemperatureFlagDoc;//温度设置成功标志

 

BOOLm_bWaterInFlagDoc;//进水标志

 

在CAnimationDoc的构造函数中初始化变量:

 

CAnimationDoc:

:

CAnimationDoc()

 

{

 

m_nSetTemperatureDoc=0;

 

m_bSetTemperatureFlagDoc=FALSE;

 

m_bWaterInFlagDoc=FALSE;

 

}

 

编辑CControlView的OnConfirm()函数:

 

voidCControlView:

:

OnConfirm()

 

{

 

CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument();

 

ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));//找到当前的

 

//CDocument类

 

UpdateData();//更新视图数据

 

pDoc->m_nSetTemperatureDoc=m_nSetTemperature;

 

pDoc->m_bSetTemperatureFlagDoc=TRUE;//预设温度成功标志

 

}

 

编辑CControlView的OnWaterIn()函数:

 

voidCControlView:

:

OnWater()

 

{

 

CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument();

 

ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));

 

pDoc->m_bWaterInFlagDoc=TRUE;//进水响应成功

 

}

 

最后在ControlView.cpp的开头包含“AnimationDoc.h"。

 

然后转入CShowView中,为了要能达到实时监测的目的,数据的接收要做在定时器中,这样才可以不断地检测是否有新的数据输入。

检测到温度设置标志后,画一条横线。

 

voidCShowView:

:

OnTimer(UINTnIDEvent)

 

{

 

CClientDCdc(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()函数,便可将其画在图上。

再把这些做在定时器当中,就可以实时监测。

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

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2