/*
Comm Base Library ( WIN98 / NT / 2000 ) ver 1.1
Compile by <EFBFBD> <EFBFBD> BC + + 5 ; C + + Builder 4 , 5 , 6 , X ; VC + + 5 , 6 ; VC . net ; GCC ;
copyright ( c ) 2004.5 - 2005.8 llbird wushaojian @ 21 cn . com
*/
# ifndef _CN_COMM_H_
# define _CN_COMM_H_
# pragma warning(disable: 4530)
# pragma warning(disable: 4786)
# pragma warning(disable: 4800)
//<2F> <> <EFBFBD> α <EFBFBD> <CEB1> 뾯<EFBFBD> <EBBEAF>
# pragma warning(disable : 4244)
# pragma warning(disable : 4305)
# pragma warning(disable : 4996)
# pragma warning(disable : 4101)
# include <assert.h>
# include <stdio.h>
# include <Windows.h>
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĵ<EFBFBD> <C4B4> <EFBFBD> <EFBFBD> <EFBFBD> : <20> ṩ<EFBFBD> <E1B9A9> ͨ<EFBFBD> õĴ<C3B5> <C4B4> ڲ<EFBFBD> <DAB2> <EFBFBD>
/*
<EFBFBD> <EFBFBD> <EFBFBD> 崮 <EFBFBD> ڶ <EFBFBD> <EFBFBD> <EFBFBD>
cnComm com ;
1. ʹ <EFBFBD> <EFBFBD> ʱ <EFBFBD> <EFBFBD> Ҫ <EFBFBD> <EFBFBD> <EFBFBD> ڳ <EFBFBD> ʼ <EFBFBD> <EFBFBD> ʱ <EFBFBD> <EFBFBD> <EFBFBD> ڣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ò <EFBFBD> <EFBFBD> <EFBFBD>
com . Open ( ) ;
2. <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
com . Write ( m_send ) ; //m_sendΪ<64> <CEAA> <EFBFBD> ͵<EFBFBD> <CDB5> ַ<EFBFBD> <D6B7> <EFBFBD>
3. <EFBFBD> <EFBFBD> <EFBFBD> մ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϣ <EFBFBD> <EFBFBD> Ҫ <EFBFBD> õ <EFBFBD> <EFBFBD> Ի <EFBFBD> <EFBFBD> <EFBFBD> ( <EFBFBD> Զ <EFBFBD> <EFBFBD> <EFBFBD> ȡ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )
Ϊ <EFBFBD> <EFBFBD> <EFBFBD> ڵ Ľ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ¼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> û <EFBFBD> <EFBFBD> <EFBFBD> Ϣ ON_COM_RECEIVE
afx_msg void OnCommRecv ( WPARAM wParam , LPARAM lParam ) ;
ON_MESSAGE ( ON_COM_RECEIVE , OnCommRecv )
<EFBFBD> Ի <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> <EFBFBD> ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
com . SetWnd ( AfxGetMainWnd ( ) - > m_hWnd ) ;
<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
void CSerialPortClassDlg : : OnCommRecv ( WPARAM wParam , LPARAM lParam )
{
<EFBFBD> <EFBFBD> //<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ϵ<EFBFBD> <CFB5> ַ<EFBFBD>
<EFBFBD> <EFBFBD> char str [ 100 ] ;
<EFBFBD> <EFBFBD> com . ReadString ( str , 100 ) ;
}
*/
//<2F> ͵<EFBFBD> <CDB5> <EFBFBD> <EFBFBD> ڵ<EFBFBD> <DAB5> <EFBFBD> Ϣ WPARAM <20> ˿ں<CBBF>
# 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-----------------------------------
//<2F> <> 1<EFBFBD> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> Ƿ<EFBFBD> <C7B7> ڴ<DAB4> <F2BFAAB4> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̣߳<DFB3> <20> <> 2<EFBFBD> <32> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪIO<49> <4F> ʽ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ <EFBFBD> <CABD> 0<EFBFBD> <30> / <20> 첽<EFBFBD> ص<EFBFBD> <D8B5> <EFBFBD> ʽ <EFBFBD> <CABD> Ĭ<EFBFBD> ϣ<EFBFBD>
cnComm ( bool fAutoBeginThread = true , DWORD dwIOMode = FILE_FLAG_OVERLAPPED ) : _dwIOMode ( dwIOMode ) , _fAutoBeginThread ( fAutoBeginThread )
{
Init ( ) ;
}
virtual ~ cnComm ( )
{
Close ( ) ;
UnInit ( ) ;
}
//----------------------------------Attributes----------------------------------
//<2F> жϴ<D0B6> <CFB4> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD>
inline bool IsOpen ( )
{
return _hCommHandle ! = INVALID_HANDLE_VALUE ;
}
//<2F> жϴ<D0B6> <CFB4> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD>
operator bool ( )
{
return _hCommHandle ! = INVALID_HANDLE_VALUE ;
}
//<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> ھ <EFBFBD> <DABE> <EFBFBD>
inline HANDLE GetHandle ( )
{
return _hCommHandle ;
}
//<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> ھ <EFBFBD> <DABE> <EFBFBD>
operator HANDLE ( )
{
return _hCommHandle ;
}
//<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> ڲ<EFBFBD> <DAB2> <EFBFBD> DCB
DCB * GetState ( )
{
return IsOpen ( ) & & : : GetCommState ( _hCommHandle , & _DCB ) = = TRUE ?
& _DCB : NULL ;
}
//<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> ڲ<EFBFBD> <DAB2> <EFBFBD> DCB
bool SetState ( DCB * pdcb = NULL )
{
return IsOpen ( ) ? : : SetCommState ( _hCommHandle , pdcb = = NULL ? & _DCB : pdcb ) = = TRUE : false ;
}
//<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> ڲ<EFBFBD> <DAB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʣ<EFBFBD> ֹͣλ<D6B9> <CEBB> <EFBFBD> <EFBFBD> ֧<> <D6A7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> "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 ;
}
//<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> ڲ<EFBFBD> <DAB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʣ<EFBFBD> ֹͣλ<D6B9> <CEBB> <EFBFBD> <EFBFBD>
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 ;
}
//<2F> <> <EFBFBD> ó<EFBFBD> ʱ<EFBFBD> ṹ
LPCOMMTIMEOUTS GetTimeouts ( void )
{
return IsOpen ( ) & & : : GetCommTimeouts ( _hCommHandle , & _CO ) = = TRUE ? & _CO : NULL ;
}
//<2F> <> <EFBFBD> ó<EFBFBD> ʱ
bool SetTimeouts ( LPCOMMTIMEOUTS lpCO )
{
return IsOpen ( ) ? : : SetCommTimeouts ( _hCommHandle , lpCO ) = = TRUE : false ;
}
//<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> ڵ<EFBFBD> I/O<> <4F> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С
bool SetBufferSize ( DWORD dwInputSize , DWORD dwOutputSize )
{
return IsOpen ( ) ? : : SetupComm ( _hCommHandle , dwInputSize , dwOutputSize ) = = TRUE : false ;
}
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϣ<EFBFBD> Ĵ<EFBFBD> <C4B4> ھ <EFBFBD> <DABE> <EFBFBD>
inline void SetWnd ( HWND hWnd )
{
assert ( : : IsWindow ( hWnd ) ) ;
_hNotifyWnd = hWnd ;
}
//<2F> 趨<EFBFBD> <E8B6A8> <EFBFBD> <EFBFBD> ֪ͨ, <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> С ֵ
inline void SetNotifyNum ( DWORD dwNum )
{
_dwNotifyNum = dwNum ;
}
//<2F> ߳<EFBFBD> <DFB3> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD>
inline bool IsThreadRunning ( )
{
return _hThreadHandle ! = NULL ;
}
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ߳̾<DFB3> <CCBE> <EFBFBD>
inline HANDLE GetThread ( )
{
return _hThreadHandle ;
}
//<2F> <> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ӵ<EFBFBD> <D3B5> ¼<EFBFBD> <C2BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ч
void SetMaskEvent ( DWORD dwEvent = DEFAULT_COM_MASK_EVENT )
{
_dwMaskEvent = dwEvent ;
}
//<2F> <> <EFBFBD> ö<EFBFBD> <C3B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD>
int GetInputSize ( )
{
COMSTAT Stat ;
DWORD dwError ;
return : : ClearCommError ( _hCommHandle , & dwError , & Stat ) = = TRUE ? Stat . cbInQue : ( DWORD ) - 1L ;
}
//----------------------------------Operations----------------------------------
//<2F> <EFBFBD> <F2BFAAB4> <EFBFBD> ȱʡ 9600, 8, n, 1
bool Open ( DWORD dwPort )
{
return Open ( dwPort , 9600 ) ;
}
//<2F> <EFBFBD> <F2BFAAB4> <EFBFBD> ȱʡ 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 ) ;
}
//<2F> <EFBFBD> <F2BFAAB4> <EFBFBD> , ʹ <> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> "9600, 8, n, 1"<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ô<EFBFBD> <C3B4> <EFBFBD>
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 ) ;
}
//<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> dwBufferLength<74> <68> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> Buffer <20> <> <EFBFBD> <EFBFBD> ʵ<EFBFBD> ʶ<EFBFBD> <CAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> <20> ɶ<EFBFBD> <C9B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
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 )
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
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 ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 첽I/O
if ( ! : : GetOverlappedResult ( _hCommHandle , & _ReadOverlapped , & uReadLength , false ) )
{
if ( : : GetLastError ( ) ! = ERROR_IO_INCOMPLETE )
uReadLength = 0 ;
}
}
else
uReadLength = 0 ;
}
return uReadLength ;
}
//<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> dwBufferLength - 1 <20> <> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> szBuffer <20> <> <EFBFBD> <EFBFBD> ANSI C ģʽ <C4A3> ַ<EFBFBD> <D6B7> <EFBFBD> ָ<EFBFBD> <D6B8> <20> ʺ<EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> ַ<EFBFBD> ͨѶ
char * ReadString ( char * szBuffer , DWORD dwBufferLength , DWORD dwWaitTime = 20 )
{
unsigned long uReadLength = Read ( szBuffer , dwBufferLength - 1 , dwWaitTime ) ;
szBuffer [ uReadLength ] = ' \0 ' ;
return szBuffer ;
}
//д<> <D0B4> <EFBFBD> <EFBFBD> <20> <> д<EFBFBD> <D0B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> "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 ;
}
//д<> <D0B4> <EFBFBD> <EFBFBD> дANSI C ģʽ <C4A3> ַ<EFBFBD> <D6B7> <EFBFBD> ָ<EFBFBD> <D6B8>
DWORD Write ( const char * szBuffer )
{
assert ( szBuffer ) ;
return Write ( ( void * ) szBuffer , strlen ( szBuffer ) ) ;
}
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ<> <CDAC> Ӧ<EFBFBD> <D3A6>
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 ;
}
//д<> <D0B4> <EFBFBD> <EFBFBD> ͬ<> <CDAC> Ӧ<EFBFBD> <D3A6>
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 ;
}
//д<> <D0B4> <EFBFBD> <EFBFBD> szBuffer <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
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 ) ;
}
//д<> <D0B4> <EFBFBD> <EFBFBD> szBuffer <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 黺<EFBFBD> <E9BBBA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <> <D0A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
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 ) ;
}
//<2F> رմ<D8B1> <D5B4> <EFBFBD> ͬʱҲ<CAB1> رչ<D8B1> <D5B9> <EFBFBD> <EFBFBD> ߳<EFBFBD>
virtual void Close ( )
{
if ( IsOpen ( ) )
{
PurgeComm ( _hCommHandle , PURGE_TXABORT | PURGE_TXCLEAR ) ;
EndThread ( ) ;
: : CloseHandle ( _hCommHandle ) ;
_hCommHandle = INVALID_HANDLE_VALUE ;
}
}
//DTR <20> <> ƽ <EFBFBD> <C6BD> <EFBFBD> <EFBFBD>
bool SetDTR ( bool OnOrOff )
{
return IsOpen ( ) ? EscapeCommFunction ( _hCommHandle , OnOrOff ? SETDTR : CLRDTR ) : false ;
}
//RTS <20> <> ƽ <EFBFBD> <C6BD> <EFBFBD> <EFBFBD>
bool SetRTS ( bool OnOrOff )
{
return IsOpen ( ) ? EscapeCommFunction ( _hCommHandle , OnOrOff ? SETRTS : CLRRTS ) : false ;
}
//
bool SetBreak ( bool OnOrOff )
{
return IsOpen ( ) ? EscapeCommFunction ( _hCommHandle , OnOrOff ? SETBREAK : CLRBREAK ) : false ;
}
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ߳̿<DFB3> <CCBF> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳<EFBFBD>
bool BeginThread ( )
{
if ( ! IsThreadRunning ( ) )
{
_fRunFlag = true ;
_hThreadHandle = NULL ;
DWORD id ;
_hThreadHandle = : : CreateThread ( NULL , 0 , CommThreadProc , this , 0 , & id ) ;
return ( _hThreadHandle ! = NULL ) ;
}
return false ;
}
//<2F> <> ͣ<EFBFBD> <CDA3> <EFBFBD> <EFBFBD> <EFBFBD> ߳<EFBFBD>
inline bool SuspendThread ( )
{
return IsThreadRunning ( ) ? : : SuspendThread ( _hThreadHandle ) ! = 0xFFFFFFFF : false ;
}
//<2F> ָ<EFBFBD> <D6B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳<EFBFBD>
inline bool ResumeThread ( )
{
return IsThreadRunning ( ) ? : : ResumeThread ( _hThreadHandle ) ! = 0xFFFFFFFF : false ;
}
//<2F> <> ֹ<EFBFBD> ߳<EFBFBD>
bool EndThread ( DWORD dwWaitTime = 100 )
{
if ( IsThreadRunning ( ) )
{
_fRunFlag = false ;
: : SetCommMask ( _hCommHandle , 0 ) ;
: : SetEvent ( _WaitOverlapped . hEvent ) ;
if ( : : WaitForSingleObject ( _hThreadHandle , dwWaitTime ) ! = WAIT_OBJECT_0 )
if ( ! : : TerminateThread ( _hThreadHandle , 0 ) )
return false ;
: : CloseHandle ( _hThreadHandle ) ;
: : ResetEvent ( _WaitOverlapped . hEvent ) ;
_hThreadHandle = NULL ;
return true ;
}
return false ;
}
protected :
volatile DWORD _dwPort ; //<2F> <> <EFBFBD> ں<EFBFBD>
volatile HANDLE _hCommHandle ; //<2F> <> <EFBFBD> ھ <EFBFBD> <DABE> <EFBFBD>
char _szCommStr [ 20 ] ; //<2F> <> <EFBFBD> <EFBFBD> COM1<4D> <31> <EFBFBD> Ƶ<EFBFBD> <C6B5> ַ<EFBFBD> <D6B7> <EFBFBD>
DCB _DCB ; //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ʣ<EFBFBD> ֹͣλ<D6B9> <CEBB> <EFBFBD> <EFBFBD>
COMMTIMEOUTS _CO ; //<2F> <> ʱ<EFBFBD> ṹ
DWORD _dwIOMode ; // 0 ͬ<> <CDAC> Ĭ<> <C4AC> FILE_FLAG_OVERLAPPED<45> ص<EFBFBD> I/O<> 첽
OVERLAPPED _ReadOverlapped , _WriteOverlapped ; // <20> ص<EFBFBD> I/O
volatile HANDLE _hThreadHandle ; //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ߳<EFBFBD>
volatile HWND _hNotifyWnd ; // ֪ͨ<CDA8> <D6AA> <EFBFBD> <EFBFBD>
volatile DWORD _dwNotifyNum ; //<2F> <> <EFBFBD> ܶ<EFBFBD> <DCB6> <EFBFBD> <EFBFBD> ֽ<EFBFBD> (>=_dwNotifyNum)<29> <> <EFBFBD> <EFBFBD> ֪ͨ<CDA8> <D6AA> Ϣ
volatile DWORD _dwMaskEvent ; //<2F> <> <EFBFBD> ӵ<EFBFBD> <D3B5> ¼<EFBFBD>
volatile bool _fRunFlag ; //<2F> ߳<EFBFBD> <DFB3> <EFBFBD> <EFBFBD> <EFBFBD> ѭ<EFBFBD> <D1AD> <EFBFBD> <EFBFBD> ־
bool _fAutoBeginThread ; //Open() <20> Զ<EFBFBD> BeginThread();
OVERLAPPED _WaitOverlapped ; //WaitCommEvent use
//<2F> <> ʼ <EFBFBD> <CABC>
void Init ( )
{
memset ( _szCommStr , 0 , 20 ) ;
memset ( & _DCB , 0 , sizeof ( _DCB ) ) ;
_DCB . DCBlength = sizeof ( _DCB ) ;
_hCommHandle = INVALID_HANDLE_VALUE ;
memset ( & _ReadOverlapped , 0 , sizeof ( _ReadOverlapped ) ) ;
memset ( & _WriteOverlapped , 0 , sizeof ( _WriteOverlapped ) ) ;
_ReadOverlapped . hEvent = : : CreateEvent ( NULL , true , false , NULL ) ;
assert ( _ReadOverlapped . hEvent ! = INVALID_HANDLE_VALUE ) ;
_WriteOverlapped . hEvent = : : CreateEvent ( NULL , true , false , NULL ) ;
assert ( _WriteOverlapped . hEvent ! = INVALID_HANDLE_VALUE ) ;
_hNotifyWnd = NULL ;
_dwNotifyNum = 0 ;
_dwMaskEvent = DEFAULT_COM_MASK_EVENT ;
_hThreadHandle = NULL ;
memset ( & _WaitOverlapped , 0 , sizeof ( _WaitOverlapped ) ) ;
_WaitOverlapped . hEvent = : : CreateEvent ( NULL , true , false , NULL ) ;
assert ( _WaitOverlapped . hEvent ! = INVALID_HANDLE_VALUE ) ;
}
//<2F> <> <EFBFBD> <EFBFBD>
void UnInit ( )
{
if ( _ReadOverlapped . hEvent ! = INVALID_HANDLE_VALUE )
CloseHandle ( _ReadOverlapped . hEvent ) ;
if ( _WriteOverlapped . hEvent ! = INVALID_HANDLE_VALUE )
CloseHandle ( _WriteOverlapped . hEvent ) ;
if ( _WaitOverlapped . hEvent ! = INVALID_HANDLE_VALUE )
CloseHandle ( _WaitOverlapped . hEvent ) ;
}
//<2F> <EFBFBD> <F3B6A8B4> <EFBFBD>
void BindCommPort ( DWORD dwPort )
{
assert ( dwPort > = 1 & & dwPort < = 1024 ) ;
char p [ 5 ] ;
_dwPort = dwPort ;
strcpy ( _szCommStr , " \\ \\ . \\ COM " ) ;
ltoa ( _dwPort , p , 10 ) ;
strcat ( _szCommStr , p ) ;
}
//<2F> <EFBFBD> <F2BFAAB4> <EFBFBD>
virtual bool OpenCommPort ( )
{
if ( IsOpen ( ) )
Close ( ) ;
_hCommHandle = : : CreateFile ( _szCommStr , GENERIC_READ | GENERIC_WRITE , 0 , NULL ,
OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL | _dwIOMode , NULL ) ;
if ( _fAutoBeginThread )
{
if ( IsOpen ( ) & & BeginThread ( ) )
return true ;
else
{
Close ( ) ; //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ߳<EFBFBD> ʧ<EFBFBD> <CAA7>
return false ;
}
}
return IsOpen ( ) ;
}
public :
//<2F> <> <EFBFBD> <EFBFBD> (<28> <> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> <EFBFBD>
virtual bool SetupPort ( )
{
if ( ! IsOpen ( ) )
return false ;
if ( ! : : SetupComm ( _hCommHandle , 4096 , 4096 ) )
return false ;
if ( ! : : GetCommTimeouts ( _hCommHandle , & _CO ) )
return false ;
_CO . ReadIntervalTimeout = 0 ;
_CO . ReadTotalTimeoutMultiplier = 1 ;
_CO . ReadTotalTimeoutConstant = 1000 ;
_CO . WriteTotalTimeoutMultiplier = 1 ;
_CO . WriteTotalTimeoutConstant = 1000 ;
if ( ! : : SetCommTimeouts ( _hCommHandle , & _CO ) )
return false ;
if ( ! : : PurgeComm ( _hCommHandle , PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) )
return false ;
return true ;
}
//---------------------------------------threads callback-----------------------------------
//<2F> ߳<EFBFBD> <DFB3> յ<EFBFBD> <D5B5> <EFBFBD> Ϣ<EFBFBD> Զ<EFBFBD> <D4B6> <EFBFBD> <EFBFBD> <EFBFBD> , <20> 細<EFBFBD> ھ <EFBFBD> <DABE> <EFBFBD> <EFBFBD> <EFBFBD> Ч, <20> ͳ<EFBFBD> <CDB3> <EFBFBD> Ϣ, <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڱ<EFBFBD> <DAB1> ţ<EFBFBD> <20> <> Ϊ<EFBFBD> 麯<EFBFBD> <E9BAAF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڻ<EFBFBD> <DABB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> չ
virtual void OnReceive ( ) //EV_RXCHAR
{
if ( : : IsWindow ( _hNotifyWnd ) )
: : PostMessage ( _hNotifyWnd , ON_COM_RECEIVE , WPARAM ( _dwPort ) , LPARAM ( 0 ) ) ;
}
virtual void OnDSR ( )
{
if ( : : IsWindow ( _hNotifyWnd ) )
{
DWORD Status ;
if ( GetCommModemStatus ( _hCommHandle , & Status ) )
: : PostMessage ( _hNotifyWnd , ON_COM_DSR , WPARAM ( _dwPort ) , LPARAM ( ( Status & MS_DSR_ON ) ? 1 : 0 ) ) ;
}
}
virtual void OnCTS ( )
{
if ( : : IsWindow ( _hNotifyWnd ) )
{
DWORD Status ;
if ( GetCommModemStatus ( _hCommHandle , & Status ) )
: : PostMessage ( _hNotifyWnd , ON_COM_CTS , WPARAM ( _dwPort ) , LPARAM ( ( Status & MS_CTS_ON ) ? 1 : 0 ) ) ;
}
}
virtual void OnBreak ( )
{
if ( : : IsWindow ( _hNotifyWnd ) )
{
: : PostMessage ( _hNotifyWnd , ON_COM_BREAK , WPARAM ( _dwPort ) , LPARAM ( 0 ) ) ;
}
}
virtual void OnTXEmpty ( )
{
if ( : : IsWindow ( _hNotifyWnd ) )
: : PostMessage ( _hNotifyWnd , ON_COM_TXEMPTY , WPARAM ( _dwPort ) , LPARAM ( 0 ) ) ;
}
virtual void OnError ( )
{
DWORD dwError ;
: : ClearCommError ( _hCommHandle , & dwError , NULL ) ;
if ( : : IsWindow ( _hNotifyWnd ) )
: : PostMessage ( _hNotifyWnd , ON_COM_ERROR , WPARAM ( _dwPort ) , LPARAM ( dwError ) ) ;
}
virtual void OnRing ( )
{
if ( : : IsWindow ( _hNotifyWnd ) )
: : PostMessage ( _hNotifyWnd , ON_COM_RING , WPARAM ( _dwPort ) , LPARAM ( 0 ) ) ;
}
virtual void OnRLSD ( )
{
if ( : : IsWindow ( _hNotifyWnd ) )
: : PostMessage ( _hNotifyWnd , ON_COM_RLSD , WPARAM ( _dwPort ) , LPARAM ( 0 ) ) ;
}
virtual DWORD ThreadFunc ( )
{
if ( ! : : SetCommMask ( _hCommHandle , _dwMaskEvent ) )
{
char szBuffer [ 256 ] ;
_snprintf ( szBuffer , 255 ,
" %s(%d) : COM%d Call WINAPI SetCommMask(%x, %x) Fail, thread work invalid! GetLastError() = %d; " , __FILE__ , __LINE__ , _dwPort , _hCommHandle , _dwMaskEvent , GetLastError ( ) ) ;
MessageBox ( NULL , szBuffer , " Class cnComm " , MB_OK ) ;
return 1 ;
}
COMSTAT Stat ;
DWORD dwError ;
for ( DWORD dwLength , dwMask = 0 ; _fRunFlag & & IsOpen ( ) ; dwMask = 0 )
{
if ( ! : : WaitCommEvent ( _hCommHandle , & dwMask , & _WaitOverlapped ) )
{
if ( : : GetLastError ( ) = = ERROR_IO_PENDING )
// asynchronous
: : GetOverlappedResult ( _hCommHandle , & _WaitOverlapped , & dwLength , TRUE ) ;
else
continue ;
}
if ( dwMask = = 0 )
continue ;
switch ( dwMask )
{
case EV_RXCHAR :
: : ClearCommError ( _hCommHandle , & dwError , & Stat ) ;
if ( Stat . cbInQue > = _dwNotifyNum )
OnReceive ( ) ;
break ;
case EV_TXEMPTY :
OnTXEmpty ( ) ;
break ;
case EV_CTS :
OnCTS ( ) ;
break ;
case EV_DSR :
OnDSR ( ) ;
break ;
case EV_RING :
OnRing ( ) ;
break ;
case EV_RLSD :
OnRLSD ( ) ;
break ;
case EV_BREAK :
OnBreak ( ) ;
break ;
case EV_ERR :
OnError ( ) ;
break ;
} //case
} //for
return 0 ;
}
private :
//the function protected
cnComm ( const cnComm & ) ;
cnComm & operator = ( const cnComm & ) ;
//base function for thread
static DWORD WINAPI CommThreadProc ( LPVOID lpPara )
{
return ( ( cnComm * ) lpPara ) - > ThreadFunc ( ) ;
}
} ;
# endif //_CN_COMM_H_