📄 comm.cpp
字号:
//Comm.cpp Rs232c烹脚阑 窍扁 困茄 努贰胶
// 2001斥 3岿 26老 (林) 付捞农肺 肺焊飘 S/W评 沥旷侥
//
#include "stdafx.h"
#include "Comm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CComm, CObject)
// 烹脚橇肺配妮 Table
BYTE _nFlow[] = {FC_NONE,FC_DTRDSR,FC_RTSCTS,FC_XONXOFF};
// 烹脚 单捞鸥 荤捞令 抛捞喉
int _nDataValues[] = {7,8};
// 烹脚加档 Table
int _nBaudRates[] = {// CBR_1200, CBR_2400, CBR_4800,
CBR_9600, CBR_14400, CBR_19200,
CBR_38400, CBR_56000, CBR_57600,
CBR_115200, };
BYTE _nStopBits[] = { ONESTOPBIT, TWOSTOPBITS };
//BOOL bTxEmpty=TRUE;
UINT ReceMessage;
CComm::CComm( )
{
idComDev=NULL;
fConnected=FALSE;
bTxEmpty=TRUE;
}
CComm::~CComm( )
{
DestroyComm();
}
//BEGIN_MESSAGE_MAP(CComm, CObject)
//{{AFX_MSG_MAP(CComm)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
//END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CComm message handlers
//CommWatchProc()
//烹脚阑 窍绰 橇肺技历 溜 单捞鸥啊 甸绢吭阑措 皑矫窍绰
//风凭 夯风凭篮 OpenComPort 窃荐 角青矫 橇肺矫历肺 楷搬凳
//OpenComPort 窃荐 曼炼
DWORD CommWatchProc(LPVOID lpData)
{
DWORD dwEvtMask ;
OVERLAPPED os ;
CComm* npComm = (CComm*) lpData ;
char InData[COM_MAXBLOCK + 1];
int nLength ;
//idCommDev 扼绰 勤甸俊 酒公繁 com 器飘啊 救嘿绢 乐栏搁
// 俊扼 府畔
if ( npComm == NULL ||
!npComm->IsKindOf( RUNTIME_CLASS( CComm ) ) )
return (DWORD)(-1);
memset( &os, 0, sizeof( OVERLAPPED ) ) ;
os.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if ( os.hEvent == NULL )
{
MessageBox( NULL, "Failed to create event for thread!", "comm Error!",
MB_ICONEXCLAMATION | MB_OK );
return ( FALSE ) ;
}
DWORD dwEventFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |
EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY;
if (!SetCommMask(npComm->idComDev, dwEventFlags))
return ( FALSE ) ;
while (npComm->fConnected)
{
dwEvtMask = 0;
WaitCommEvent(npComm->idComDev, &dwEvtMask, NULL );
if ((dwEvtMask & EV_BREAK) == EV_BREAK)
{
;;;
}
else if ((dwEvtMask & EV_CTS) == EV_CTS)
{
;;;
}
else if ((dwEvtMask & EV_ERR) == EV_ERR)
{
;;;
}
else if ((dwEvtMask & EV_RING) == EV_RING)
{
;;;
}
else if ((dwEvtMask & EV_RLSD) == EV_RLSD)
{
;;;
}
else if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
do
{
memset(InData,0,80);
if (nLength = npComm->ReadCommBlock((LPSTR) InData, COM_MAXBLOCK ))
{
npComm->SetReadData(InData,nLength);
//捞镑俊辑 单捞鸥甫 罐绰促.
}
}
while ( nLength > 0 ) ;
}
else if ((dwEvtMask & EV_RXFLAG) == EV_RXFLAG)
{
;;;
}
else if ((dwEvtMask & EV_TXEMPTY) == EV_TXEMPTY)
{
npComm->bTxEmpty = TRUE;
}
}
CloseHandle( os.hEvent );
return( TRUE );
}
//单捞鸥甫 佬绊 单捞鸥甫 佬菌促绰
//皋技瘤甫 府畔茄促.
void CComm::SetReadData(LPSTR data, int nLen)
{
memcpy(abIn,data,nLen);
//汲沥等 扩档快俊 WM_RECEIVEDATA皋技瘤甫
//朝妨林绢 泅力 单捞鸥啊 甸绢吭促绰巴阑
//舅妨霖促.
//SendMessage(m_hwnd,ReceMessage,nLen,0);
SendMessage(m_hwnd,WM_RECEIVEDATA,nLen,0);
}
//皋技瘤甫 傈崔且 hwnd汲沥
void CComm::SetHwnd(HWND hwnd)
{
m_hwnd=hwnd;
}
//com 器飘甫 凯绊 楷搬阑 矫档茄促.
//OpenComport()
BOOL CComm::OpenCommPort(LPTTYSTRUCT lpTTY)
{
char szPort[ 15 ] ;
BOOL fRetVal ;
COMMTIMEOUTS CommTimeOuts ;
osWrite.Offset = 0 ;
osWrite.OffsetHigh = 0 ;
osRead.Offset = 0 ;
osRead.OffsetHigh = 0 ;
//捞亥飘 芒备 汲沥
osRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if (osRead.hEvent == NULL)
{
return FALSE ;
}
osWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if (NULL == osWrite.hEvent)
{
CloseHandle( osRead.hEvent );
return FALSE;
}
if (lpTTY->byCommPort > COM_MAXPORTS)
lstrcpy( szPort, "\\\\.\\TELNET" ) ;
else
wsprintf( szPort, "COM%d", lpTTY->byCommPort );
// COMM device甫 拳老屈侥栏肺 楷搬茄促.
if ((idComDev =
CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL )) == (HANDLE) -1 )
return ( FALSE ) ;
else
{
//哪器飘俊辑 单捞鸥甫 背券窍绰 规过阑 char窜困甫 扁夯栏肺 汲沥窍磊
SetCommMask( idComDev, EV_RXCHAR ) ;
SetupComm( idComDev, 4096, 4096 ) ;
//叼官捞胶俊 静饭扁啊 乐阑瘤 葛福聪鳖 柄昌捞 没家甫 窍磊!
PurgeComm( idComDev, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
CommTimeOuts.WriteTotalTimeoutConstant = 1000 ;
SetCommTimeouts( idComDev, &CommTimeOuts ) ;
}
fRetVal = SetupConnection(lpTTY) ;
if (fRetVal)//楷搬捞 登菌促搁 fRetVal TRUE捞骨肺
{
fConnected = TRUE ;//楷搬登菌促绊 富秦淋
//橇肺矫傈甫 CommWatchProc俊 楷搬窍聪鳖 唱吝俊 单捞鸥啊 吭促艾促
//窍搁 葛电 郴侩篮 CommWatchProc啊 淬寸茄促.
AfxBeginThread((AFX_THREADPROC)CommWatchProc,(LPVOID)this);
}
else
{
fConnected = FALSE ;
CloseHandle( idComDev) ;
}
return ( fRetVal ) ;
}
//拳老肺 汲沥等 哪器飘客 角龙 器飘客 楷搬阑 矫挪促.
//SetupConnection 捞傈俊 CreateComPort甫 秦林绢具 茄促.
BOOL CComm::SetupConnection(LPTTYSTRUCT lpTTY)
{
BOOL fRetVal;
DCB dcb;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState( idComDev, &dcb ) ;//dcb狼 扁夯蔼阑 罐绰促.
dcb.BaudRate = lpTTY->dwBaudRate;
dcb.ByteSize = lpTTY->byByteSize;
dcb.Parity = lpTTY->byParity;
dcb.StopBits = lpTTY->byStopBits;
// setup hardware flow control FC_DTRDSR
BOOL bSet = (BYTE)((lpTTY->byFlowCtrl & FC_DTRDSR) != 0);
dcb.fOutxDsrFlow = bSet;
if(bSet)
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
else
dcb.fDtrControl = DTR_CONTROL_ENABLE;
// FC_RTSCTS
bSet = (BYTE)((lpTTY->byFlowCtrl & FC_RTSCTS) != 0);
dcb.fOutxCtsFlow = bSet;
if(bSet)
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
else
dcb.fRtsControl = RTS_CONTROL_ENABLE;
// setup software flow control FC_XONXOFF
bSet = (BYTE)((lpTTY->byFlowCtrl & FC_XONXOFF) != 0);
dcb.fInX = dcb.fOutX = bSet;
dcb.XonChar = ASCII_XON;
dcb.XoffChar = ASCII_XOFF;
dcb.XonLim = 1;
dcb.XoffLim = 1;
// other various settings
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
fRetVal = SetCommState( idComDev, &dcb ) ; //函版等 Dcb 汲沥
return ( fRetVal ) ;
}
//哪器飘肺 何磐 单捞鸥甫 佬绰促.
int CComm::ReadCommBlock(LPSTR lpszBlock, int nMaxLength )
{
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLength;
// only try to read number of bytes in queue
ClearCommError( idComDev, &dwErrorFlags, &ComStat ) ;
dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
if (dwLength > 0)
{
fReadStat = ReadFile( idComDev, lpszBlock, dwLength, &dwLength, &osRead ) ;
if (!fReadStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
OutputDebugString("\n\rIO Pending");
// we have to wait for read to complete. This function will timeout
// according to the CommTimeOuts.ReadTotalTimeoutConstant variable
// Every time it times out, check for port errors
while(!GetOverlappedResult(idComDev, &osRead,
&dwLength, TRUE))
{
DWORD dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
// normal result if not finished
continue;
}
else
{
// CAN DISPLAY ERROR MESSAGE HERE
// an error occured, try to recover
::ClearCommError(idComDev, &dwErrorFlags, &ComStat);
if(dwErrorFlags > 0)
{
// CAN DISPLAY ERROR MESSAGE HERE
}
break;
}
}
}
else
{
// some other error occured
dwLength = 0;
ClearCommError(idComDev, &dwErrorFlags, &ComStat);
if(dwErrorFlags > 0)
{
// CAN DISPLAY ERROR MESSAGE HERE
}
}
}
}
return ( dwLength ) ;
}
// 哪器飘俊 单捞磐甫 敬促.
BOOL CComm::WriteCommBlock( LPSTR lpByte , DWORD dwBytesToWrite)
{
DWORD dwErrorFlags;
BOOL fWriteStat ;
DWORD dwBytesWritten ;
COMSTAT ComStat;
DWORD dwLength = dwBytesToWrite;
bTxEmpty = FALSE;
fWriteStat = WriteFile( idComDev, lpByte, dwBytesToWrite, &dwBytesWritten, &osWrite ) ;
//if (dwBytesToWrite != dwBytesWritten)
if(!fWriteStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
OutputDebugString("\n\rIO Pending");
// 佬阑 巩磊啊 巢酒 乐芭唱 傈价且 巩磊啊 巢酒 乐阑 版快 Overapped IO狼
// 漂己俊 蝶扼 ERROR_IO_PENDING 俊矾 皋矫瘤啊 傈崔等促.
//timeouts俊 沥秦霖 矫埃父怒 扁促妨霖促.
while(!GetOverlappedResult(idComDev, &osWrite,
&dwLength, TRUE))
{
DWORD dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
// normal result if not finished
continue;
}
else
{
// CAN DISPLAY ERROR MESSAGE HERE
// an error occured, try to recover
::ClearCommError(idComDev, &dwErrorFlags, &ComStat);
if(dwErrorFlags > 0)
{
// CAN DISPLAY ERROR MESSAGE HERE
AfxMessageBox("ERROR");
}
break;
}
}
}
else
{ // some other error occured
dwLength = 0;
ClearCommError(idComDev, &dwErrorFlags, &ComStat);
if(dwErrorFlags > 0)
{
// CAN DISPLAY ERROR MESSAGE HERE
AfxMessageBox("ERROR");
}
}
}
return ( TRUE ) ;
}
//哪器飘甫 肯傈洒 秦力茄促.
BOOL CComm::DestroyComm()
{
if (fConnected)
CloseConnection();
if (osRead.hEvent!=NULL)
CloseHandle( osRead.hEvent ) ;
if (osWrite.hEvent != NULL)
CloseHandle( osWrite.hEvent ) ;
return ( TRUE ) ;
}
//楷搬阑 摧绰促.
BOOL CComm::CloseConnection()
{
// set connected flag to FALSE
fConnected = FALSE ;
// disable event notification and wait for thread
// to halt
SetCommMask( idComDev, 0 ) ;
EscapeCommFunction( CLRDTR ) ;
EscapeCommFunction( CLRRTS ) ;
PurgeComm( idComDev, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
CloseHandle( idComDev ) ;
return ( TRUE ) ;
}
void CComm::EscapeCommFunction(DWORD dwFunc)
{
// TODO: Add your control notification handler code here
::EscapeCommFunction(idComDev,dwFunc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -