第一篇:紫金桥软件读取历史数据的方法小结
紫金桥软件读取历史数据的方法小结
摘要:本文简述了紫金桥软件读取历史数据的三种方式,重点说明了取批量历史的不同操作方法以及各方法间的区别。正文: 紫金桥软件自带了过程数据库,可以高效的保存相关数据点的历史记录,同时提供了丰富的方法读取所需的历史记录。笔者使用紫金桥做了多个工程,仅就个人经验进行简单小结,这里和大家分享,还望能起到抛砖引玉的作用,如有不对之处,还望指正。
关于保存历史记录
通过紫金桥组态软件自身的过程数据库,可以通过两种方式自动保存数据点的历史记录,定时保存和变化率保存,定时保存适合保存变化不是很快,或者比较有规律的数据点,变化率保存的应用范围相对更广,适合变化较快或者较慢的情形,这里要注意两点内容:
对于定时保存的历史记录一般不做压缩的,所以不建议对于较多的数据库点设置为保存间隔较短的定时保存,否则历史记录的文件体积会增加相对较快;
对于变化率保存的数据,系统会自动压缩保存,要注意的是其变化率是相对于该点的量程而言的,而不是相对于上次保存的历史值。数据点的量程可以在“点组态”基本参数中修改;
个人觉得过程数据库很适合保存现场连续的采集值,对于一些字符型的数据,可能还需要借助关系数据库来保留历史值了。而关系数据库在保存连续数值方面也远不如过程数据库方便。关于紫金桥对关系数据库的各种操作,笔者将在其它文档中进行说明,这里不再赘述。
历史数据的读取
紫金桥软件提供了多种方式读取历史数据,这里仅就一些常用的方法进行说明。一般有三种方式读取历史记录,分别是:历史曲线、读取单点历史、读取批量历史。在说明各种方式之前先要解释下“坏值”的概念,数据点只有在系统运行时才能保存历史记录,对于系统没有运行时的历史值,如果该时刻早于当前时刻,紫金桥软件通常会赋一个坏值,-9999。而对于未到时间的历史值可以在“系统参数”进行设置,如图所示:
下面简述下读取历史记录的三种操作: 通过历史曲线
通过历史曲线或者趋势分析曲线可以直接查询相关点的历史值,这种方法的优点在于数据很直观,便捷、曲线可以任意放大。历史曲线:
趋势分析:
历史曲线和趋势分析曲线的不同在于,历史曲线可以通过“打散单元”的操作将该组件分解,自行根据需要重新组合;而趋势分析组件功能更强,提供了历史曲线没有的统计数据、全屏显示等功能,但是不支持分解操作,不能自行组合。读取单点历史记录
单独采集某点某时刻的历史值或某段时间的统计值一般通过脚本函数实现: 读取某刻历史值一般使用三种函数:GetHisData(Var,Year,Month,Day,Hour,Minute,Second,MilliSec);
GetHisData2(Var,StartTime, MilliSec);
GetHisDataEx(DataSource, VarName ,StartTime,MilliSecond);
GetHisData和GetHisData2前者适合读取具体时刻的历史值,后者通过一个时间值来获取历史记录,该值是一个整数,表示相对于1970年1月1日08:00时过去的秒数,这个秒数在紫金桥软件中非常常用。实际工程中,这个秒数可以通过函数LongTime(“2001/01/01 14:50:48”)得到,该函数可以自动得到某时刻过去的秒数。秒数也可以通过一些组件得到,比如起始时间组件,如图所示:
图中有一个起始时间组件,其下是该组件的time属性所对应的相对于1970/1/1/08:00:00 过去的秒数。比如该组件被命名为EndTime,在脚本中通过#EndTime.time即可得到相应的秒数。
读取某段时间内的统计值可以通过函数GetStatisDataEx(DataSource,VarName,StartTime,TimeSpan,Flag,Time)或GetStatisData(Var, Year, Month, Day, Hour, TimeSpan, Flag,Time)得到一段时间内的最大值、最小值或者平均值。
val = GetStatisDataEx(“",”FQ101.PV“, LongTime(”2007/09/04 14:30:00"), 2,0,strTime)示例中Val变量可以得到FQ101.pv值在2007年9月4日14点30分起2个小时内的平均值。这里要注意的是,GetStatisData 和GetStatisDataEx函数会自动过滤掉坏值。在使用统计函数时,要确保对应的点在组态时选择上统计设置,如图所示:
此外还要注意的是,由于紫金桥系统是每小时自动统计下历史记录,对于刚保存的历史记录,比如1小时内的历史值,通过统计函数可能无法得到最新的统计值。如果需要得到即时的统计值,需要借助紫金桥软件提供的SPC历史组件进行统计。关于该组件的一些操作可以参看紫金桥软件相关帮助文档。读取批量历史
读取批量历史通常以报表的形式显示出来。对于历史报表,依据不同的标准有不同的分法,按照行数区分可以分为固定行列和不固定行数,按显示的类型可以分为统计和非统计历史报表。所谓统计报表通常是对一些累加值的点进行统计,比如最大值、最小值、或者平均值等,非统计报表就是直接查询某时刻的历史值。不同情况下具体实现的方法也各不同,这里仅就笔者熟悉的方法进行简述。
行数固定的非统计历史报表
对于需要获取某段时间内,固定时间间隔的历史记录,通常其行数是固定的,比如需要对一天内的整点数值采样,其行数是24,时间间隔一小时。这种情况下,使用自由报表的“取批量历史”功能最为简单。具体操作方式简述如下:
首先选中自由报表中需要显示历史记录的一列,然后点击自由报表工具栏中右侧的公式选择按钮,如图所示:
点击后选择“取批量历史”,如图所示:
系统弹出对话框:
在“数据库变量”中填写所关联的数据点,比如“A1.pv”,根据实际情况设定“采集个数”和“时间间隔”,“采集个数”不能填写为变量。这里的“时间表达式”是指批量历史中首个采集点的时间,可以是一个整形变量,其值是前文中提到的1970年1月1日08:00时过去的秒数。
优点:通过取批量历史的功能,可以轻松的获取某点采集个数固定,时间间隔固定的历史记录。
缺点:无法实现采集时间不固定、采集历史记录个数不固定的要求,无法采集统计值。
小技巧:通常显示历史记录的时候,往往需要在另一行显示该记录相对应的时间,可以选择一列,将该列的输入输出设置为“日期和时间”,然后将该列关联和历史值对应的秒数即可。
行数不固定的非统计报表
有时需要用户自行设置历史记录查询的开始时间和结束时间,查询的历史记录的间隔时间,这时往往需要借助历史数据对象来获取记录。
在紫金桥的图库中“历史数据”选择“历史数据对象”,如图所示:
将其拖拽置窗口,系统自动增加一历史数据对象,如图所示:
双击该对象,可以在属性对话框中进行参数设置,如图所示:
该组件通常运行时是隐藏的。可以在属性设置对话框中增加所需查询的历史点(可以同时查询多个)。通过点击“事件脚本”,可以在此编写所需的脚本语句,如图所示:
通常是通过按钮等事件调用历史数据对象的Start(BeginTime, Cycle, Count)函数,通过该函数可以设置查询的开始时间,查询的时间周期和查询的历史个数,并进行查询。当查询结束后,会执行“检索完成时”脚本。一般在“检索完成时”的脚本中通过一个循环语句,把查询到的结果更新到自由报表中。例如脚本: num=#his.GetColCount();//得到查询的行数
for k=1to num+1step1 #report.settxt(1,k+1,#his.GetTimeText(k-1,0));//得到时间
#report.settxt(2,k+1,#his.GetCellText(0,k-1));//得到变量1的历史值 #report.settxt(3,k+1,#his.GetCellText(1,k-1));//得到变量2的历史值
Next 该脚本首先获得历史数据对象查询的数据行数,然后逐行赋值给自由报表中指定的单元格。关于该组件的更详细操作可以参看紫金桥软件的说明书。优点:可以方便的采集行数固定或不固定的历史值。
统计报表
对于有些报表,需要统计一些历史值,比如一段时间的最大值、最小值、平均值或者某段时间内,历史值的最大值和最小值的差值(比如产量)。这类报表可以通过SPC控件或者历史摘要控件进行读取统计值,然后再写入自由报表中,也可以直接使用统计函数获取统计值。关于SPC控件和历史摘要控件的操作方法和上文中提到了历史数据对象比较类似,具体内容和相关函数可以参看紫金桥软件说明书。其中SPC控件可以从任意时段的历史数据中进行抽样统计,进行SPC统计的点是否选择了“是否统计”都不影响SPC分析;而历史摘要控件选择的是该点的统计值,进行历史摘要的点必须选择“统计”,而统计往往是以小时为单位的,所以相对于SPC控件,摘要控件统计的结果更为准确,但是时间跨度需要大于一小时。
这里要说明的是,对于一些累加的值而言,比如产量等,有时需要得到一段时间内的差值,有些用户往往会用结束时刻的历史值减去开始时刻的历史值,这种做法是有隐患的,因为开始时刻或者结束时刻系统可能处于未运行状态,这时,历史值会是坏值-9999。所以建议的做法是选取这段时间内的最大统计值减去这段时间内的最小统计值(系统会自动过滤坏值),不过获取统计值的速度会比获取历史值的速度稍慢一点,如果该段时间跨度很大,可以适当缩小统计值的时间范围。
其他历史报表
有时可能需要统计一些离散的历史值,比如在检测行业,每次测量的时间间隔可能不固定,测量次数可能也不确定,这时想查询历史检测记录,使用前面提到的方法都难以实现。这里推荐两种做法:
设置一个标记点,该标记点使用变化率保存历史记录,每测量结束后,都改变一次标记点的值,其他测量值同样保持历史记录,查询时使用“取全部历史数据对象”组件(在图库中“历史数据”中调用),如图所示:
通过该组件可以查询这个标记点指定范围内的所有历史记录,同时可以查询到该时刻时其他测量值的历史值。比如,工程中有A1和A2两个位号,A1是标记点,现在希望查询A1的在当天的所有历史数据。比如查到的结果是12:23:18.102时刻有一个历史数据,18:43:25.358时刻有一个历史数据。这时希望同时查询A2在12:23:18.102时刻和18:43:25.358时刻的历史数据。进入“取全部历史数据”对象的报表设置界面:
可以看到,报表的前3列分别是时间、毫秒和查询的位号的数据,可以在后面增加一列,比如A2.PV,见上图。并在下面输入如下的脚本=GetHisData2(A2.PV, Val(1,$R), Val(2,$R))。这段脚本的意义是取A2.PV的历史数据,其中时间采用左侧第一列的时间,毫秒数采用左侧第二列的时间。当组件查询到A1.PV的历史数据的时候,会自动地增加报表的行数来存放相应的数据。同时也会自动地复制上面输入的脚本,这样后面的列就能显示A2.PV的相应时刻的历史数据了。
优点:无需借助关系数据库,即可查询离散的无规律变化的历史记录; 缺点:受过程数据库自身的局限,无法保存字符型历史记录。 每次测量结束后,将测量数据保存到关系数据库中,然后通过自由报表查询关系数据库中的历史记录。
优点:可以方便的保存字符型或非字符型的离散历史记录; 缺点:需要关系库的支持;
本文简述了读取紫金桥软件历史数据库的三种方式:曲线、函数、报表,并详细介绍了各种情况下使用报表读取历史数据的不同操作方法,当然具体操作中,还有更多其他的方法可以选择。希望以上介绍能对各位操作紫金桥软件有所帮助,也希望起到抛砖引玉的作用,欢迎提出更好操作方法,彼此讨论提高。
第二篇:组态王紫金桥--输煤控制系统工艺分析
控制系统综合实验
第1章 输煤控制系统工艺分析
1.1 输煤控制系统的目的
在我国大型热电厂中所采用的绝大部分燃料是燃煤。由于煤产地与电厂间地理位置或地域不同,就需通过汽车、火车、或轮船把煤运往火电厂煤厂,通过由卸煤系统、堆煤系统、上煤系统和配煤系统等组成的输煤程控系统输送到指定的煤仓或煤筒。火电厂输煤控制系统的主要任务就是卸煤、堆煤、上煤和配煤,以达到按时保质保量为机组(原煤仓)提供燃煤的目的。整个输煤控制系统是火电厂十分重要的支持系统,它是保证机组稳发满发的重要条件。基于输煤控制系统在整个火电厂中的重要性,且煤场面积大、工作环境恶劣、人工作业通讯难以畅通,利用组态王及其他先进技术实现其控制功能。
1.2 输煤控制系统的组成
输煤控制系统由原煤仓,往复给煤机,皮带机、拉线开关,电磁分离器,滚轴筛,缓冲滚筒,碎煤机和犁煤器组成。
输煤程控系统是实现输煤过程自动化的计算机控制及监视系统。可以实现皮带自动上煤、自动配煤、计算机监控管理、画面参数提示、语音报警、报表自动打印等功能。能够实现对整个输煤系统包括皮带机、除铁器、犁煤器、跑偏信号、打滑信号、拉绳信号、堵煤信号、煤位信号在内的多套装置、信号的控制与监测包括:输煤运行方式选择(自动控制、集中手动控制、就地手动控制),皮带机启停。给煤机及除铁器启停,除尘器的启停,自动配煤加仓,设备故障报警、联锁保护,现场信号采集、处理与显示。
1.3 输煤控制系统概述
输煤系统的主要任务是由料斗和皮带的传递将煤由贮煤场输送到配煤场,由给煤机给煤,再经由皮带机传送到锅炉。火电厂输煤程控系统主要控制的对象包括:给煤机、三通挡板、皮带机、碎煤机、除铁器、犁式卸煤器等设备。在此次设计中主要概述了输煤系统的卸煤和上煤的皮带传输控制。系统总体设计先进可靠,设备选型合理,监控功能齐全,投资少、操作简单、实用性强,能提高电厂输煤系统的综合自动化水平,改善劳动条件,提高劳动生产率和安全经济运行水平。
控制系统综合实验
第2章 输煤控制系统设计
2.1 输煤控制系统仪表的选择
编程控制器(简称PLC)由于其将系统的继电器技术,计算机技术和通信技术融为一体,以其可靠性高,稳定性好、抗干扰能力强,以及编程简单,维护方便,通讯灵活等众多优点,广泛应用于工业生产过程和装置的自动控制中。PLC不仅能实现复杂的逻辑控制,还能完成定时、计算和各种闭环控制功能。设置性能完善、质量可靠、技术先进的可编程控制器PLC控制皮带运输机监控系统,可以实现高自动化的皮带机群的集中控制及保护。此次课程设计的课题内容即为输煤控制系统,.煤在配煤场经碾碎去渣和铁硝石,由给煤机给煤通过一系列过程传送进锅炉,方案要求用一台PLC控制卸煤、给煤,PLC与PC之间不通讯。系统具备很多自动化控制的功能:(1)系统启动前各台设备预警;(2)地面输煤生产线上各设备按逆煤流方向顺序延时起动,按顺煤流方向顺序延时停车;(3)输煤线上任一设备因故障或其它原因停车时,来煤方向各设备立即停车,顺煤方向顺序延时停车,以避免堆煤,减少皮带压煤;(4)在紧急情况下,任一设备都可通过现场急停按钮实现紧急停车;(5)对各台设备的运转状态实时自动检测,并将信息传输给PLC;(6)各台设备的运转情况及故障报警等信息都可以在总控室由显示灯显示出来。
可编程控制器是为工业控制应用而设计制造的。早期的可编程控制器称作可编程逻辑控制器,简称PLC,它主要用来代替继电器实现逻辑控制。随着技术的发展,这种装置的功能已经大大超过了逻辑控制的范围,因此,今天这种装置称作可编程控制器,简称PC。但是为了避免与个人计算机的简称混淆,所以将可编程控制器简称PLC。
PLC实质是一种专用于工业控制的计算机,其硬件结构基本上与微型计算机相同,基本构成为: 电源、中央处理单元(CPU)、存储器、输入输出接口电路、功能模块、通信模块。
PLC的特点:
1.可靠性高,抗干扰能力强; 2.配套齐全,功能完善,适用性强; 3.易学易用,深受工程技术人员欢迎;
4.系统的设计、建造工作量小,维护方便,容易改造; 5.体积小,重量轻,能耗低。2.2 输煤控制系统传感器的选型
现代传感器在原理与结构上千差万别,如何根据具体的测量目的、测量对象以及测量环境合理地选用传感器,是在进行某个量的测量时首先要解决的问题。
控制系统综合实验
当传感器确定之后,与之相配套的测量方法和测量设备也就可以确定了。测量结果的成败,在很大程度上取决于传感器的选用是否合理。
传感器选择的原则:
1.根据测量对象与测量环境确定传感器的类型
2.灵敏度的选择 3.频率响应特性 4.线性范围 5.稳定性
6.精度
7.对某些特殊使用场合,无法选到合适的传感器,则需自行设计制造传感器。2.3 控制方案分析
PID(比例-积分-微分)控制器作为最早实用化的控制器已有50多年历史,现在仍然是应用最广泛的工业控制器。PID控制器简单易懂,使用中不需精确的系统模型等先决条件,因而成为应用最为广泛的控制器。
PID控制器由比例单元(P)、积分单元(I)和微分单元(D)组成。在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。PID控制器问世至今已有近70年历史,它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。当被控对象的结构和参数不能完全掌握,或得不到精确的数学模型时,控制理论的其它技术难以采用时,系统控制器的结构和参数必须依靠经验和现场调试来确定,这时应用PID控制技术最为方便。即当我们不完全了解一个系统和被控对象,或不能通过有效的测量手段来获得系统参数时,最适合用PID控制技术。PID控制,实际中也有PI和PD控制。PID控制器就是根据系统的误差,利用比例、积分、微分计算出控制量进行控制的。
1.比例(P)控制:
比例控制是一种最简单的控制方式。其控制器的输出与输入误差信号成比例关系。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。
2.积分(I)控制:
在积分控制中,控制器的输出与输入误差信号的积分成正比关系。对一个自动控制系统,如果在进入稳态后存在稳态误差,则称这个控制系统是有稳态误差的或简称有差系统(System with Steady-state Error)。为了消除稳态误差,在控制器中必须引入“积分项”。积分项对误差取决于时间
控制系统综合实验 的积分,随着时间的增加,积分项会增大。这样,即便误差很小,积分项也会随着时间的增加而加大,它推动控制器的输出增大使稳态误差进一步减小,直到等于零。因此,比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。
3.微分(D)控制:
在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳。其原因是由于存在有较大惯性组件(环节)或有滞后(delay)组件,具有抑制误差的作用,其变化总是落后于误差的变化。解决的办法是使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零。这就是说,在控制器中仅引入 “比例”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势,这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调。所以对有较大惯性或滞后的被控对象,比例+微分(PD)控制器能改善系统在调节过程中的动态特性。2.4 输送机的选择
带式输送机是连续运输机中效率最高、使用最普遍的一种机型。在我国建设的大、中型燃煤火力发电厂中,从受卸装置向储煤场及锅炉原煤仓输煤所用的运送设备,主要就是带式输送机。
带式输送机是以挠性输送带作为物料承载物件和牵引构件的连续输送设备。根据摩擦原理,由驱动滚筒带动输送带,将物料输送到所需的地方。带式输送机与其他类型的输送设备相比,具有良好的性能,在连续装载的情况下能连续运输,生产率高,运行平稳可靠,输送连续均匀,工作过程中噪音小,结构简单,能量消耗小,运行维护费用低,维修方便,易于实现自动控制及远方操作等优点,因此,在输煤运行中得到于广泛的应用。
控制系统综合实验
第3章 基于组态王的输煤控制系统监控程序设计
3.1 主控界面
图3-1 主控界面图像
3.2 趋势界面
图3-2 历史曲线运行前的图
控制系统综合实验
图3-3 历史曲线运行后的图
控制系统综合实验
第4章 结论与体会
通过为期一周的课程设计,我深刻体会到了自己知识的匮乏。我深深的感觉到自己知识的不足,自己原来所学的东西只是一个表面性的,理论性的,而且是理想化的。根本不知道在现实中还存在有很多问题。真正的能将自己的所学知识转化为实际所用才是最大的收获,也就是说真正的能够做到学为所用才是更主要的。设计一个很简单的电路,所要考虑的问题,要比考试的时候考虑的多的多。
在课程设计中我充分的应用了课本的基础知识,把所学的知识应用到实践中,补充了一些知识的不足。在设计的过程中遇到的问题,能通过老师的帮助和自己的努力基本了解组态王的软件的使用,了解输煤控制系统的基本原理,我了解到先进技术的重要性。
总之,通过这次课程设计,不仅使我对所学过的知识有了一个新的认识。而且提高了我考虑问题,分析问题的全面性以及动手操作能力。使我的综合能力有了一个很大的提高。
控制系统综合实验
参考文献
[1]鲍林.PLC在放电厂输煤系统中的应用[J].电站系统工程,2000 [2]马敏涛.PLC与上位计算机的自由通信[J].电气时代,2002 [3]李友善.自动控制原理[M].北京:国防工业出版社,2005 [4]赖寿宏.微型计算机控制技术[M].北京:机械工业出版社,2004 [5]蔡自兴.智能控制-基础与应用[M].北京:国防工业出版社,1999 [6]李仁.电器控制[M].北京:机械工业出版社,1998
目 录
第1章 输煤控制系统工艺分析..................................................................................1 1.1 输煤控制系统的目的...........................................................................................................1 1.2 输煤控制系统的组成...........................................................................................................1 1.3 输煤控制系统概述................................................................................................................1 第2章 输煤控制系统设计..........................................................................................2 2.1 输煤控制系统仪表的选择.................................................................................................2 2.2 输煤控制系统传感器的选型.............................................................................................2 2.3 控制方案分析.........................................................................................................................3 2.4 输送机的选择.........................................................................................................................4 第3章 基于组态王的输煤控制系统监控程序设计..................................................5 3.1 主控界面...................................................................................................................................5 3.2 趋势界面...................................................................................................................................5 第4章 结论与体会......................................................................................................7 参考文献........................................................................................................................8
第三篇:VC环境下读取显示.bmp图像方法
总结显示bmp图像的方法,列出四种显示方法。通过SetPixel()函数画出每个像素点来显示图像。2 通过读取位图资源中bmp资源显示图像。通过读取本地文件,利用位图结构信息,定义HGLOBAL,再采用固定的显示方式显示位图。通过读取本地文件,利用位图结构信息,定义buffer,再采用SetDIBitsToDevice()函数。下面分别对这四种方法进行详细描述:
首先新建VC工程ShowBmpImage->MFC->单文档模式。将显示的操作都是放在CShowBmpImageView下进行的,并且没有定义成员变量。1 第一种方法
通过SetPixelShow()函数循环画出每个像素点,从而显示图像。操作如下: 增加成员函数SetPixelShow(),编辑代码如下:
int x,y;
//定义像素位置 CClientDC dc(this);
//获取dc,也可以用CDC *pDC for(x=0;x<200;x++)
for(y=0;y<200;y++)
dc.SetPixel(x,y,RGB(x,y,255));
//画一个像素点,RGB是颜色 调用函数后,显示的是一幅彩色图像,可以根据需要改变RGB的值来显示一幅完整的图像。2 第二种方法
通过读取位图资源中的位图显示图像,选择菜单栏->插入->资源,弹出对话框,选择导入按钮,将文件类型改成所有文件,选择想要显示bmp位图,导入。这样工程的资源位图中,导入的位图默认的ID是IDB_BITMAP1。而显示这种位图有一个固定的显示模式,非常方便。方法如下:
a 定义一个CBitmap对象,使其加载位图资源。b 定义一个CDC对象,用于装载位图 ;
使其创建兼容DC,相当于初始化;
与CBitmap对象关联起来,相当于获取位图。
c 定义BITMAP对象,使其与CBitmap对象绑定,可以获取宽度和高度。d 创建DC,画图像。e 选择回原来的资源。操作如下:
增加成员函数LoadResShow(),编辑代码如下: CBitmap bmp;
//1.定义一个CBitmap对象
bmp.LoadBitmap(IDB_BITMAP1);
// 使其加载位图资源
CDC memDC;
//2.定义一个CDC对象,用于装载位图
memDC.CreateCompatibleDC(NULL);
// 使其创建兼容DC,相当于初始化
CBitmap* pOldBmp = memDC.SelectObject(&bmp);// 与CBitmap对象关联起来,就获取位图了
BITMAP bm;
//3.定义BITMAP对象
bmp.GetBitmap(&bm);
// 使其与CBitmap对象绑定 int nWidth = bm.bmWidth;
// 获取宽度 int nHeight = bm.bmHeight;
// 获取高度
//CClientDC dc(this);//dc.StretchBlt(0,0,nWidth,nHeight,&memDC,0,0,nWidth,nHeight,SRCCOPY);CDC *pDC=GetDC();
//4.创建DC pDC->BitBlt(0,0,nWidth,nHeight,&memDC,0,0,SRCCOPY);
// 画图像
//pDC->StretchBlt(0,0,nWidth,nHeight,&memDC,0,0,nWidth,nHeight,SRCCOPY);
memDC.SelectObject(pOldBmp);
//5.选择回原来的资源 调用函数后,显示载入的位图。3 第三种方法
通过读取本地的位图文件,再用固定的模式显示图像。操作如下:
增加成员函数FileLoad1(),ReadBmpFile1(CString filepathname),编辑代码如下: void CShowBmpImageView::FileLoad1(){ CString filename;CFileDialog dlg(true,“*.bmp”,NULL,NULL,“(Bmp File)*.bmp|*.bmp||”);if(IDOK==dlg.DoModal()){
filename=dlg.GetPathName();
ReadBmpFile1(filename);
//获取到文件路径,加载bmp文件 } else {
MessageBox(“您取消操作”);} } void CShowBmpImageView::ReadBmpFile1(CString filepathname){ CFile file;
//定义CFile对象
if(!file.Open(filepathname, CFile::modeRead))
MessageBox(“该文件打开出错”);long nFileLen;
//定义文件长度 nFileLen = file.GetLength();BITMAPFILEHEADER bmfHeader;
//定义位图文件头 //读取位图文件头,大小为文件头的大小
if(file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader))!= sizeof(bmfHeader))
MessageBox(“读取文件错误”);//判断文件的类型是否为bmp文件
if(bmfHeader.bfType!=((WORD)('M' <<8)| 'B'))
MessageBox(“该文件不是BMP文件”);//定义hDIB,并GlobalAlloc分配内存,用完后需要GlobalFree释放 HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen);
//将文件读入到hDIB,大小为总长度减去文件头的长度 if(file.ReadHuge((LPSTR)hDIB, nFileLensizeof(BITMAPFILEHEADER))
MessageBox(“读取文件错误”);//定义位图信息,并与hDIB捆绑
BITMAPINFO &bmInfo = *(LPBITMAPINFO)::GlobalLock(hDIB);//定义位图信息头,并连接hDIB BITMAPINFOHEADER *pInfoHead =(BITMAPINFOHEADER *)hDIB;//计算bmp文件Buffer大小 BYTE *pBmpPixelBuffer=(BYTE *)&bmInfo+bmfHeader.bfOffBits-sizeof(BITMAPFILEHEADER);//创建dc,并初始化 CDC dc;dc.CreateDC(“DISPLAY”,NULL,NULL,NULL);//定义HBITMAP对象,并与dc和位图关联,此对象就是现有的位图资源 HBITMAP hBitmap;hBitmap=CreateDIBitmap(dc.m_hDC,(BITMAPINFOHEADER *)&bmInfo,CBM_INIT,(VOID *)pBmpPixelBuffer,&bmInfo,DIB_RGB_COLORS);
//下面即是位图显示的固定思路
//****************************************************************************** CBitmap bmp;bmp.Attach(hBitmap);
CDC memDC;memDC.CreateCompatibleDC(NULL);CBitmap* pOldBmp = memDC.SelectObject(&bmp);
BITMAP bm;bmp.GetBitmap(&bm);int nWidth = bm.bmWidth;int nHeight = bm.bmHeight;
CDC* pDC = GetDC();pDC->BitBlt(0,0,nWidth,nHeight,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBmp);//**************************************************************************
::GlobalUnlock(hDIB);
//解锁hDIB ::GlobalFree(hDIB);
//释放hDIB } 调用函数后,弹出对话框,选择要显示的本地位图文件,显示。4 第四种方法
通过读取本地位图文件,再采用SetDIBitsToDevice()函数显示图像,操作如下:
在头文件中定义位图结构,在ShowBmpImageView.h文件的开头,在定义类CShowBmpImageView之前加入
//**************定义位图文件结构******************************* struct BMPFILE { tagBITMAPINFO *pInfo;BITMAPFILEHEADER *pFileHeader;BYTE *buffer;BYTE *PToData;};//***********将文件头和位图信息封装**************************** 增加成员函数FileLoad2(),ReadBmpFile2(CString filepathname),编辑代码如下: void CShowBmpImageView::FileLoad2(){ CString filename;CFileDialog dlg(true,“*.bmp”,NULL,NULL,“(BmpFile)*.bmp|*.bmp||”);if(dlg.DoModal()==IDOK){
filename=dlg.GetPathName();
ReadBmpFile2(filename);
//获取到文件路径,加载bmp文件
} else {
MessageBox(“您取消操作”);} } void CShowBmpImageView::ReadBmpFile2(CString filepathname){
BMPFILE *bmpfile;
//定义BMPFILE指针
bmpfile=(BMPFILE *)malloc(sizeof(BMPFILE));
//并分配内存
bmpfile->pFileHeader=new BITMAPFILEHEADER;
//初始化结构中的成员 bmpfile->pInfo=new tagBITMAPINFO;CFile file;
//定义CFile对象
if(!file.Open(filepathname,CFile::modeRead))
MessageBox(“打开文件错误”);
long Filelen;
//定义文件长度
Filelen=file.GetLength();//读取位图文件头,大小为文件头的大小
if(!file.Read(bmpfile->pFileHeader,sizeof(BITMAPFILEHEADER)))
MessageBox(“读取文件错误”);//判断文件的类型是否为bmp文件
if(bmpfile->pFileHeader->bfType!=((WORD)('M' <<8)| 'B'))
MessageBox(“该文件不是BMP文件”);//定义储存位图文件的buffer bmpfile->buffer=new byte[Filelen];//将文件读取到buffer中,大小为长度减去文件头
if(!file.ReadHuge(bmpfile->buffer,Filelen-sizeof(BITMAPFILEHEADER)))
MessageBox(“读取文件错误”);//创建位图信息,并与buffer绑定
bmpfile->pInfo=(tagBITMAPINFO *)(bmpfile->buffer);//计算位图数据大小
bmpfile->PToData=bmpfile->buffer+bmpfile->pFileHeader->bfOffBits-sizeof(BITMAPFILEHEADER);
file.Close();
//关闭文件
//**********************显示位图*************************************** CDC *pDC=GetDC();HDC hdc=pDC->GetSafeHdc();SetDIBitsToDevice(hdc,//设备环境句柄
0,//目标区域的左上角x
0,//目标区域的左上角y
bmpfile->pInfo->bmiHeader.biWidth,//资源文件的宽度
bmpfile->pInfo->bmiHeader.biHeight,//资源文件的高度
0,//源文件左下角的x
0,//源文件左下角的y
0,//开始扫描的行号
bmpfile->pInfo->bmiHeader.biHeight,//总共扫描行数
bmpfile->PToData,//字节形数组的颜色数据指针
bmpfile->pInfo,//包含位图信息的位图信息指针
DIB_RGB_COLORS
//RGB颜色表);
//************************************************************************ free(bmpfile);
//释放所有内存 } 调用函数后,弹出对话框,选择要显示的本地位图文件,显示。
第四篇:软件测试小结
第二阶段学习小结
1.白盒测试需要了解其内部结构和运行机制。白盒测试,也称之为结构测试和逻辑驱动测试。黑盒测试不需了解程序内部结构和内部特征。主要着眼于程序外部的用户界面,关注软件的输入和输出,关注用户的需求,从用户的角度来验证软件的功能。黑盒测试也称之为功能测试和数据驱动测试。
2.黑盒测试技术主要有:等价类划分法、边界值分析法、判定表方法、因果图法、错误推测法。
3.白盒测试主要技术有:语句覆盖、判定覆盖、条件覆盖、判定-条件覆盖、条件组合覆盖、路径覆盖。
4.测试用例的定义:测试用例就是一个文档,描述输入、动作、或者时间和一个期望的结果,其目的是确定应用程序的某个特性是否正常的工作。
软件测试的基本格式:软件测试用例的基本要素包括测试用例编号、测试标题、重要级别、测试输入、操作步骤、预期结果。{系统测试用例的编号这样定义规则: PROJECT1-ST-001,命名规则是项目名称+测试阶段类型(系统测试阶段)+编号。定义测试用例的优先级别,可以笼统的分为 “ 高 ” 和 “ 低 ” 两个级别。测试用例设计方法:(1)逐级细分法(2)输入域测试法(3)输出域分析法(4)正交试验设计法(5)业务流程分析法(6)状态迁移法(7)因果图法(8)判定表法(9)错误猜测法(10)等价类划分法(11)边界值分析法}。
5.Bug的描述:
① 和 bug 产生对应的软件版本。
② 开发的接口人员。
③ bug 的优先级。
④ bug 的严重程度。
⑤ bug 可能属于的模块,如果不能确认,可以用开发人员来判断。
⑥ bug 标题,需要清晰的描述现象。
⑦ bug 描述,需要尽量给出重新 bug 的步骤。
⑧ bug 附件中能给出相关的日志和截图。
6.软件测试环境的主要要素:配置测试环境是测试实施的一个重要阶段,测试环境适合与否会严重影响测试结果的重要性和真实性。一般来说,配置测试环境要满足五个基本元素:硬件、软件、网络环境、数据准备、测试工具。
7.测试环境的搭建:单机版测试环境搭建,b/s架构测试环境的搭建,c/s架构测试环境的搭建。
8.测试环境的管理:设置专门的测试环境管理员角色、明确测试环境管理所需的各种文档、测试环境访问权限的管理、测试环境的变更管理、测试环境的备份和恢复。
9.自动化测试工具介绍:性能测试—Loadrunner、Robot、Silk performer,功能测试—QTP、Winrunner、Robot、Silk test,其他测试—Xenu、AiRoboForm。
第五篇:软件课程设计小结
软件课程设计小结
在我们整个软件工程过程中,我体会到了许多,也学到了许多。
我们班由16名同学组成,在相互商量后我们确定了我们班的项目,是做一个计算器程序。在老师的指导下我们的项目也正式开始了。
在整个项目开发过程中,我们也同时遇到了许多程序代码问题,页面和功能相结合的问题,这些问题都是源于我们对程序的认识不足、以及没有将老师所讲的知识点融会贯通。我深刻认识到,在项目开发时,老师的指导以及同学之间的交流非常重要的。如果我们要在功能方面作出修改,那么有些代码以及复制的区间都不能有误差,这需要老师的帮助、指导,以及同学之间交流研究共同对整个程序作出相应的设计,这样才能避免最终整合时出现问题。
在这段时间的学习里,我还对软件工程有了新的理解。在我以前的理解当中,软件工程,无非就是一个人或者几个人或一个团队集中在一起进行编写代码的工作,以实现开发出所用的软件。但现在我明白了,软件工程的作用,就是告诉人们怎样去开发软件和管理软件。具体地讲,它表现在与软件开发和管理有关的人员和过程上。所以,软件工程就不仅仅是单一的编程过程了。它包括了系统分析->建模->概要设计->详细设计->编码->测试->维护。编码可以理解为编程,这个只占总时间的20%左右。编程只是其中的一小部分。
在这次项目里我完成了许多工作,在界面设计上我完成了“页面设计、读代码、记代码、代码编辑”等制作,在后期项目整合过程中修改了功能和界面结合时出现的bug,还有程序外观设计、美观度。这些工作我都顺利完成了,虽然并不能算是非常的出色,但也算是尽力了。现在看到自己辛劳的成果,我感到很欣慰。
当然,在这次项目过程中我也发现了自己的一些问题。如现在的软件制作技术还不够强,在和小组成员相互沟通上还不够积极、出现问题没有及时寻求老师的帮助等。我希望以此为契机,在将来的项目开发中能做得更好。
Xxx
2013/1/7