⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialcomm.cpp

📁 使用WINDOWS API接口
💻 CPP
字号:
// SerialComm.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "SerialComm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define EV_EXIT   0X0000

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

/////////////////////////////////////////////////////////////////////////////
// CSerialCommApp

BEGIN_MESSAGE_MAP(CSerialCommApp, CWinApp)
	//{{AFX_MSG_MAP(CSerialCommApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSerialCommApp construction

CSerialCommApp::CSerialCommApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CSerialCommApp object

CSerialCommApp theApp;

struct  THREADPAR
{
	HANDLE       idComDev;
	CWinThread   *pMainWnd;
}ThreadParameter;

HANDLE _declspec(dllexport) OpenComm( char ComStr[], UINT cbInQueue, UINT cbOutQueue )
{
    HANDLE   hCommDev;
	DCB      dcb;
	char     ComPath[8]="\\\\.\\";
	char     TempCom[8]="COM1";
	char     COMM[12]="COM1";
	char     TemStr[8]="";
	char     *p1,*p2;
    BYTE     DCB_Parity,DCB_Stop;
	char     ErrorMessage[32]="";

	p1=ComStr;
	p2=strstr(ComStr,":");
	strncpy(TempCom,ComStr,p2-p1);
	TempCom[p2-p1]='\0';
   	strupr(TempCom);
	sprintf(COMM,"%s%s",ComPath,TempCom);
	hCommDev=CreateFile( COMM, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
	if(hCommDev==(HANDLE)-1)
	{
 	    sprintf( ErrorMessage, "创建%s失败!", COMM );
		AfxMessageBox(ErrorMessage);
		return (HANDLE)-1;
	}

	dcb.DCBlength = sizeof( DCB );
	GetCommState( hCommDev, &dcb );

	p1=p2+1;
	p2=strstr(p1,",");
	strncpy(TemStr,p1,p2-p1);
	TemStr[p2-p1]='\0';
	dcb.BaudRate = atoi(TemStr);

	p1=p2+1;
	p2=strstr(p1,",");
	switch(*p1)
	{
	case 'N':
	case 'n':
		DCB_Parity=0;
		break;
	case 'O':
	case 'o':
		DCB_Parity=1;
		break;
	case 'E':
	case 'e':
		DCB_Parity=2;
		break;
	case 'M':
	case 'm':
		DCB_Parity=3;
		break;
	case 'S':
	case 's':
		DCB_Parity=4;
		break;
	default:
		DCB_Parity=0;
	}
 	dcb.Parity = DCB_Parity;

	p1=p2+1;
	p2=strstr(p1,",");
	strncpy(TemStr,p1,p2-p1);
	TemStr[p2-p1]='\0';
	dcb.ByteSize = atoi(TemStr);

	p1=p2+1;
	switch(*p1)
	{
	case 1:
		DCB_Stop=0;
		break;
	case 2:
		DCB_Stop=2;
		break;
	default:
		DCB_Stop=0;
	}
	dcb.StopBits = DCB_Stop;

    SetCommState( hCommDev, &dcb );
	SetupComm( hCommDev, cbInQueue, cbOutQueue );

	COMMTIMEOUTS CommTimeOuts;
	CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
	CommTimeOuts.ReadTotalTimeoutConstant = 0;
	CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
	CommTimeOuts.WriteTotalTimeoutConstant = 5000;
	SetCommTimeouts( hCommDev, &CommTimeOuts );

	PurgeComm(hCommDev,PURGE_TXCLEAR); //清发送缓冲区
	PurgeComm(hCommDev,PURGE_RXCLEAR); //清接收缓冲区

	return hCommDev;
}

void _declspec(dllexport) CloseComm(HANDLE IdCommDev)
{
    CloseHandle(IdCommDev);
}

int _declspec(dllexport) WriteComm(HANDLE idComDev,void FAR* lpvBuf,DWORD cbWrite)
{
	BOOL bWriteStat;
    OVERLAPPED  write_os;

	memset(&write_os,0,sizeof(OVERLAPPED));
	write_os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	bWriteStat = WriteFile( idComDev, (LPSTR)lpvBuf, cbWrite, &cbWrite, &write_os );
	if( !bWriteStat )
	{
		if( WaitForSingleObject( write_os.hEvent, INFINITE ) ) 
		{
			cbWrite = 0;
		}
		else
		{
			GetOverlappedResult( idComDev, &write_os, &cbWrite, FALSE );
			write_os.Offset += cbWrite;
		}
	}
	CloseHandle(write_os.hEvent);

	return cbWrite;
}

int _declspec(dllexport) WriteCommByte( HANDLE idComDev, char ucByte )
{
	BOOL bWriteStat;
	DWORD dwBytesWritten;
    OVERLAPPED  write_os;

	memset(&write_os,0,sizeof(OVERLAPPED));
	write_os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	bWriteStat = WriteFile( idComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &write_os );
	if( !bWriteStat )
	{
		if( WaitForSingleObject( write_os.hEvent, INFINITE ) ) 
		{
			dwBytesWritten = 0;
		}
		else
		{
			GetOverlappedResult( idComDev, &write_os, &dwBytesWritten, FALSE );
			write_os.Offset += dwBytesWritten;
		}
	}
	CloseHandle(write_os.hEvent);

	return( TRUE );
}

int _declspec(dllexport) ReadComm(HANDLE idComDev, void FAR* lpvBuf, DWORD cbRead)
{
	DWORD      dwErrorFlag;
	COMSTAT    comStat;
	OVERLAPPED  read_os;

	memset(&read_os,0,sizeof(OVERLAPPED));
	read_os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	ClearCommError(idComDev,&dwErrorFlag,&comStat);
	cbRead=comStat.cbInQue;
	if(cbRead>0)
	{
		BOOL bReturn=ReadFile(idComDev,lpvBuf,cbRead,&cbRead,&read_os);
		if(!bReturn)//错误
		{
			if( GetLastError() == ERROR_IO_PENDING )
			{
				WaitForSingleObject( read_os.hEvent, INFINITE );
				return( (int) cbRead );
			}
			return( 0 );
		}
	}
	CloseHandle(read_os.hEvent);

	return cbRead;
}

void _declspec(dllexport) SendDTR(HANDLE idComDev)
{
    EscapeCommFunction(idComDev,SETDTR);     
}

void _declspec(dllexport) ClearDTR(HANDLE idComDev)
{
    EscapeCommFunction(idComDev,CLRDTR);     
}

void _declspec(dllexport) SendRTS(HANDLE idComDev)
{
    EscapeCommFunction(idComDev,SETRTS);     
}

void _declspec(dllexport) ClearRTS(HANDLE idComDev)
{
    EscapeCommFunction(idComDev,CLRRTS);     
}

void _declspec(dllexport) SendBreak(HANDLE idComDev)
{
    EscapeCommFunction(idComDev,SETBREAK);
	//SetCommBreak(idComDev);
}

void _declspec(dllexport) ClearBreak(HANDLE idComDev)
{
    EscapeCommFunction(idComDev,CLRBREAK);
	//ClearCommBreak(idComDev);
}

int CommWatch( THREADPAR *pParameter )
{
	DWORD       dwEvtMask;
	HANDLE      idComDev;
	CWinThread  *pMainWnd;

    idComDev=pParameter->idComDev;
	pMainWnd=pParameter->pMainWnd;

	if( !SetCommMask(idComDev,EV_RXCHAR|EV_DSR|EV_CTS|EV_BREAK))
		return FALSE;
	while(TRUE)
	{
		dwEvtMask=0;
		WaitCommEvent(idComDev,&dwEvtMask,NULL);
		if((dwEvtMask&EV_RXCHAR)==EV_RXCHAR)
		{
			pMainWnd->PostThreadMessage(WM_COMMRECVNOTIFY,(WPARAM)idComDev,NULL);
		}
		else if((dwEvtMask&EV_DSR)==EV_DSR)
		{
			pMainWnd->PostThreadMessage(WM_COMMDTRNOTIFY,(WPARAM)idComDev,NULL);
		}
		else if((dwEvtMask&EV_CTS)==EV_CTS)
		{
			pMainWnd->PostThreadMessage(WM_COMMRTSNOTIFY,(WPARAM)idComDev,NULL);
		}
		else if((dwEvtMask&EV_BREAK)==EV_BREAK)
		{
			pMainWnd->PostThreadMessage(WM_COMMBREAKNOTIFY,(WPARAM)idComDev,NULL);
		}
		else
		{
			//Exit Thread
			GetCommMask(idComDev,&dwEvtMask);
			if(dwEvtMask==EV_EXIT)
			{
#ifdef  DLLDEBUG
				AfxMessageBox("COM监控线程退出!");
#endif
				break;
			}
			//end
		}
	}

    return TRUE;
}

HANDLE _declspec(dllexport) CreateWatchComm(HANDLE idComDev,CWinThread *pMainWnd)
{
    DWORD             dwThreadID;
	HANDLE            hTherad;

	ThreadParameter.idComDev=idComDev;
	ThreadParameter.pMainWnd=pMainWnd;

	hTherad=CreateThread(
		(LPSECURITY_ATTRIBUTES)NULL,
		0,
		(LPTHREAD_START_ROUTINE)CommWatch,
		&ThreadParameter,
		0,
		&dwThreadID);
    return hTherad;
}

int _declspec(dllexport) DeleteWatchComm(HANDLE idComDev)
{
    SetCommMask(idComDev,EV_EXIT);
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -