UnitComm.cpp
上传用户:gyjjlc
上传日期:2013-03-29
资源大小:2124k
文件大小:6k
源码类别:

多显示器编程

开发平台:

C++ Builder

  1. //---------------------------------------------------------------------------
  2. #pragma hdrstop
  3. #include "UnitMain.h"
  4. //---------------------------------------------------------------------------
  5. #pragma package(smart_init)
  6. __fastcall TCommunication::TCommunication()
  7. {
  8. }
  9. //---------------------------------------------------------------------------
  10. __fastcall TCommunication::~TCommunication()
  11. {
  12. }
  13. //---------------------------------------------------------------------------
  14. //初始化串行口
  15. bool __fastcall TCommunication::ComInitialization(AnsiString DevicePort,
  16.         int BaudRate,int ByteSize, int Parity, int StopBits)
  17. {
  18.     //串行通信设备的控制(配置)块数据结构
  19.     DCB dcb;
  20.     //串行通信设备的超时参数数据结构
  21.     COMMTIMEOUTS CommTimeOuts;
  22.     //创建串行通信设备句柄
  23.     BOOL fSuccess;
  24.     hCom = CreateFile(DevicePort.c_str(),
  25.         GENERIC_READ | GENERIC_WRITE,
  26.         0,    //必须以opened w/exclusive-access
  27.         NULL, //无安全属性
  28.         OPEN_EXISTING, //必须用OPEN_EXISTING
  29.         FILE_FLAG_OVERLAPPED,  //重叠I/O操作
  30.         NULL  //对通信设备必须是NULL
  31.         );
  32.     //创建句柄失败...
  33.     if (hCom == INVALID_HANDLE_VALUE) {
  34.         MessageBox(NULL,"打开通信设备文件失败!","错误",MB_OK);
  35.         return false;
  36.     }
  37.     // 设置串行口内部输入(接收),输出(发送)缓冲区长度
  38.     if(!SetupComm(hCom,BLOCK_LENGTH,BLOCK_LENGTH))
  39.     {
  40.         MessageBox(NULL,"设置串行口内部输入、输出缓冲区长度操作异常!","错误",MB_OK);
  41.         return false;
  42.     }
  43.     //获取串行口默认控制(配置)块数据结构
  44.     fSuccess = GetCommState(hCom, &dcb);
  45.     if (!fSuccess) {
  46.         MessageBox(NULL,"获取通信设备控制块数据结构操作异常!","错误",MB_OK);
  47.         return false;
  48.     }
  49.     //填充要改变的串行口控制(配置)块数据结构的有关成员,其它不变...
  50.     dcb.BaudRate = BaudRate;//波特率,由调用者设置,系函数自变量
  51.     dcb.ByteSize = ByteSize;//字长
  52.     dcb.Parity = Parity;    //奇偶校验
  53.     dcb.StopBits = StopBits;//停止位
  54.     dcb.fInX =  TRUE;             //允许输入(接收)Xon/Xoff流量控制
  55.     dcb.fOutX =  TRUE;            //允许输出(发送)Xon/Xoff流量控制
  56.     dcb.XonLim =  BLOCK_LENGTH/4; //接收时发出Xon时的门限值
  57.     dcb.XoffLim =  BLOCK_LENGTH/4;//接收时发出Xoff时的门限值
  58.     //用改变后的控制(配置)块数据结构设置串行口
  59.     fSuccess = SetCommState(hCom, &dcb);
  60.     if (!fSuccess) {
  61.         MessageBox(NULL,"设置通信设备控制块数据结构操作异常!","错误",MB_OK);
  62.         return false;
  63.     }
  64.     //获取串行口超时参数
  65.     GetCommTimeouts(hCom, &CommTimeOuts);
  66.     CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
  67. CommTimeOuts.WriteTotalTimeoutConstant = 5000;
  68.     //用改变后的超时参数的数据结构设置串行口超时参数
  69. SetCommTimeouts(hCom, &CommTimeOuts);
  70.     //初始化接收重叠数据结构
  71.     memset(&osRead, 0, sizeof(OVERLAPPED));
  72.     //初始化发送重叠数据结构
  73.     memset(&osWrite, 0, sizeof(OVERLAPPED));
  74.     //为接收操作的重叠结构建立信号事件,手工复位方式,初始状态FALSE
  75.     osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  76.     //为发送操作的重叠结构建立信号事件,手工复位方式,初始状态FALSE
  77.     osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  78.     //接收缓冲区Buffer(非内部接收缓冲区)计数器清0
  79.     BufferOffset=0;
  80.     return true;
  81. }
  82. //---------------------------------------------------------------------------
  83. //接收1个或连续若干个字符,接收字符串至接收缓冲区Buffer
  84. char * __fastcall TCommunication::ReceiveProcess()
  85. {
  86.     DWORD nLength;
  87.     do
  88.     {
  89.         if((nLength=ReadCommBlock((LPSTR)(Buffer+BufferOffset),BLOCK_LENGTH))>0)
  90.         {
  91.             BufferOffset+=nLength;
  92.         }
  93.     }
  94.     while(nLength>0);
  95.     if(BufferOffset>0)
  96.     {
  97.         //收到字符后,将接收缓冲区变换成0结尾的ASCZ码串
  98.         *(Buffer+BufferOffset)=0;
  99.         BufferOffset=0;
  100.         return Buffer;
  101.     }
  102.     return NULL;
  103. }
  104. //---------------------------------------------------------------------------
  105. //从内部接收缓冲区读取(接收)若干字符
  106. DWORD __fastcall TCommunication::ReadCommBlock(LPSTR lpBlock,DWORD nMaxLength)
  107. {
  108.     //串行口状态信息数据结构,可了解内部输入、输出缓冲区中缓存的字节数
  109.     COMSTAT ComStat;
  110.     BOOL fReadStat;
  111.     DWORD dwErrorFlages,dwLength;
  112.     //获取串行口状态信息数据结构,获取出错信息并清除出错标志
  113.     ClearCommError(hCom,&dwErrorFlages,&ComStat);
  114.     //在入口参数指定长度,与串行口内部接收字符数间,取较小者作为将要接收的字符数
  115.     dwLength=(((DWORD)nMaxLength<ComStat.cbInQue)?(DWORD)nMaxLength:ComStat.cbInQue);
  116.     if(dwLength>0)
  117.     {
  118.         //以重叠方式接收指定字符,函数立即返回
  119.         fReadStat=ReadFile(hCom,lpBlock,dwLength,&dwLength,&osRead);
  120.         if(!fReadStat)
  121.         {
  122.             //属重叠方式操作在后台进行的情况...
  123.             if(GetLastError()==ERROR_IO_PENDING)
  124.             {
  125.                 //等待1s,若接收事件处于信号态,说明重叠方式操作完成,超时...
  126.                 if(WaitForSingleObject(osRead.hEvent,1000)==WAIT_TIMEOUT)
  127.                     dwLength=0;
  128.             }
  129.             else dwLength=0;//异常情况
  130.         }
  131.     }
  132.     return dwLength;
  133. }
  134. //---------------------------------------------------------------------------
  135. //发送指定长度的字符串
  136. BOOL  __fastcall TCommunication::WriteCommBlock(LPSTR lpBlock,DWORD nMaxLength)
  137. {
  138.     BOOL fWriteStat;
  139. DWORD dwBytesWritten;
  140.     //写入块长度为0时,立即返回,返回值false
  141.     if(nMaxLength==0)return false;
  142.     //逐个发送循环
  143.     for(DWORD i=0;i<nMaxLength;i++)
  144.     {
  145.         //向指定串口写入当前字符,因为重叠方式,函数会不等操作完成立即返回
  146.     fWriteStat = WriteFile(hCom, lpBlock+i, 1, &dwBytesWritten, &osWrite);
  147.         //字符发送重叠操作期间...
  148.     if (!fWriteStat && (GetLastError() == ERROR_IO_PENDING))
  149.     {
  150.             //等待1s期间,字符发送完成(即事件为有信号态)的情况,超时为异常情况
  151.      if (WaitForSingleObject(osWrite.hEvent, 1000)==WAIT_TIMEOUT)
  152.                 return false;
  153.     }
  154.     }
  155.     return TRUE;
  156. }
  157. //---------------------------------------------------------------------------