UnitComm.cpp
资源名称:第6章 多线程编程.rar [点击查看]
上传用户:gyjjlc
上传日期:2013-03-29
资源大小:2124k
文件大小:6k
源码类别:
多显示器编程
开发平台:
C++ Builder
- //---------------------------------------------------------------------------
- #pragma hdrstop
- #include "UnitMain.h"
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- __fastcall TCommunication::TCommunication()
- {
- }
- //---------------------------------------------------------------------------
- __fastcall TCommunication::~TCommunication()
- {
- }
- //---------------------------------------------------------------------------
- //初始化串行口
- bool __fastcall TCommunication::ComInitialization(AnsiString DevicePort,
- int BaudRate,int ByteSize, int Parity, int StopBits)
- {
- //串行通信设备的控制(配置)块数据结构
- DCB dcb;
- //串行通信设备的超时参数数据结构
- COMMTIMEOUTS CommTimeOuts;
- //创建串行通信设备句柄
- BOOL fSuccess;
- hCom = CreateFile(DevicePort.c_str(),
- GENERIC_READ | GENERIC_WRITE,
- 0, //必须以opened w/exclusive-access
- NULL, //无安全属性
- OPEN_EXISTING, //必须用OPEN_EXISTING
- FILE_FLAG_OVERLAPPED, //重叠I/O操作
- NULL //对通信设备必须是NULL
- );
- //创建句柄失败...
- if (hCom == INVALID_HANDLE_VALUE) {
- MessageBox(NULL,"打开通信设备文件失败!","错误",MB_OK);
- return false;
- }
- // 设置串行口内部输入(接收),输出(发送)缓冲区长度
- if(!SetupComm(hCom,BLOCK_LENGTH,BLOCK_LENGTH))
- {
- MessageBox(NULL,"设置串行口内部输入、输出缓冲区长度操作异常!","错误",MB_OK);
- return false;
- }
- //获取串行口默认控制(配置)块数据结构
- fSuccess = GetCommState(hCom, &dcb);
- if (!fSuccess) {
- MessageBox(NULL,"获取通信设备控制块数据结构操作异常!","错误",MB_OK);
- return false;
- }
- //填充要改变的串行口控制(配置)块数据结构的有关成员,其它不变...
- dcb.BaudRate = BaudRate;//波特率,由调用者设置,系函数自变量
- dcb.ByteSize = ByteSize;//字长
- dcb.Parity = Parity; //奇偶校验
- dcb.StopBits = StopBits;//停止位
- dcb.fInX = TRUE; //允许输入(接收)Xon/Xoff流量控制
- dcb.fOutX = TRUE; //允许输出(发送)Xon/Xoff流量控制
- dcb.XonLim = BLOCK_LENGTH/4; //接收时发出Xon时的门限值
- dcb.XoffLim = BLOCK_LENGTH/4;//接收时发出Xoff时的门限值
- //用改变后的控制(配置)块数据结构设置串行口
- fSuccess = SetCommState(hCom, &dcb);
- if (!fSuccess) {
- MessageBox(NULL,"设置通信设备控制块数据结构操作异常!","错误",MB_OK);
- return false;
- }
- //获取串行口超时参数
- GetCommTimeouts(hCom, &CommTimeOuts);
- CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
- CommTimeOuts.WriteTotalTimeoutConstant = 5000;
- //用改变后的超时参数的数据结构设置串行口超时参数
- SetCommTimeouts(hCom, &CommTimeOuts);
- //初始化接收重叠数据结构
- memset(&osRead, 0, sizeof(OVERLAPPED));
- //初始化发送重叠数据结构
- memset(&osWrite, 0, sizeof(OVERLAPPED));
- //为接收操作的重叠结构建立信号事件,手工复位方式,初始状态FALSE
- osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- //为发送操作的重叠结构建立信号事件,手工复位方式,初始状态FALSE
- osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- //接收缓冲区Buffer(非内部接收缓冲区)计数器清0
- BufferOffset=0;
- return true;
- }
- //---------------------------------------------------------------------------
- //接收1个或连续若干个字符,接收字符串至接收缓冲区Buffer
- char * __fastcall TCommunication::ReceiveProcess()
- {
- DWORD nLength;
- do
- {
- if((nLength=ReadCommBlock((LPSTR)(Buffer+BufferOffset),BLOCK_LENGTH))>0)
- {
- BufferOffset+=nLength;
- }
- }
- while(nLength>0);
- if(BufferOffset>0)
- {
- //收到字符后,将接收缓冲区变换成0结尾的ASCZ码串
- *(Buffer+BufferOffset)=0;
- BufferOffset=0;
- return Buffer;
- }
- return NULL;
- }
- //---------------------------------------------------------------------------
- //从内部接收缓冲区读取(接收)若干字符
- DWORD __fastcall TCommunication::ReadCommBlock(LPSTR lpBlock,DWORD nMaxLength)
- {
- //串行口状态信息数据结构,可了解内部输入、输出缓冲区中缓存的字节数
- COMSTAT ComStat;
- BOOL fReadStat;
- DWORD dwErrorFlages,dwLength;
- //获取串行口状态信息数据结构,获取出错信息并清除出错标志
- ClearCommError(hCom,&dwErrorFlages,&ComStat);
- //在入口参数指定长度,与串行口内部接收字符数间,取较小者作为将要接收的字符数
- dwLength=(((DWORD)nMaxLength<ComStat.cbInQue)?(DWORD)nMaxLength:ComStat.cbInQue);
- if(dwLength>0)
- {
- //以重叠方式接收指定字符,函数立即返回
- fReadStat=ReadFile(hCom,lpBlock,dwLength,&dwLength,&osRead);
- if(!fReadStat)
- {
- //属重叠方式操作在后台进行的情况...
- if(GetLastError()==ERROR_IO_PENDING)
- {
- //等待1s,若接收事件处于信号态,说明重叠方式操作完成,超时...
- if(WaitForSingleObject(osRead.hEvent,1000)==WAIT_TIMEOUT)
- dwLength=0;
- }
- else dwLength=0;//异常情况
- }
- }
- return dwLength;
- }
- //---------------------------------------------------------------------------
- //发送指定长度的字符串
- BOOL __fastcall TCommunication::WriteCommBlock(LPSTR lpBlock,DWORD nMaxLength)
- {
- BOOL fWriteStat;
- DWORD dwBytesWritten;
- //写入块长度为0时,立即返回,返回值false
- if(nMaxLength==0)return false;
- //逐个发送循环
- for(DWORD i=0;i<nMaxLength;i++)
- {
- //向指定串口写入当前字符,因为重叠方式,函数会不等操作完成立即返回
- fWriteStat = WriteFile(hCom, lpBlock+i, 1, &dwBytesWritten, &osWrite);
- //字符发送重叠操作期间...
- if (!fWriteStat && (GetLastError() == ERROR_IO_PENDING))
- {
- //等待1s期间,字符发送完成(即事件为有信号态)的情况,超时为异常情况
- if (WaitForSingleObject(osWrite.hEvent, 1000)==WAIT_TIMEOUT)
- return false;
- }
- }
- return TRUE;
- }
- //---------------------------------------------------------------------------
English
