停车场管理系统毕业论文-_第1页
停车场管理系统毕业论文-_第2页
停车场管理系统毕业论文-_第3页
停车场管理系统毕业论文-_第4页
停车场管理系统毕业论文-_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、摘要本文以停车场管理为研究重点,系统软件采用WINDOWS操作平台和SQL Server 2000开发。本系统是一个功能齐全的停车场系统。通过串口通信,使用SQL Server数据库处理图像等技术,实现了入住、结账、计费等主要功能。在这些功能的支持下,停车场管理人员可以监控出来的车辆是否与进来的车辆相同,收银员可以通过电子显示和语音告诉客户到期金额。停车场管理者可以通过后台数据库了解收入状况,查询历史交易记录。关键词:串行通信,捕捉图像,动画,视频目录第一章导言1.1本研究的目的和意义31.2本课题的研究目标和预期成果3第2章串行通信及其实现概述32.1串行通信概述32.2串行通信的实现2.2

2、.1通过控件实现串行通信42.2.2实现串行通信的文件方法6第三章主要功能简述93.1打印凭证3.2抓拍的图像93.3扫描条形码.3.4费用第四章系统分析与设计104.1数据库设计4.2系统配置信息4.3实现功能的主界面13第五章是关键功能的实现及其代码135.1串行通信5.1.1初始化串行端口5.1.2发送数据5.1.3接收数据5.1.4工作电流函数265.2视频功能的实现第6章用户自定义动画回放36致参考文献38第一章导言1.1本研究的目的和意义随着社会经济的发展,越来越多的汽车进入家庭。开发一个具有凭票停车、车辆拍照、语音报价、费用电子屏显示、缴费等一整套业务逻辑功能的停车场管理系统越来

3、越有价值。因此,停车场管理变得越来越重要。21世纪,信息处理技术突飞猛进,各种数据和信息迅速增加。大家对信息处理技术的使用已经渗透到各行各业。与此同时,我国汽车的产量和销量在逐年增加,因此对停车场的需求也在逐年增加。需要对停车场进行更好的管理,主要是实现停车场的智能化管理,为人们提供一种安全合理的服务,省去人们很多麻烦,让人们更加重视。1.2本课题的研究目标和预期成果本课题的研究目标是建立一个功能相对完善的停车场系统。通过串口通信,使用SQL Server数据库处理图像等技术,实现了入住、结账、计费等主要功能。在这些功能的支持下,停车场管理者可以监控出站车辆是否与进站车辆相同。收银员可以通过电

4、子显示和语音告诉客户到期金额,停车场管理者可以通过后台数据库了解收入状况和查询历史交易记录。第二章是串行通信及其实现的概述。2.1串行通信概述计算机数据传输通常有两种方式:一种是并行,另一种是串行。并行数据传输是指数据在宽度为1比特的多条并行传输线上从发送方传输到接收方的数据传输方式。串行数据传输(Serial data transmission)是指数据在单个1位宽的传输线上按顺序、分时、逐位传输的数据传输方式。并行数据通信的距离通常很短,串行数据通信的距离可以很长,从几百米到几千公里不等。并行数据通信比串行数据通信快。(1)串行通信的连接方式根据数据在传输线上传输方向的不同,串行通信可分为

5、单工模式、半双工模式和全双工模式。(2)串行通信协议为了使双方能够顺利通信,发送方和接收方必须遵守一些基本的通信规则,如双方的同步方式、检错方式、数据传输的速度、通信消息的格式以及控制字符的定义和含义等。这些通信规则也可以称为通信协议,常用的协议有异步通信和同步通信。2.2串行通信的实现用Visual C+实现串口通信有三种方式:一种是使用微软提供的MsComm控件;一种是使用Visual C+提供的标准通信函数;一种是使用API的方法,也就是使用文件的方法。串口也是文件。2.2.1通过控制实现串行通信:微软提供了MSComm32控件。该组件专门用于串行通信。因此,我们可以使用这个组件来编写串

6、行通信程序。(1)属性MSComm32控件提供了很多属性,但是常用的并不多。以下是一些常用的属性:CommPort:设置/获取串行端口号;设置:设置/获取串口通信的四个通信特征:波特率、奇偶校验、数据位、停止位,是一个字符串;PortOpen:打开/关闭串行端口。TRUE表示串行端口打开,FALSE表示串行端口关闭。输入:从串口接收缓冲区读取数据。输出:将数据写入串行端口发送缓冲区。2)方法当此控件添加到Visual C+项目中时,将为该控件生成一个类。默认情况下,该类的名称是CMSComm。当然,我们可以进行修改。该类提供了很多方法,其中用于上述属性操作的方法有:void SetCommPo

7、rt(短nNew值);该功能用于设置序列号,即CommPort属性。短GetCommPort()该函数用于获取当前操作的序列号。void SetInBufferSize(短nNew值);该函数用于设置输入缓冲区的大小。short GetInBufferSize();这个函数用于获取输入缓冲区的大小。void SetOutBufferSize(短nNew值);该函数用于设置输出缓冲区的大小。short GetOutBufferSize();该函数用于获取输出缓冲区的大小。void SetPortOpen(BOOL bNewValue);该函数根据bNewValue的值打开/关闭串口。TRUE表示

8、打开串口,FALSE表示关闭串口。BOOL GetPortOpen();该函数用于获取当前串口的状态,是打开还是关闭。Void SetOutput(常量变量和新值);该函数用于向串行端口写入数据,或发送数据。VARIANT GetInput();该函数用于从串口读取数据,或接收数据。void set setting(LPCTSTR lpszNewValue);该函数用于设置设置属性。参数lpszNewValue是一个包含波特率、奇偶校验、数据位和停止位的字符串。CString get settings();这个函数用于获取串口的属性,并将它们返回到一个字符串中。void SetCommEven

9、t(短nnew value);该功能用于设置串行事件。这些设定事件发生后,系统会自动响应,响应函数是OnComm。在Visual C+中可以重载这个函数,然后在这个事件响应函数中,使用下面的shortgetcomment()函数对事件进行分析,做出不同的动作。void SetRThreshold(短nnew value);该功能用于设置接收数据事件发生的时间。当接收缓冲区大于或等于参数nNewValue时,将发生接收数据事件,导致执行事件响应函数OnComm。(3)对系列事件响应的介绍MSComm32控件提供了两种方式来响应串行事件:事件驱动模式:当串口事件(数据在接收缓冲区,串口状态改变,串

10、口操作错误等。)发生时,它将导致OnComm事件响应功能运行。因此,可以在应用程序中获取事件,经过分析,针对不同的事件采取不同的动作。该方法具有程序响应及时、可靠性高的优点。查询方式:通过不断检查CommEvent属性,我们可以知道当前串口事件的发生。显然,这种方法没有事件驱动的方式来响应串行事件。比如,当查看者的第一次查看刚刚结束,事件就发生了,但是响应事件要等到找到下一次查看才能响应。(4)使用在Visual+中,使用MSComm控件方法编写串口通信程序时,一般情况是将MSComm控件放入一个对话框中,然后在对话框类中定义该控件对应的控件类型的数据成员,再用该数据成员操作串口。在对话框资源

11、编辑环境中,默认情况下没有MSComm控件。我们可以先将控件添加到项目中,然后会生成一个默认名称为CMsComm的类。而且,对话框资源编辑环境中会出现一个控件的小图标,只需将控件拖入对话框即可。2.2.2实现串行通信的文件方法在16位Windows中,提供了一些关于串行通信的函数,如OpenComm、WriteComm、ReadComm、CloseComm等。还提供了WM_COMMNOTIFY消息。在Win32系统中,除了一般的文件之外,许多设备也作为文件来操作。下面介绍在32位Windows平台下,用Visual C+中的file方法实现串行通信:(1)打开串口在Win32中串口被当作一个文

12、件,它的打开函数是CreateFile。功能原型处理创建文件(LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY _ ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,处理hTemplateFile);第一个参数lpFileName:指定要打开的文件的文件名。第二个参数dwDesiredAccess:访问模式。第三个参数dwShareMode:共享模式。对于串口,该参数必须设置为0,即

13、串口不能像普通文件一样共享,属于独占设备。第四个参数lpSecurityAttributes:SECURITY ATTRIBUTES,指向一个SECURITY_ATTRIBUTES结构,可以用来设置设备文件的关联核心对象的安全属性,从而决定设备文件句柄是否可以继承。通常,给定值为NULL,表示创建的文件句柄不能被继承。第五个参数dwCreationDisposition:创建方法。对于串行端口,此参数必须设置为OPEN_EXISTING属性,这意味着打开现有文件。如果文件(串行端口)不存在,CreateFile功能将失败。因此,它不能设置为CREATE_NEW、CREATE_ALWAYS、OP

14、EN _ ALWAY和STRUNCATE_EXISTING值。第六个参数dwFlagsAndAttributes:表示新创建文件的属性和标志。对于串口,如果设置了FILE_FLAG_OVERLAPPED,则意味着串口通信方式是重叠的,即异步的,读写串口时必须定义重叠结构。如果未设置FILE_FLAG_OVERLAPPED,即默认情况下,串行通信是非重叠的,即同步的。在MS_DOS和16位Windows下,很多程序员习惯使用同步模式。例如,当读取一个文件时,程序将处于等待状态,直到文件被读取并返回,程序才会继续执行。用网络的话说,就是堵。第七个参数hTemplateFile:临时文件的句柄,必须

15、为空。它的返回值:Success:返回文件或设备的句柄,表示该函数成功创建或打开了文件或设备。失败:返回无效句柄值。(2)设置串口状态。打开串口之后,接下来应该就是串口通信了,也就是读写数据。但是我们发现串口通讯程序出现问题的原因是串口的属性设置不正确。因此,在读写串行数据之前,应该设置串口属性。这些属性包括波特率、是否允许奇偶校验、奇偶校验的方式、每个字符的数据位数、接收和发送缓冲区以及停止位数等。在Windows中,这些属性被打包在一个名为DCB的结构中。(3)串口的读写Win32使用ReadFile()和WriteFile()函数,而不是ReadComm()和WriteComm()函数来

16、读写串行端口。(4)异步串行通信对于异步模式下的串行通信,当调用ReadFile函数或WriteFile函数时,调用者会立即返回去做别的事情。Win32使用线程同步内核对象来知道读写是否返回。您可以通过SetCommMask函数设置串口的事件掩码,然后使用WaitCommEvent函数等待一个或多个设置的串口事件。SetCommMask函数:BOOL SetCommMask(处理hFile,DWORD dwEvtMask事件);HFile参数:表示文件句柄。事件:事件遮罩事件掩码可以是下列值的组合:EV_BREAK:检测到输入中断;Ev _ cts: cts信号改变状态;Ev _ DSR: D

17、SR(数据集就绪)信号改变状态;EV_ERR:出现线路状态错误;EV_RING:检测到振铃信号;EV_RXCHAR:输入缓冲区接收一个新字符,并将这个字符放入输入缓冲区;EV_RXFLAG:输入缓冲区接收事件字符(属于DCB结构的EvtChar数据成员);EV_TXEMPTY:将缓冲区中的最后一个字符发送出去;(5)串口超时设置对于串行通信,可以通过设置其超时值来影响读写操作功能的返回。简单来说就是当读写操作超过设定的时间段时返回。Set,首先定义一个COMMTIMEOUTS结构变量,然后通过SetCommmTimeouts函数进行设置。COMMTIMEOUTS结构定义如下:Typedef s

18、truct_COMMTIMEOUTSDWORD ReadIntervalTimeoutDWORD ReadTotalTimeoutMultiplier;DWORD ReadTotalTimeoutConstantDWORD WriteTotalTimeoutMultiplier;DWORD WriteTotalTimeoutConstant;COMMTIMEOUTS,* LPCOMMTIMEOUTSReadIntervalTimeout:指读取两个字符间隔的超时指示器。当一个字符读完时,计时器开始计时。如果超过了这个时间间隔,ReadFile函数将返回。ReadTotalTimeoutMult

19、iplier,WriteTotalTimeoutMultiplier:用于计算总超时的乘数。Readtotaltimeoutconstant,writetotaltimeoutconstant:这个值加上ReadTotalTimeoutMultiplier和要读取的字符数的乘积就是总超时。具体计算公式为(其中bytes指要读取或写入的字节数):总读取超时值=(readtotaltimeoutmultiplier * bytes)+readtotaltimeoutconstant总写入超时值=(writetotaltimeoutmultiplier * bytes)+writetotaltime

20、outconstant(6)关闭串口。当不再使用串口时,要使用CloseHandle函数关闭串口句柄,这就是原型;BOOL close HANDLE(HANDLE hobject);HObject:对于串口,是指使用CreatFile函数打开串口时获得的句柄。它的返回值:TRUE:表示成功关机;FALSE:表示关闭失败;第3章:主要功能简介。3.1打印凭证当汽车到达停车场的入口处时,入口处的停车站关闭。管理员单击“签发票证”按钮后,系统会打印带有当前时间和凭证号的纸质票证。司机拿到这张罚单后,管理员打开停车点,车进入停车场。在系统部门,要保存好这个票号及其相关数据,为后续的出车做准备。3.2捕

21、捉图像在打印凭证时,系统还应该在入口处捕捉一张汽车图像,以便在汽车离开时进行验证。由于上述用法,要求必须将该图像保存在数据库中,以便将来可以跟踪停车场中曾经服务过的车辆。图像格式要求JPEG,大小约为270像素 200像素。3.3扫描条形码在汽车离开之前,司机必须付费。付费时,司机要提供纸质车票。条形码阅读器将纸质票证读入系统。3.4费用本系统采用统一的费率标准:2元/小时。计费的精度至少精确到秒。当司机要离开停车场时,在出口处出示证件进行扫描或人工输入。该系统读出车辆的停车时间,并根据费率计算司机应付的钱。司机交费后,管理员打开阻车器放行车辆。应该备份数据库中汽车的记录,包括使用凭证、进入时

22、间、离开时间、进入时间的图像和支付费用。第四章系统分析与设计4.1数据库设计本系统使用SQL Server数据库VicAly,程序使用ODBC操作数据。以下是VicAly数据库中的数据表。在正式工作之前,管理员或出纳必须输入系统的密码才能进入。所以要设计操作员表,如图所示:SQL语句是:创建表dbo。TAB _ operator(operatorvarchar(50)不为空,密码 varchar (50)空)开主当汽车进入停车场时,系统立即记录时间、司机所持的卡号以及当时汽车的图像,于是设计了TAB_COUNTTIME数据表,如图所示:CARD_ID条形码,即司机所持证件上条形码的含义。IN_

23、TIME是汽车的进入时间。CARD_IMAGE是汽车进入停车场前系统拍摄的照片。SQL语句是:创建表dbo。TAB_COUNTTIME(CARD_ID varchar (50)不为空,IN_TIME datetime空,汽车图片图片空)系统需要保存每辆进入停车场的车辆的历史记录,包括进入时所持的卡、进入时间、离开时间、收费情况以及进入时的图像。根据上述要求设计表TAB_HISTORY_CARD,字段描述如图所示:CARD_ID表示纸卡的卡号,即凭证上打印的条形码。IN_TIME汽车进入的时间。公共汽车离开的时间。PAY_AMOUNT司机支付的费用CAR_IMAGE汽车进入时的画面SQL语句是:

24、创建表dbo。选项卡_历史记录_卡片(CARD_ID varchar (50)空,IN_TIME datetime空,OUT_TIME datetime空,支付金额金额为空,汽车图片图片空)ONPRIMARYTEXTIMAGE _ ONPRIMARY4.2系统配置信息(主要是ODBC数据库)打开配置对话框,配置名为DSN_VicAly的数据源,并将SQL Server作为其驱动程序:并将默认数据库名称更改为VicAly:4.3实现功能的主界面第五章是关键功能及其代码的实现。5.1串行通信本系统中实现串口通信的类是CSerialPort,这是一个开发源代码的类。作者是雷蒙斯派克雷塞。类别的定义:

25、代码示例CSerialPort类定义(串行通信类)/*文件名CSerialPort.h* *目的这个类可以读、写和观察一个串口。*有事发生时,它会向主人发送消息在港口* *该类创建一个用于读写的线程,因此主*程序未被阻止。*作者雷蒙斯派克雷塞*/#ifndef _SERIALPORT_H_#define _SERIALPORT_H_# define WM _ COMM _ BREAK _ DETECTED WM _ USER+1/在输入上检测到中断。# define WM _ COMM _ CTS _ DETECTED WM _ USER+2CTS(清除发送)信号改变了状态。#定义WM _ C

26、OMM _ DSR _检测到的WM _用户+3/DSR(数据设置就绪)信号改变了状态。# define WM _ COMM _ ERR _ DETECTED WM _ USER+4/出现线路状态错误。线路状态错误包括CE_FRAME、CE_OVERRUN和CE_RXPARITY。# define WM _ COMM _ RING _ DETECTED WM _ USER+5/检测到响铃指示器。#定义WM _ COMM _ RLSD _检测到的WM _用户+6/RLSD(接收线路信号检测)信号改变了状态。#define WM_COMM_RXCHAR WM_USER+7/接收到一个字符并将其放入输

27、入缓冲区。# define WM _ COMM _ rx flag _ DETECTED WM _ USER+8/接收到事件字符并将其放入输入缓冲区。# define WM _ COMM _ tx empty _ DETECTED WM _ USER+9/输出缓冲区中的最后一个字符已发送。CSerialPort类公共:BOOL ClearRXBuffer();/建设和破坏CSerialPort();virtual CSerialPort();/端口初始化BOOL InitPort(CWnd* pPortOwner,UINT portnr = 3,UINT baud = 1200,char pa

28、rity = E ,UINT databits = 8,UINT stopsbits = 1,DWORD dwCommEvents = EV _ rx char | EV _ CTS,UINT nBufferSize = 512);/开始/停止通信监视BOOL start monitoring();BOOL restart monitoring();BOOL StopMonitoring()。DWORD GetWriteBufferSize();DWORD GetCommEvents();DCB get DCB();void write toport(char * string);受保护:/受

29、保护的成员函数void process error message(char * ErrorText);静态UINT CommThread(LPVOID PP aram);静态void receive char(CSerialPort * port,COMSTAT COMSTAT);静态void write char(CSerialPort * port);/线程CWinThread * m _ Thread/同步对象CRITICAL _ SECTION m _ csCommunicationSync;BOOL m _ bThreadAlive/句柄处理m _ hShutdownEvent句柄

30、m _ hComm句柄m _ hWriteEvent/事件数组。/每个事件使用一个元素。每个端口有两个事件句柄。/一个写事件和一个接收字符事件,位于重叠结构(m_ov.hEvent)中。/当端口关闭时,一般会关闭。HANDLE m _ hEventArray3;/结构重叠的m _ ovcomm time outs m _ comm time outs;DCB m _ dcb/所有者窗口CWnd * m _ pOwner/杂项UINT m _ nPortNrchar * m _ szWriteBufferDWORD m _ dwCommEventsDWORD m _ nWriteBufferSi

31、ze;#endif _SERIALPORT_H_/*初始化串行端口代码示例初始化串行端口(CSerialPort:InitPort函数)/*/*文件名CSerialPort.cpp/初始化端口。这可以是端口1到4。/BOOL CSerialPort:init port(CWnd * pport owner,/端口的所有者(CWnd)(接收消息)UINT端口号,/端口号(3.6)UINT波特,/波特速率char奇偶校验,/奇偶校验UINT数据比特,/数据比特UINT停止位,/停止位DWORD dwCommEvents,/ EV_RXCHAR,EV_CTS等UINT writebuffersize

32、) /写入缓冲区的大小/assert(port NR 2 & & port NR m _ hWriteEvent);/获得临界区的所有权EnterCriticalSection(& port- m _ cscommuniationsync);if (bWrite)/ Initailize变量端口-m_ov。偏移= 0;端口-m_ov。offset high = 0;/清除缓冲区PurgeComm(port-m_hComm,PURGE _ rx clear | PURGE _ tx clear | PURGE _ rx abort | PURGE _ tx abort);b result = W

33、riteFile(Port- m _ hComm,/COMM端口句柄port-m_szWriteBuffer,/指向调用函数中消息缓冲区的指针strlen(char *)port- m _ szWriteBuffer),/要发送的消息长度&BytesSent,/存储发送的字节数的位置& port- m _ ov);/重叠结构/处理任何错误代码如果(!bResult)DWORD dwError = GetLastError();开关(dwError)案例错误_IO_PENDING:/继续获取OverlappedResults()BytesSent = 0;bWrite = FALSE打破;默认值

34、:/所有其他错误代码port- ProcessErrorMessage( WriteFile();其他LeaveCriticalSection(& port- m _ csCommunicationSync); / end if(bWrite)如果(!bWrite)bWrite = TRUEbr sult = GetOverlappedResult(port- m _ hComm,/COMM端口句柄&port-m_ov,/重叠结构&BytesSent,/存储发送的字节数真);/等待标志LeaveCriticalSection(& port- m _ csCommunicationSync);/

35、处理错误代码如果(!bResult)port- process error message( GetOverlappedResults()in write file(); / end if(!bWrite)/验证发送的数据大小等于我们尝试发送的数据大小if (BytesSent!= strlen(char *)port- m _ szWriteBuffer)TRACE(警告:WriteFile()错误.发送的字节数:% d;消息长度:%dn ,BytesSent,strlen(char *)port- m _ szWriteBuffer);/*接收数据代码示例接收数据(CSerialPort:

36、ReceiveChar函数)/*/收到字符。通知业主/void CSerialPort:receive char(CSerialPort * port,COMSTAT comstat)BOOL bRead = TRUEBOOL bResult = TRUEDWORD dw error = 0;DWORD bytes read = 0;无符号字符RXBufffor(;)/获得comm端口临界区的所有权。/这个过程不保证这个程序的其他部分/正在使用端口对象。EnterCriticalSection(& port- m _ cscommuniationsync);/ ClearCommError()

37、将更新COMSTAT结构并/清除任何其他错误。b result = ClearCommError(port- m _ hComm,&dwError,& comstat);LeaveCriticalSection(& port- m _ csCommunicationSync);/开始永久循环。我使用这种循环是因为我/不知道在运行时需要多少次循环/运行。我的解决方案是启动一个永久循环/当我处理完所有的/数据可用。小心使用这种方法/确保您的循环将会退出。/我这样做的原因在这个例子中并不清楚/因为它在我的生产代码中,但是我发现了这个/解决方案是最有效的方法。if (comstat.cbInQue =

38、 0)/读取所有字节后中断打破;EnterCriticalSection(& port- m _ cscommuniationsync);如果(面包)bResult = ReadFile(port-m_hComm,/COMM端口句柄&RXBuff,/ RX缓冲区指针1,/读取一个字节&BytesRead,/存储读取的字节数& port- m _ ov);/指向m_ov结构的指针/处理错误代码如果(!bResult)开关(dwError = GetLastError()案例错误_IO_PENDING:/异步i/o仍在进行中/继续执行GetOverlappedResults();面包=假;打破;默

39、认值:/发生了另一个错误。处理此错误。port- ProcessErrorMessage( ReadFile();打破;其他/ ReadFile()返回完成。没有必要调用GetOverlappedResults()面包=真; /关闭if (bRead)如果(!面包)面包=真;br sult = GetOverlappedResult(port- m _ hComm,/COMM端口句柄&port-m_ov,/重叠结构&BytesRead,/存储读取的字节数真);/等待标志/处理错误代码如果(!bResult)port- ProcessErrorMessage( GetOverlappedResu

40、lts()in ReadFile(); /关闭if(!面包)LeaveCriticalSection(& port- m _ csCommunicationSync);/通知父节点收到一个字节* SendMessage(port- m _ pow ner)- m _ hWnd,WM_COMM_RXCHAR,(WPARAM) RXBuff,(LPARAM)port- m _ nPortNr); /永远结束循环/*当前功能代码示例工作当前函数(CSerialPort:CommThread函数)/*CommThread函数。/UINT CSerialPort:comm thread(LPVOID P

41、PAR am)/将传递给线程的void指针强制转换回CSerialPort类的指针CSerialPort * port =(CSerialPort *)PP aram;/将对话框类中的状态变量设置为/ TRUE表示线程正在运行。port- m _ bThreadAlive = TRUE;/杂项变量DWORD BytesTransfered = 0;DWORD事件= 0;DWORD CommEvent = 0;DWORD dw error = 0;COMSTAT comstatBOOL bResult = TRUE/启动时清除通信缓冲区if (port-m_hComm) /检查端口是否打开Pur

42、geComm(port-m_hComm,PURGE _ rx clear | PURGE _ tx clear | PURGE _ rx abort | PURGE _ tx abort);/开始永久循环。只要线程还活着,这个循环就会一直运行。for(;)b result = WaitCommEvent(port- m _ hComm,&Event,& port- m _ ov);如果(!bResult)/如果WaitCommEvent()返回FALSE,则处理最后一个错误以确定/原因.开关(dwError = GetLastError()案例错误_IO_PENDING:/如果没有字节,这是一

43、个正常的返回值/在端口读取。/什么都不做,继续打破;案例87:/在Windows NT下,由于某种原因返回该值。/我没有调查为什么,但也是一个有效的回复/也什么都不做,继续。打破;默认值:/所有其他错误代码都表明存在严重错误/发生。处理此错误。port- ProcessErrorMessage( WaitCommEvent();打破;其他/如果WaitCommEvent()返回TRUE,请检查以确保有/缓冲区中要读取的实际字节数。/如果一次从缓冲区读取多个字节/(这个程序不这样做)你会有这种情况发生/到达的第一个字节将导致WaitForMultipleObjects()/函数停止等待。Wait

44、ForMultipleObjects()函数/将m_OverlappedStruct.hEvent中的事件句柄重置为非signelead状态/当它返回时。/如果在重置此事件和调用之间的时间内/ ReadFile()更多字节到达,将再次设置m_OverlappedStruct.hEvent句柄/到签名状态。当调用ReadFile()时,它将/从缓冲区读取所有字节,程序将/循环回到WaitCommEvent()。/此时,您将处于设置了m_OverlappedStruct.hEvent的情况下,/但是没有可供读取的字节。如果你继续打电话/ ReadFile(),由于异步端口设置,它将立即返回,但是/

45、在下一个字符到达之前,GetOverlappedResults()不会返回。/不希望GetOverlappedResults()函数位于/这个状态。线程关闭事件(事件0)和WriteFile()/如果线程被GetOverlappedResults()阻塞,event (Event2)将不起作用。/解决方法是通过调用ClearCommError()来检查缓冲区。/此调用将重置事件句柄,如果没有要读取的字节/我们可以通过WaitCommEvent()再次循环,然后继续。/如果真的有字节要读,什么都不做,继续。b result = ClearCommError(port- m _ hComm,&dw

46、Error,& comstat);if (comstat.cbInQue = 0)继续; /结束if bResult/主等待函数。这个函数通常会阻塞线程/直到发生需要采取行动的九个事件之一。Event = WaitForMultipleObjects(3,port-m_hEventArray,FALSE,INFINITE);开关(事件)案例0:/关闭事件。这是零事件,所以它将是/最高优先级,首先得到服务。port- m _ bThreadAlive = FALSE;/杀死这个线程。休息是不需要的,但让我感觉更好。AfxEndThread(100);打破;案例1: / read事件GetComm

47、Mask(port-m_hComm,& CommEvent);if(通信事件& EV_CTS)* SendMessage(port- m _ pow ner- m _ hWnd,WM_COMM_CTS_DETECTED,(WPARAM) 0,(LPARAM)port- m _ nPortNr);if(通信事件& EV_RXFLAG)* SendMessage(port- m _ pow ner- m _ hWnd,WM_COMM_RXFLAG_DETECTED,(WPARAM) 0,(LPARAM)port- m _ nPortNr);if(通信事件& EV_BREAK)* SendMessa

48、ge(port- m _ pow ner- m _ hWnd,WM_COMM_BREAK_DETECTED,(WPARAM) 0,(LPARAM)port- m _ nPortNr);if(通信事件& EV_ERR)* SendMessage(port- m _ pow ner- m _ hWnd,WM_COMM_ERR_DETECTED,(WPARAM) 0,(LPARAM)port- m _ nPortNr);if(通信事件& EV_RING)* SendMessage(port- m _ pow ner- m _ hWnd,WM_COMM_RING_DETECTED,(WPARAM) 0

49、,(LPARAM)port- m _ nPortNr);if(通信事件& EV_RXCHAR)/从端口接收字符事件。ReceiveChar(port,comstat);打破;情况2: /写入事件/从端口写入字符事件WriteChar(端口);打破; /结束开关 /永远关闭循环返回0;/*5.2视频功能的实现如上所述,本系统具有检查进出停车场车辆的功能,即拍摄所有进入停车场的车辆。当这些车辆驶出时,系统会自动从数据库中取出它们进门时的图像,管理员会对它们进行比对,以确定它们是作为同一辆车辆进出的。下面描述在本系统中实现视频功能的类CAviCap。【代码示例】CAviCap类定义(实现视频功能的类

50、)/*/CAviCap级/构造公共:cavi cap();BOOL capInit(CWnd* pParentWnd,int tx,int ty,int bx,int by,int avi_WindowID,int device index);void cap close();HWND m _ hWndCap/属性公共:/操作公共:/覆盖/ ClassWizard生成的虚函数重写/ AFX _虚拟(AviCap)/AFX_VIRTUAL/实现公共:虚拟 CAviCap();/生成的消息映射函数受保护:私人:/错误处理函数静态LRESULT回调ErrorCallbackProc(HWND hWn

51、d,int nErrID,LPSTR LP errortext);;/*1初始化代码示例CAviCap类的用法/*/文件Avicap.cppBOOL cavi cap:capInit(CWnd * PP arent wnd,int tx,int ty,int bx,int by,int avi_WindowID,int设备索引)/创建一个视频窗口m _ hWndCap = capCreateCaptureWindow(LPSTR)捕获窗口,WS_CHILD|WS_VISIBLE,tx,ty,bx,by,pParentWnd-GetSafeHwnd(),avi _ window id);/连接视

52、频设备capDriverConnect(m_hWndCap,device index);capOverlay (m_hWndCap,TRUE);if (m_hWndCap = NULL)返回FALSE/设置错误处理函数capSetCallbackOnError(m _ hWndCap,cavi cap:ErrorCallbackProc);返回TRUE/*2.捕获图像并将捕获的图像保存到数据库。代码示例CAviCap类的用法/*void CParkSysView:OnGrabimage(CString strCardID)CParkSysApp * app =(CParkSysApp *)Af

53、xGetApp();CString str = app- ExtractFilePath();str+= carin . DIB ;BOOL revalue = capFileSaveDIB(app- avi . m _ hWndCap,(LPCTSTR)str);update window();/判断如果保存图像不成功,则直接返回。如果(!重估)AfxMessageBox(保存图像失败,程序会继续,但是这车出去你就没法比了。);返回;HANDLE hFile = CreateFile(str,GENERIC_READ,0/*文件共享读取|文件共享写入*/,null,/读写共享OPEN_EXI

54、STING,0,0);断言(hFile!=无效句柄值);德沃德希泽;DWORD lsize = GetFileSize(hFile,& hsize);h global ghandle = global alloc(GMEM _可移动,lsize);DWORD s = GlobalSize(ghandle);void * p = global lock(ghandle);DWORD nBytesToRead = lsizeBOOL reval = TRUEreval = ReadFile(hFile,p,nBytesToRead,&nBytesToRead,NULL);close handle(

55、hFile);克隆二进制图像;CCountTime rs_CountTime( &app-数据库);/将二进制文件转换为十六进制文件cs string csSQL = UPDATE TAB _ count time SET CAR _ IMAGE = 0 x ;LPTSTR szTemp =新TCHARlsize * 2+1;外部常量TCHAR十六进制2562;for(DWORD I = 0;i lsizei+)* (szTemp + (i 1) = HEX(无符号字符)*(字节*)p+I)0;* (szTemp + (i 数据库。execute SQL(csSQL);删除SZ temp;BO

56、OL val = global unlock(ghandle);h global h = global free(ghandle);/*数据库中显示的图像不是视频的一部分,而是显示在视图中。代码示例/*void CParkSysView:display image(clong binary * image)DWORD lsize = image- m _ dw datalength;HANDLE ghan dle = image- m _ hData;DWORD s = GlobalSize(ghandle);void * p = global lock(ghandle);DWORD nByt

57、esToWrite = lsize/* #如果已定义(_DEBUG)AfxMessageBox(检查carout.bmp是否存在);#endif*/CString str =(CParkSysApp *)AfxGetApp()- ExtractFilePath();str+= ca rout . BMP ;HANDLE hFile = CreateFile(str,GENERIC_WRITE/*文件共享写入|文件共享读取*/0,NULL,CREATE_ALWAYS,0,0);断言(hFile!=无效句柄值);BOOL reval = WriteFile(hFile,p,nBytesToWrite,& nBytesToWrite,NULL);close handle(hFile);/* #如果已定义(_DEBUG)AfxMessageBox(检查carout.bmp的内容);#endif*/BOOL

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论