📄 tcomm32.cpp
字号:
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 + -