📄 comm.cpp
字号:
#include "comm.h"
//---------------------------------------------------------------------------
COMM::COMM(HWND hWnd)
{
CommPort=INVALID_HANDLE_VALUE;
strcpy(CommName,"");
Window=hWnd;
ThreadHandleRD=NULL;
ThreadHandleWR=NULL;
TimeOutRD=INFINITE;
TimeOutWR=INFINITE;
OverWR.Internal=0;
OverWR.InternalHigh=0;
OverWR.Offset=0;
OverWR.OffsetHigh=0;
OverWR.hEvent=CreateEvent(NULL, TRUE, TRUE, NULL);
OverRD.Internal=0;
OverRD.InternalHigh=0;
OverRD.Offset=0;
OverRD.OffsetHigh=0;
OverRD.hEvent=CreateEvent(NULL, TRUE, TRUE, NULL);
}
//---------------------------------------------------------------------------
COMM::~COMM()
{
Close();
CloseHandle(OverRD.hEvent);
CloseHandle(OverWR.hEvent);
}
//---------------------------------------------------------------------------
DWORD COMM::Open(char* PortName,UINT Baud,UINT DataBits,BYTE Parity,BYTE StopBits)
{
if((strncmp(PortName,"COM",3))&&(strncmp(PortName,"LPT",3))) return -1;
Close();
// if(strcmp(CommName,PortName)) if((CommPort!=INVALID_HANDLE_VALUE)/*&&(strcmp(CommName,PortName))*/)
CommPort=CreateFile(PortName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL, // Pointer to the security attribute
OPEN_EXISTING,// How to open the serial port
FILE_FLAG_OVERLAPPED, // Port attributes
NULL); // Handle to port with attribute
strcpy(CommName,PortName);
if(CommPort==INVALID_HANDLE_VALUE) return -1;
if(strncmp(PortName,"COM",3)==0)
{
if(!GetCommState((HANDLE)CommPort,&CommDCB)) return -1;
CommDCB.BaudRate=Baud;
CommDCB.ByteSize=DataBits;
CommDCB.StopBits=StopBits;
CommDCB.Parity=Parity;
CommDCB.fParity = TRUE;
if(!SetCommState((HANDLE)CommPort,&CommDCB)) return -1;
}
if(!GetCommTimeouts((HANDLE)CommPort,&CommTimeOut)) return -1;
CommTimeOut.ReadIntervalTimeout=0;
CommTimeOut.ReadTotalTimeoutMultiplier=MAXDWORD; //0
CommTimeOut.ReadTotalTimeoutConstant=MAXDWORD; //300
CommTimeOut.WriteTotalTimeoutMultiplier=MAXDWORD; //0
CommTimeOut.WriteTotalTimeoutConstant=MAXDWORD; //300
if(!SetCommTimeouts((HANDLE)CommPort,&CommTimeOut)) return -1;
SetEvent(OverWR.hEvent);
SetEvent(OverRD.hEvent);
return 0;
}
//---------------------------------------------------------------------------
DWORD COMM::CommThreadRD(PVOID Handle)
{
COMM* Comm=(COMM*)Handle;
DWORD Count=0;
ReadFile(Comm->CommPort,Comm->DataBufRD,Comm->LengthRD,&Count,&Comm->OverRD);
if(WaitForSingleObject(Comm->OverRD.hEvent,Comm->TimeOutRD)==WAIT_OBJECT_0)
{
if(!GetOverlappedResult(Comm->CommPort,&Comm->OverRD,&Count,FALSE))
{
PostMessage(Comm->Window,WM_COMM_RD_ERROR,0,0);
SetEvent(Comm->OverRD.hEvent);
ExitThread(0);
}
}
else
{
PostMessage(Comm->Window,WM_COMM_RD_ERROR,0,0);
SetEvent(Comm->OverRD.hEvent);
ExitThread(0);
}
PostMessage(Comm->Window,WM_COMM_RD_OK,Count,0);
ExitThread(0);
return 0;
}
//---------------------------------------------------------------------------
DWORD COMM::CommThreadWR(PVOID Handle)
{
COMM* Comm=(COMM*)Handle;
DWORD Count=0;
WriteFile(Comm->CommPort,Comm->DataBufWR,Comm->LengthWR,&Count,&Comm->OverWR);
if(WaitForSingleObject(Comm->OverWR.hEvent,Comm->TimeOutWR)!=WAIT_OBJECT_0)
{
PostMessage(Comm->Window,WM_COMM_WR_ERROR,Count,0);
SetEvent(Comm->OverWR.hEvent);
ExitThread(0);
}
if(!GetOverlappedResult(Comm->CommPort,&Comm->OverWR,&Count,FALSE))
{
PostMessage(Comm->Window,WM_COMM_WR_ERROR,Count,0);
SetEvent(Comm->OverWR.hEvent);
ExitThread(0);
}
PostMessage(Comm->Window,WM_COMM_WR_OK,Count,0);
return 0;
}
//---------------------------------------------------------------------------
void COMM::Close()
{
DWORD exid;
SetEvent(OverWR.hEvent);
SetEvent(OverRD.hEvent);
do{GetExitCodeThread(ThreadHandleRD,&exid);
}while((exid==STILL_ACTIVE)&&(ThreadHandleRD!=NULL));
do{GetExitCodeThread(ThreadHandleWR,&exid);
}while((exid==STILL_ACTIVE)&&(ThreadHandleWR!=NULL));
if(ThreadHandleRD!=NULL) {CloseHandle(ThreadHandleRD);ThreadHandleRD=NULL;}
if(ThreadHandleWR!=NULL) {CloseHandle(ThreadHandleWR);ThreadHandleWR=NULL;}
if(CommPort!=INVALID_HANDLE_VALUE) CloseHandle(CommPort);
CommPort=INVALID_HANDLE_VALUE;
ResetEvent(OverWR.hEvent);
ResetEvent(OverRD.hEvent);
}
//---------------------------------------------------------------------------
void COMM::SetWindow(HANDLE hWnd)
{
Window=hWnd;
}
//---------------------------------------------------------------------------
DWORD COMM::Read(char* DataBuf,UINT Length,bool Synchro)
{
if(CommPort==INVALID_HANDLE_VALUE) return -1;
if(WaitForSingleObject(OverRD.hEvent,1)!=WAIT_OBJECT_0) return -1;
if(ThreadHandleRD!=NULL) {CloseHandle(ThreadHandleRD);ThreadHandleRD=NULL;}
if(!ResetEvent(OverRD.hEvent)) return -1;
if(Synchro)
{
DWORD Count=0;
ReadFile(CommPort,DataBuf,Length,&Count,&OverRD);
if(WaitForSingleObject(OverRD.hEvent,TimeOutRD)!=WAIT_OBJECT_0) return -1;
if(!GetOverlappedResult(CommPort,&OverRD,&Count,FALSE)) return -1;
return Count;
}
else
{
DWORD ComThreadID;
DataBufRD=DataBuf;LengthRD=Length;
ThreadHandleRD=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CommThreadRD,this,0,&ComThreadID);
if(ThreadHandleRD==NULL) return -1;
}
return 0;
}
//---------------------------------------------------------------------------
DWORD COMM::Write(char* DataBuf,UINT Length,bool Synchro)
{
if(CommPort==INVALID_HANDLE_VALUE) return -1;
if(WaitForSingleObject(OverWR.hEvent,1)!=WAIT_OBJECT_0) return -1;
if(ThreadHandleWR!=NULL) {CloseHandle(ThreadHandleWR);ThreadHandleWR=NULL;}
if(!ResetEvent(OverWR.hEvent)) return -1;
if(Synchro)
{
DWORD Count=0;
WriteFile(CommPort,DataBuf,Length,&Count,&OverWR);
if(WaitForSingleObject(OverWR.hEvent,TimeOutWR)!=WAIT_OBJECT_0) return -1;
if(!GetOverlappedResult(CommPort,&OverWR,&Count,FALSE)) return-1;
return Count;
}
else
{
DWORD ComThreadID;
DataBufWR=DataBuf;LengthWR=Length;
ThreadHandleWR=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CommThreadWR,this,0,&ComThreadID);
if(ThreadHandleWR==NULL) return -1;
}
return 0;
}
//---------------------------------------------------------------------------
DWORD COMM::GetModemState()
{
if((CommPort==INVALID_HANDLE_VALUE)||(strncmp(CommName,"COM",3))) return -1;
if(!GetCommModemStatus(CommPort,&ModemState)) return -1;
return ModemState;
}
//---------------------------------------------------------------------------
void COMM::TerminateRD()
{
if(ThreadHandleRD!=NULL)
{
SetEvent(OverRD.hEvent);
CloseHandle(ThreadHandleRD);
ThreadHandleRD=NULL;
}
}
//---------------------------------------------------------------------------
void COMM::TerminateWR()
{
if(ThreadHandleWR!=NULL)
{
SetEvent(OverWR.hEvent);
CloseHandle(ThreadHandleWR);
ThreadHandleWR=NULL;
}
}
//---------------------------------------------------------------------------
DWORD COMM::SetTimeOut(DWORD RD,DWORD WR)
{
TimeOutRD=RD;
TimeOutWR=WR;
return 0;
}
//---------------------------------------------------------------------------
DWORD COMM::ShowLastError()
{
DWORD Error=GetLastError();
if(!Error) return 0;
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
Error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
MessageBox(Window,(char *)lpMsgBuf ,"Application Error", MB_ICONSTOP);
LocalFree(lpMsgBuf);
return Error;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -