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

📄 tcomm32.cpp

📁 简单实用, 功能强大的 C++ Builder 串口控件! 本控件是免费的, 不需要注册, 有关授权及许可协议详见 license.txt 文件。 1.支持二进制数据和文本数据的收发 2.支
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  if(_Opened)
   {
     _Opened = false;
     _ModemStatus = 0; //All modem status OFF after port closed //MS_CTS_ON | MS_DSR_ON | MS_RING_ON | MS_RLSD_ON
     CommNotify(EV_CTS|EV_DSR|EV_RLSD);
   }

  //-- error msg. --
  if(ecErrCode)
   {
     throw EComm32Error(ecErrCode);
   }
}
//---------------------------------------------------------------------------

TComm32::TFlowControl __fastcall TComm32::fGetFCtrl(void)
{
  if(_dcb.fOutxCtsFlow && _dcb.fOutX)
   {
     return fcRtsCtsXonXoff; //6
   }

  if(_dcb.fOutxCtsFlow)
   {
     return fcRtsCts; //3
   }

  if(_dcb.fOutX)
   {
     return fcXonXoff; //4
   }

  //fcTranXonXoff; //5 (not supported)
  return fcNone; //0
}
//---------------------------------------------------------------------------

void __fastcall TComm32::fSetFCtrl(TFlowControl fctrl)
{
  Close();
  switch(fctrl)
   {
     case fcRtsCts:
             _dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
             _dcb.fOutxCtsFlow = true;

             _dcb.fDtrControl = DTR_CONTROL_ENABLE;
             _dcb.fOutxDsrFlow = false;

             _dcb.fInX = false;
             _dcb.fOutX = false;
             break;

     case fcXonXoff:
     case fcTranXonXoff:
             _dcb.fRtsControl = RTS_CONTROL_ENABLE;
             _dcb.fOutxCtsFlow = false;

             _dcb.fDtrControl = DTR_CONTROL_ENABLE;
             _dcb.fOutxDsrFlow = false;

             _dcb.fInX = true;
             _dcb.fOutX = true;
             break;

     case fcRtsCtsXonXoff:
             _dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
             _dcb.fOutxCtsFlow = true;

             _dcb.fDtrControl = DTR_CONTROL_ENABLE;
             _dcb.fOutxDsrFlow = false;

             _dcb.fInX = true;
             _dcb.fOutX = true;
             break;

     default: //fcNone:
             _dcb.fRtsControl = RTS_CONTROL_ENABLE;
             _dcb.fOutxCtsFlow = false;

             _dcb.fDtrControl = DTR_CONTROL_ENABLE;
             _dcb.fOutxDsrFlow = false;

             _dcb.fInX = false;
             _dcb.fOutX = false;
             break;
   }
}
//---------------------------------------------------------------------------

bool __fastcall TComm32::fGetDTR(void) //Computer status, read/write
{
  if(!Active)
    return false;
  return _bDTR;
}
//---------------------------------------------------------------------------

bool __fastcall TComm32::fGetRTS(void) //Computer status, read/write
{
  if(!Active)
    return false;
  return _bRTS;
}
//---------------------------------------------------------------------------

void __fastcall TComm32::fSetDTR(bool b) //Computer status, read/write
{
  if(Active)
    EscapeCommFunction(b?SETDTR:CLRDTR);
  else
    _bDTR = b; //change DTR status after open
}
//---------------------------------------------------------------------------

void __fastcall TComm32::fSetRTS(bool b) //Computer status, read/write
{
  if(Active)
    EscapeCommFunction(b?SETRTS:CLRRTS);
  else
    _bRTS = b; //change RTS status after open
}
//---------------------------------------------------------------------------

void __fastcall TComm32::fmsgCommTimer(void)
{
  DWORD dwStatus;
  GetCommModemStatus(_Handle, &dwStatus);
  if((_ModemStatus^dwStatus)&MS_RLSD_ON)
   {
     _ModemStatus&=~MS_RLSD_ON;
     _ModemStatus|=dwStatus&MS_RLSD_ON;
     CommNotify(EV_RLSD); //由于某些内置 MODEM 不能正确识别
   }

  if(_dwDetectingRing<_DetectRingTime)
   {
     _dwDetectingRing++;
   }
  else if(!(_ModemStatus&MS_RLSD_ON))
   {
     if(dwStatus&MS_RING_ON)
      {
        _dwDetectingRing = 0;
        CommNotify(EV_RING); //由于某些版本的 Windows 不能正确识别
      }
   }
}
//---------------------------------------------------------------------------

long __fastcall TComm32::Read(void far *s, long n)
{
  return _InQueue->Out((char far *)s, n);
}
//---------------------------------------------------------------------------

long __fastcall TComm32::Write(const void far *s, long n)
{
  if(_DisableWrite)
    return 0;

  long Retv = _OutQueue->In((const char far *)s, n);
  SetEvent(_hSyncWrite);
  return Retv;
}
//---------------------------------------------------------------------------

long __fastcall TComm32::Command(const char far *s)
{
  long Retv = _OutQueue->In(s,strlen(s));
  SetEvent(_hSyncWrite);
  return Retv;
}
//---------------------------------------------------------------------------

void __fastcall TComm32::PurgeRead(bool bAbort)
{
  if(_Opened)
   {
     DWORD WhatToPurge = PURGE_RXCLEAR;
     if(bAbort)WhatToPurge|=PURGE_RXABORT;
     PurgeComm(_Handle, WhatToPurge);
     _InQueue->Clear();
   }
}
//---------------------------------------------------------------------------

void __fastcall TComm32::PurgeWrite(bool bAbort)
{
  if(_Opened)
   {
     DWORD WhatToPurge = PURGE_TXCLEAR;
     if(bAbort)WhatToPurge|=PURGE_TXABORT;
     PurgeComm(_Handle, WhatToPurge);
     _OutQueue->Clear();
   }
}
//---------------------------------------------------------------------------

void __fastcall TComm32::ResetModem(void) //reset modem to factory settings
{
  Command(Str_ResetModem);
}
//---------------------------------------------------------------------------

void __fastcall TComm32::InitModem(void) //init modem using TComm32 properties
{
  char szCmd[64];
  sprintf(szCmd, Fmt_InitModem, (int)FlowControl, (int)AutoAnswer);
  Command(szCmd);
}
//---------------------------------------------------------------------------

BOOL __fastcall TComm32::EscapeCommFunction(DWORD dwFunc) //dwFunc: one of the following values: CLRDTR,CLRRTS,SETDTR,SETRTS,SETXOFF,SETXON,SETBREAK,CLRBREAK
{
  if(Active)
   {
     if(::EscapeCommFunction(Handle,dwFunc))
      {
        switch(dwFunc)
         {
           case SETRTS: _bRTS=true ; break;
           case CLRRTS: _bRTS=false; break;
           case SETDTR: _bDTR=true ; break;
           case CLRDTR: _bDTR=false; break;
         }
        return true;
      }
   }
  return false;
}
//---------------------------------------------------------------------------

void __fastcall TComm32::CommNotify(int NotifyType)
{
  if(lpCommNotify)
   {
     try
      {
        lpCommNotify(this, NotifyType);
      }
     catch(...)
      {
        //do nothing (errors occurred on user's event)
      }
   }
}
//---------------------------------------------------------------------------

void __fastcall TComm32::CommAfterOpen(void)
{
  if(lpAfterOpen)
   {
     try
      {
        lpAfterOpen(this);
      }
     catch(...)
      {
        //do nothing (errors occurred on user's event)
      }
   }
}
//---------------------------------------------------------------------------

void __fastcall TComm32::CommBeforeClose(void)
{
  if(lpBeforeClose)
   {
     try
      {
        lpBeforeClose(this);
      }
     catch(...)
      {
        //do nothing (errors occurred on user's event)
      }
   }
}

/***************************************************************************\
*                              EComm32Error                                 *
\***************************************************************************/

__fastcall EComm32Error::EComm32Error(TErrorCode ErrCode)
                        :Exception(MessageStrings().ErrMsg[ErrCode])
{
  _ErrorCode = ErrCode;
  Message = AppLang.FromGBK(Message);
}
//---------------------------------------------------------------------------

__fastcall EComm32Error::MessageStrings::MessageStrings()
{
  switch(AppLang.LangType)
   {
     case TAppLang::ltGbk:
          Err_Messages = Err_Messages_Chs;
          Err_Unknown  = Err_Unknown_Chs ;
          break;

     case TAppLang::ltBig5:
          Err_Messages = Err_Messages_Cht;
          Err_Unknown  = Err_Unknown_Cht ;
          break;

     default:
          Err_Messages = Err_Messages_Enu;
          Err_Unknown  = Err_Unknown_Enu ;
          break;
   }
}
//---------------------------------------------------------------------------

AnsiString __fastcall EComm32Error::MessageStrings::fGetErrMsg(TErrorCode ecCode)
{
  for(ERRMSG *em=Err_Messages; em->Msg; em++)
   if(em->Code==ecCode)
    return em->Msg;
  return Err_Unknown;
}
//---------------------------------------------------------------------------

AnsiString __fastcall EComm32Error::MessageStrings::fGetUnknown(void)
{
  return Err_Unknown;
}
//---------------------------------------------------------------------------

EComm32Error::MessageStrings::ERRMSG EComm32Error::MessageStrings::Err_Messages_Chs[] =
{
  {COMM_NOMEMORY  , "内存不够"              },
  {COMM_INITRDBUF , "不能初始化读缓存"      },
  {COMM_INITWRBUF , "不能初始化写缓存"      },
  {COMM_OPENPORT  , "不能打开端口"          },
  {COMM_SETMASK   , "不能设置端口事件MASK"  },
  {COMM_BUFSIZE   , "不能设置端口缓存"      },
  {COMM_GETSTATE  , "不能得到端口参数"      },
  {COMM_SETSTATE  , "不能设置端口参数"      },
  {COMM_CRRDEVENT , "不能创建端口异步读事件"},
  {COMM_CRWREVENT , "不能创建端口异步写事件"},
  {COMM_CRRDTHREAD, "不能创建端口读线程"    },
  {COMM_CRWRTHREAD, "不能创建端口写线程"    },
  {COMM_CLOSERDT  , "不能关闭端口读线程"    },
  {COMM_CLOSEWRT  , "不能关闭端口写线程"    },
  {COMM_NOERROR   , 0}, //没有错误
};

EComm32Error::MessageStrings::ERRMSG EComm32Error::MessageStrings::Err_Messages_Cht[] =
{
  {COMM_NOMEMORY  , "記憶體不夠"            },
  {COMM_INITRDBUF , "不能初始化讀緩存"      },
  {COMM_INITWRBUF , "不能初始化寫緩存"      },
  {COMM_OPENPORT  , "不能打開埠"            },
  {COMM_SETMASK   , "不能設置埠事件MASK"    },
  {COMM_BUFSIZE   , "不能設置埠緩存"        },
  {COMM_GETSTATE  , "不能得到埠參數"        },
  {COMM_SETSTATE  , "不能設置埠參數"        },
  {COMM_CRRDEVENT , "不能創建埠非同步讀事件"},
  {COMM_CRWREVENT , "不能創建埠非同步寫事件"},
  {COMM_CRRDTHREAD, "不能創建埠讀執行緒"    },
  {COMM_CRWRTHREAD, "不能創建埠寫執行緒"    },
  {COMM_CLOSERDT  , "不能關閉埠讀執行緒"    },
  {COMM_CLOSEWRT  , "不能關閉埠寫執行緒"    },
  {COMM_NOERROR   , 0}, //沒有錯誤
};

EComm32Error::MessageStrings::ERRMSG EComm32Error::MessageStrings::Err_Messages_Enu[] =
{
  {COMM_NOMEMORY  , "Out of memory"                                  },
  {COMM_INITRDBUF , "Cannot initialize read buffer"                  },
  {COMM_INITWRBUF , "Cannot initialize write buffer"                 },
  {COMM_OPENPORT  , "Cannot open COM port"                           },
  {COMM_SETMASK   , "Cannot set comm-mask"                           },
  {COMM_BUFSIZE   , "Cannot set COM port buffer size"                },
  {COMM_GETSTATE  , "Cannot read COM port parameters"                },
  {COMM_SETSTATE  , "Cannot set COM port parameters"                 },
  {COMM_CRRDEVENT , "Cannot create COM port asynchronize read event" },
  {COMM_CRWREVENT , "Cannot create COM port asynchronize write event"},
  {COMM_CRRDTHREAD, "Cannot create COM port read thread"             },
  {COMM_CRWRTHREAD, "Cannot create COM port write thread"            },
  {COMM_CLOSERDT  , "Cannot close COM port read thread"              },
  {COMM_CLOSEWRT  , "Cannot close COM port write thread"             },
  {COMM_NOERROR   , 0}, //沒有錯誤
};
//---------------------------------------------------------------------------

char EComm32Error::MessageStrings::Err_Unknown_Chs[] = "未知错误";
char EComm32Error::MessageStrings::Err_Unknown_Cht[] = "未知錯誤";
char EComm32Error::MessageStrings::Err_Unknown_Enu[] = "Unknown error";
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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