📄 20000804014.htm
字号:
else <br>
ProcessErrorMessage("GetCommState()"); <br>
} <br>
else <br>
ProcessErrorMessage("SetCommMask()"); <br>
} <br>
else <br>
ProcessErrorMessage("SetCommTimeouts()"); <br>
<br>
delete [] szPort; <br>
delete [] szBaud; <br>
<br>
// flush the port <br>
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PU
<br>
RGE_TXABORT); <br>
<br>
// release critical section <br>
LeaveCriticalSection(&m_csCommunicationSync); <br>
<br>
return true; <br>
} <br>
<br>
// <br>
// The CommThread Function. <br>
// <br>
DWORD _stdcall TSerialPort::CommThread(LPVOID pParam) <br>
{ <br>
// Cast the void pointer passed to the thread back to <br>
// a pointer of TSerialPort class <br>
TSerialPort *port = (TSerialPort*)pParam; <br>
<br>
// Set the status variable in the dialog class to <br>
// TRUE to indicate the thread is running. <br>
port->m_bThreadAlive = true; <br>
<br>
// Misc. variables <br>
DWORD BytesTransfered = 0; <br>
DWORD Event = 0; <br>
DWORD CommEvent = 0; <br>
DWORD dwError = 0; <br>
COMSTAT comstat; <br>
BOOL bResult = true; <br>
<br>
// Clear comm buffers at startup <br>
if (port->m_hComm) // check if the port is opened <br>
PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_R
<br>
ABO <br>
RT | PURGE_TXABORT); <br>
<br>
// begin forever loop. This loop will run as long as the thread is a
<br>
live. <br>
for (;;) <br>
{ <br>
<br>
// Make a call to WaitCommEvent(). This call will return immedi <br>
tly <br>
<br>
// because our port was created as an async port (FILE_FLAG_OVER <br>
APP <br>
ED <br>
// and an m_OverlappedStructerlapped structure specified). This <br>
cal <br>
l will cause the <br>
// m_OverlappedStructerlapped element m_OverlappedStruct.hEvent, <br>
whi <br>
ch is part of the m_hEventArray to <br>
// be placed in a non-signeled state if there are no bytes avail <br>
ble <br>
to be read, <br>
// or to a signeled state if there are bytes available. If this <br>
eve <br>
nt handle <br>
// is set to the non-signeled state, it will be set to signeled <br>
hen <br>
a <br>
// character arrives at the port. <br>
<br>
// we do this for each port! <br>
<br>
bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);
<br>
<br>
if (!bResult) <br>
{ <br>
// If WaitCommEvent() returns FALSE, process the last er <br>
or to dete <br>
rmin <br>
rmin <br>
// the reason.. <br>
switch (dwError = GetLastError()) <br>
{ <br>
case ERROR_IO_PENDING: <br>
{ <br>
// This is a normal return value if ther <br>
are no bytes <br>
// to read at the port. <br>
// Do nothing and continue <br>
break; <br>
} <br>
case 87: <br>
{ <br>
// Under Windows NT, this value is retur <br>
ed for some reason. <br>
// I have not investigated why, but it i <br>
also a valid reply <br>
// Also do nothing and continue. <br>
break; <br>
} <br>
default: <br>
{ <br>
// All other error codes indicate a seri <br>
us error has <br>
// occured. Process this error. <br>
port->ProcessErrorMessage("WaitCommEvent <br>
)"); <br>
break; <br>
} <br>
} <br>
} <br>
else <br>
{ <br>
// If WaitCommEvent() returns TRUE, check to be sure the <br>
e are <br>
// actually bytes in the buffer to read. <br>
// <br>
// If you are reading more than one byte at a time from <br>
he buffer <br>
<br>
// (which this program does not do) you will have the si <br>
uation occ <br>
ur <br>
// where the first byte to arrive will cause the WaitFor <br>
ultipleObj <br>
ects() <br>
// function to stop waiting. The WaitForMultipleObjects <br>
) function <br>
<br>
// resets the event handle in m_OverlappedStruct.hEvent <br>
o the non- <br>
signelead state <br>
// as it returns. <br>
// <br>
// If in the time between the reset of this event and th <br>
call to <br>
// ReadFile() more bytes arrive, the m_OverlappedStruct. <br>
Event hand <br>
le will be set again <br>
// to the signeled state. When the call to ReadFile() oc <br>
urs, it wi <br>
ll <br>
// read all of the bytes from the buffer, and the progra <br>
will <br>
// loop back around to WaitCommEvent(). <br>
// <br>
// At this point you will be in the situation where m_Ov <br>
rlappedStr <br>
uct.hEvent is set, <br>
// but there are no bytes available to read. If you pro <br>
eed and ca <br>
ll <br>
// ReadFile(), it will return immediatly due to the asyn <br>
port setu <br>
p, but <br>
// GetOverlappedResults() will not return until the next <br>
character <br>
arrives. <br>
// <br>
// It is not desirable for the GetOverlappedResults() fu <br>
ction to b <br>
e in <br>
// this state. The thread shutdown event (event 0) and <br>
he WriteFi <br>
le() <br>
// event (Event2) will not work if the thread is blocked <br>
by GetOver <br>
lappedResults(). <br>
// <br>
// The solution to this is to check the buffer with a ca <br>
l to Clear <br>
CommError(). <br>
// This call will reset the event handle, and if there a <br>
e no bytes <br>
to read <br>
// we can loop back through WaitCommEvent() again, then <br>
roceed. <br>
// If there are really bytes to read, do nothing and pro <br>
eed. <br>
<br>
bResult = ClearCommError(port->m_hComm, &dwError, &comst
<br>
t); <br>
<br>
if (comstat.cbInQue == 0) <br>
continue; <br>
} // end if bResult <br>
<br>
// Main wait function. This function will normally block the th <br>
ead <br>
<br>
<br>
// until one of nine events occur that require action. <br>
Event = WaitForMultipleObjects(3, port->m_hEventArray, false, IN
<br>
INI <br>
TE); <br>
<br>
switch (Event) <br>
{ <br>
case 0: <br>
{ <br>
// Shutdown event. This is event zero so it wil <br>
be <br>
// the higest priority and be serviced first. <br>
<br>
port->m_bThreadAlive = false; <br>
<br>
// Kill this thread. break is not needed, but m <br>
kes me feel bette <br>
r. <br>
ExitThread(100); <br>
break; <br>
} <br>
case 1: // read event <br>
{ <br>
GetCommMask(port->m_hComm, &CommEvent); <br>
if (CommEvent & EV_CTS) <br>
::SendMessage(port->m_pOwner->Handle, WM <br>
COMM_CTS_DETECTED, (WPAR <br>
AM) 0, (LPARAM) port->m_nPortNr); <br>
if (CommEvent & EV_RXFLAG) <br>
::SendMessage(port->m_pOwner->Handle, WM <br>
COMM_RXFLAG_DETECTED, (W <br>
PARAM) 0, (LPARAM) port->m_nPortNr); <br>
if (CommEvent & EV_BREAK) <br>
::SendMessage(port->m_pOwner->Handle, WM <br>
COMM_BREAK_DETECTED, (WP <br>
ARAM) 0, (LPARAM) port->m_nPortNr); <br>
if (CommEvent & EV_ERR) <br>
::SendMessage(port->m_pOwner->Handle, WM <br>
COMM_ERR_DETECTED, (WPAR <br>
AM) 0, (LPARAM) port->m_nPortNr); <br>
if (CommEvent & EV_RING) <br>
::SendMessage(port->m_pOwner->Handle, WM <br>
COMM_RING_DETECTED, (WPA <br>
RAM) 0, (LPARAM) port->m_nPortNr); <br>
<br>
if (CommEvent & EV_RXCHAR) <br>
// Receive character event from port. <br>
ReceiveChar(port, comstat); <br>
<br>
break; <br>
} <br>
case 2: // write event <br>
{ <br>
// Write character event from port <br>
WriteChar(port); <br>
break; <br>
} <br>
<br>
} // end switch <br>
<br>
} // close forever loop <br>
<br>
return 0; <br>
} <br>
<br>
// <br>
// <br>
// start comm watching <br>
// <br>
BOOL TSerialPort::StartMonitoring() <br>
{ <br>
DWORD lpThreadId; <br>
m_HThread =CreateThread(NULL, <br>
0, <br>
CommThread, <br>
this, <br>
0, <br>
&lpThreadId); <br>
if(m_HThread==NULL) <br>
{ <br>
ProcessErrorMessage("Create Thread Error"); <br>
return false; <br>
} <br>
return true; <br>
} <br>
<br>
// <br>
// Restart the comm thread <br>
// <br>
// <br>
BOOL TSerialPort::RestartMonitoring() <br>
{ <br>
ResumeThread(m_HThread); <br>
return true; <br>
} <br>
<br>
// <br>
// Suspend the comm thread <br>
// <br>
BOOL TSerialPort::StopMonitoring() <br>
{ <br>
SuspendThread(m_HThread); <br>
return true; <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -