⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comm.h

📁 模拟数字硬盘录像机部分功能
💻 H
📖 第 1 页 / 共 2 页
字号:
/*
Comm Base Library(WIN98/NT/2000) ver 1.1
Compile by: BC++ 5; C++ BUILDER 4, 5, 6, X; VC++ 5, 6; VC.NET; GCC;
copyright(c) 2004.5 - 2005.8 llbird wushaojian@21cn.com
*/ 
#ifndef _COMM_H_
#define _COMM_H_

#pragma warning(disable: 4530)
#pragma warning(disable: 4786)
#pragma warning(disable: 4800)

#include <assert.h>
#include <stdio.h>
#include <windows.h>

//送到窗口的消息 WPARAM 端口号
#define ON_COM_RECEIVE WM_USER + 618
#define ON_COM_CTS WM_USER + 619 //LPARAM 1 valid
#define ON_COM_DSR WM_USER + 621 //LPARAM 1 valid
#define ON_COM_RING WM_USER + 623
#define ON_COM_RLSD WM_USER + 624
#define ON_COM_BREAK WM_USER + 625
#define ON_COM_TXEMPTY WM_USER + 626
#define ON_COM_ERROR WM_USER + 627 //LPARAM save Error ID
#define DEFAULT_COM_MASK_EVENT EV_RXCHAR | EV_ERR | EV_CTS | EV_DSR | EV_BREAK | EV_TXEMPTY | EV_RING | EV_RLSD

class cnComm
{
  public:  

  //------------------------------Construction-----------------------------------
  //第1个参数为是否在打开串口时启动监视线程, 第2个参数为IO方式 阻塞方式(0)/ 异步重叠方式(默认)
  cnComm(bool fAutoBeginThread = true, DWORD dwIOMode =
FILE_FLAG_OVERLAPPED): _dwIOMode(dwIOMode), _fAutoBeginThread(fAutoBeginThread)
  {
    Init();
  }

  virtual ~cnComm()
  {
    Close();
    UnInit();
  }

  //----------------------------------Attributes----------------------------------
  //判断串口是否打开
  inline bool IsOpen()
  {
    return _hCommHandle != INVALID_HANDLE_VALUE;
  }
  //判断串口是否打开
  operator bool()
  {
    return _hCommHandle != INVALID_HANDLE_VALUE;
  }
  //获得串口句炳
  inline HANDLE GetHandle()
  {
    return _hCommHandle;
  }
  //获得串口句炳
  operator HANDLE()
  {
    return _hCommHandle;
  }
  //获得串口参数 DCB
  DCB *GetState()
  {
    return IsOpen() && ::GetCommState(_hCommHandle, &_DCB) == TRUE ?
    &_DCB: NULL;
  }
  //设置串口参数 DCB
  bool SetState(DCB *pdcb = NULL)
  {
    return IsOpen() ? ::SetCommState(_hCommHandle, pdcb == NULL ? &_DCB:pdcb) == TRUE: false;
  }
  //设置串口参数:波特率,停止位,等 支持设置字符串 "9600, 8, n, 1"
  bool SetState(char *szSetStr)
  {
    if (IsOpen())
    {
      if (::GetCommState(_hCommHandle, &_DCB) != TRUE)
        return false;
      if (::BuildCommDCB(szSetStr, &_DCB) != TRUE)
        return false;
      return ::SetCommState(_hCommHandle, &_DCB) == TRUE;
    }
    return false;
  }
  //设置串口参数:波特率,停止位,等
  bool SetState(DWORD dwBaudRate, DWORD dwByteSize = 8, DWORD dwParity =
NOPARITY, DWORD dwStopBits = ONESTOPBIT)
  {
    if (IsOpen())
    {
      if (::GetCommState(_hCommHandle, &_DCB) != TRUE)
        return false;
      _DCB.BaudRate = dwBaudRate;
      _DCB.ByteSize = (unsigned char)dwByteSize;
      _DCB.Parity = (unsigned char)dwParity;
      _DCB.StopBits = (unsigned char)dwStopBits;
      return ::SetCommState(_hCommHandle, &_DCB) == TRUE;
    }
    return false;
  }
  //获得超时结构
  LPCOMMTIMEOUTS GetTimeouts(void)
  {
    return IsOpen() && ::GetCommTimeouts(_hCommHandle, &_CO) == TRUE ?
&_CO: NULL;
  }
  //设置超时
  bool SetTimeouts(LPCOMMTIMEOUTS lpCO)
  {
    return IsOpen() ? ::SetCommTimeouts(_hCommHandle, lpCO) == TRUE:false;
  }
  //设置串口的I/O缓冲区大小
  bool SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize)
  {
    return IsOpen() ? ::SetupComm(_hCommHandle, dwInputSize, dwOutputSize)== TRUE: false;
  }
  //关联消息的窗口句柄
  inline void SetWnd(HWND hWnd)
  {
    assert(::IsWindow(hWnd));
    _hNotifyWnd = hWnd;
  }
  //设定发送通知, 接受字符最小值
  inline void SetNotifyNum(DWORD dwNum)
  {
    _dwNotifyNum = dwNum;
  }
  //线程是否运行
  inline bool IsThreadRunning()
  {
    return _hThreadHandle != NULL;
  }
  //获得线程句柄
  inline HANDLE GetThread()
  {
    return _hThreadHandle;
  }
  //设置要监视的事件, 打开前设置有效
  void SetMaskEvent(DWORD dwEvent = DEFAULT_COM_MASK_EVENT)
  {
    _dwMaskEvent = dwEvent;
  }
  //获得读缓冲区的字符数
  int GetInputSize()
  {
    COMSTAT Stat;
    DWORD dwError;

    return ::ClearCommError(_hCommHandle, &dwError, &Stat) == TRUE ? Stat.cbInQue : (DWORD) - 1L;
  }

  //----------------------------------Operations----------------------------------
  //打开串口 缺省 9600, 8, n, 1
  bool Open(DWORD dwPort)
  {
    return Open(dwPort, 9600);
  }
  //打开串口 缺省 baud_rate, 8, n, 1
  bool Open(DWORD dwPort, DWORD dwBaudRate)
  {
    if (dwPort < 1 || dwPort > 1024)
      return false;
    BindCommPort(dwPort);

    if (!OpenCommPort())
      return false;

    if (!SetupPort())
      return false;

    return SetState(dwBaudRate);
  }
  //打开串口, 使用类似"9600, 8, n, 1"的设置字符串设置串口
  bool Open(DWORD dwPort, char *szSetStr)
  {
    if (dwPort < 1 || dwPort > 1024)
      return false;

    BindCommPort(dwPort);

    if (!OpenCommPort())
      return false;

    if (!SetupPort())
      return false;

    return SetState(szSetStr);
  }
  //读取串口 dwBufferLength个字符到 Buffer 返回实际读到的字符数 可读任意数据
  DWORD Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime = 10)
  {
    if (!IsOpen())
      return 0;

    COMSTAT Stat;
    DWORD dwError;

    if (::ClearCommError(_hCommHandle, &dwError, &Stat) && dwError > 0)
    {
      ::PurgeComm(_hCommHandle,PURGE_RXABORT | PURGE_RXCLEAR);
      return 0;
    }  
    if (!Stat.cbInQue)
      // 缓冲区无数据
      return 0;

    unsigned long uReadLength = 0;

    dwBufferLength = dwBufferLength > Stat.cbInQue ? Stat.cbInQue :dwBufferLength;

    if (!::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength,&_ReadOverlapped))
    {
      if (::GetLastError() == ERROR_IO_PENDING)
      {
        WaitForSingleObject(_ReadOverlapped.hEvent, dwWaitTime);
        // 结束异步I/O
        if (!::GetOverlappedResult(_hCommHandle, &_ReadOverlapped,&uReadLength, false))
        {
          if (::GetLastError() != ERROR_IO_INCOMPLETE)
            uReadLength = 0;
        }
      }
      else
        uReadLength = 0;
    }

    return uReadLength;
  }
  //读取串口 dwBufferLength - 1 个字符到 szBuffer 返回ANSI C 模式字符串指针 适合一般字符通讯

  char *ReadString(char *szBuffer, DWORD dwBufferLength, DWORD dwWaitTime =20)
  {
    unsigned long uReadLength = Read(szBuffer, dwBufferLength - 1,dwWaitTime);
    szBuffer[uReadLength] = '\0';
    return szBuffer;
  }
  //写串口 可写任意数据 "abcd" or "\x0\x1\x2"
  DWORD Write(LPVOID Buffer, DWORD dwBufferLength)
  {
    if (!IsOpen())
      return 0;

    DWORD dwError;

    if (::ClearCommError(_hCommHandle, &dwError, NULL) && dwError > 0)
      ::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR);

    unsigned long uWriteLength = 0;

    if (!::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength,&_WriteOverlapped))
      if (::GetLastError() != ERROR_IO_PENDING)
        uWriteLength = 0;

      return uWriteLength;
    }
    //写串口 写ANSI C 模式字符串指针 
    DWORD Write(const char *szBuffer)
    {
      assert(szBuffer);

      return Write((void*)szBuffer, strlen(szBuffer));
    }
    //读串口 同步应用
    DWORD ReadSync(LPVOID Buffer, DWORD dwBufferLength)
    {
      if (!IsOpen())
        return 0;

      DWORD dwError;
      if (::ClearCommError(_hCommHandle, &dwError, NULL) && dwError > 0)
      {
        ::PurgeComm(_hCommHandle,PURGE_RXABORT | PURGE_RXCLEAR);
        return 0;
      }

      DWORD uReadLength = 0;
      ::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, NULL);
      return uReadLength;
    }
    //写串口 同步应用
    DWORD WriteSync(LPVOID Buffer, DWORD dwBufferLength)
    {
      if (!IsOpen())
        return 0;

      DWORD dwError;
      if (::ClearCommError(_hCommHandle, &dwError, NULL) && dwError > 0)
        ::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR);

      unsigned long uWriteLength = 0;
      ::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength, NULL);
      return uWriteLength;
    }
    //写串口 szBuffer 可以输出格式字符串 包含缓冲区长度
    DWORD Write(char *szBuffer, DWORD dwBufferLength, char *szFormat, ...)
    {
      if (!IsOpen())
        return 0;

      va_list va;
      va_start(va, szFormat);
      _vsnprintf(szBuffer, dwBufferLength, szFormat, va);
      va_end(va);

      return Write(szBuffer);
    }
    //写串口 szBuffer 可以输出格式字符串 不检查缓冲区长度 小心溢出
    DWORD Write(char *szBuffer, char *szFormat, ...)
    {
      if (!IsOpen())
        return 0;

      va_list va;
      va_start(va, szFormat);
      vsprintf(szBuffer, szFormat, va);
      va_end(va);

      return Write(szBuffer);
    }
    //关闭串口 同时也关闭关联线程
    virtual void Close()
    {
      if (IsOpen())
      {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -