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

📄 serialport.cpp

📁 使用短信猫可以实现短信的群发
💻 CPP
字号:
// SerialPort.cpp: implementation of the CSerialPort class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "sms.h"
#include "SerialPort.h"

#include <Winreg.h> //RegEnumValue所在头文件
#include <atlbase.h> //CRegKey所在头文件


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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSerialPort::CSerialPort()
{
	hCom=NULL;
}

CSerialPort::~CSerialPort()
{
	CloseHandle(hCom);
	hCom=NULL;
}

//////////////////////////////////////////////////////////////////////////
//取得系统上的所有COM口
void CSerialPort::GetCOMList(vector<CString> & PortList)
{
	CRegKey RegKey;   
    int nCount = 0;   
	//CString * pNameList=new CString[5];
	//CString * pPortList=new CString[5];
    if(RegKey.Open(HKEY_LOCAL_MACHINE, "Hardware\\DeviceMap\\SerialComm") == ERROR_SUCCESS)   
    {   
        while(true)   
        {   
            char ValueName[_MAX_PATH];   
            unsigned char ValueData[_MAX_PATH];   
            DWORD nValueSize = _MAX_PATH;   
            DWORD nDataSize = _MAX_PATH;   
            DWORD nType;   
			
			//RegEnumValue函数的作用是,从被指定打开的注册表项中列举所有的值
			//这函数每调用一次就会拷贝一个索引值的名称和数据块
            if(::RegEnumValue(HKEY(RegKey), nCount, ValueName, &nValueSize, NULL, &nType, ValueData, &nDataSize) == ERROR_NO_MORE_ITEMS)   
            {   
                break;   
            }   
			
//              if(pNameList)   
//                  pNameList[nCount] = ValueName;   
// 			
//             if(pPortList)  
//                 pPortList[nCount] = ValueData;   
			CString temp=ValueData;
			PortList.push_back(temp);
			TRACE(PortList[nCount]+"\n");
            nCount++;   
        }
	}
}

BOOL CSerialPort::OpenCOMPort(CString sPort,int nBaudRate,int nByteSize,int nParity,int nStopBit)
{
	BOOL result=FALSE;
	//打开文件
	hCom=CreateFile((LPCSTR)(LPCTSTR(sPort)), //指定要找开或创建的文件 这里指定串口名或设置的路径
		GENERIC_READ|GENERIC_WRITE,		//提供读写方式
		0,								//这里设置共享方式,这里采用独占方式
		NULL,							//设置安全属性,我们采用默认的设置
		OPEN_EXISTING,					//指定打开一个已存在的文件,由于COM口在系统中被认为是一个以存在的文件 打开而不是创建
		NULL ,
		NULL );							//不需要参照模板文件
	
	if(INVALID_HANDLE_VALUE==hCom)			//如果打开COM口文件失改,将会返回INVALID_HANDLE_VALUE这个错误
	{
		TRACE("打开COM失败!");
		return FALSE;
	}
	
	//////////////////////////////////////////////////////////////////////////
	//清空异步读写参数
	memset(&m_OverlappedRead,0,sizeof(OVERLAPPED));
	memset(&m_OverlappedWrite,0,sizeof(OVERLAPPED));
	
	
	//////////////////////////////////////////////////////////////////////////
	//读取通信状态,并对特定属性进行修改
	DCB dcb;
	
	//通过GetCommState函数可获取指定通信端口的状态
	GetCommState(hCom,&dcb);   //取得打开COM口的状态
	dcb.BaudRate=nBaudRate;   //波特率
	dcb.ByteSize=nByteSize;  //字节大小
	dcb.Parity=nParity;     //奇偶校验
	dcb.StopBits=nStopBit; //停止位
	
	//通过dcb结构体来重置一下通信状态
	//SetCommState(hCom,&dcb);
	
	//////////////////////////////////////////////////////////////////////////
	//设置通信超时
	
	//设置通信超时信息结构体
	COMMTIMEOUTS commTimeouts;
	commTimeouts.ReadIntervalTimeout=100; // 读字符间隔超时时间: 100 ms
	commTimeouts.ReadTotalTimeoutConstant=500 ; // 基本的(额外的)读超时时间: 500 ms
	commTimeouts.ReadTotalTimeoutMultiplier=1; // 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
	commTimeouts.WriteTotalTimeoutConstant=100; // 基本的(额外的)写超时时间: 100 ms
	commTimeouts.WriteTotalTimeoutMultiplier=1;// 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
	
	//将超时信信息结构体的内容设置到指定的通信设备上去
	SetCommTimeouts(hCom,&commTimeouts);
	
	
	//////////////////////////////////////////////////////////////////////////
	//初始化通信设备的缓冲区
	
	//SetupComm函数来初始化一个指定通信设备的通信参数 通过句柄来指明要修改参数的设备
	//SetupComm(hCom/*设备的句柄*/ ,4096 /*输入缓冲区大小*/,1024 /*输出缓冲区大小*/);	
	
	if( !SetCommState(hCom,&dcb) || //通过dcb结构体来重置一下通信状态
		
		!SetupComm(hCom/*设备的句柄*/ ,4096 /*输入缓冲区大小*/,1024 /*输出缓冲区大小*/)	)
	{
		CloseHandle(hCom);
		hCom=NULL;
		return FALSE;
	}
	//删除指定通信资源的输入和输出缓冲区中的所有字符
	PurgeComm(hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
	
	
	TRACE("连接串口成功");
	return TRUE;
}

BOOL CSerialPort::CloseSerialPort()
{
	if (hCom != NULL)
	{
		PurgeComm(hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
		CloseHandle(hCom);
		hCom = NULL;
	}
	return true;
}
BOOL CSerialPort::IsOpen()
{
	return hCom != INVALID_HANDLE_VALUE;
	//return	hCom!=NULL;
}
int CSerialPort::ReadCom(LPVOID buffer, DWORD bufferLength)
{
	//判断是否连接
	if(hCom == NULL)
	{
		TRACE("串口以关闭\n");
		return (DWORD)0;
	}

	DWORD dwError;
	COMSTAT comStat;
	DWORD readLength=0;
	if(!ClearCommError(hCom,&dwError,&comStat))
	{
		return FALSE;
	}
	//在该读取中使用了同步方式,因些要传递readLength以返回引响的字节数
	//对于异步方式要指定重叠结构,可不指定已读取节数  将读取操作跟m_OverlappedRead结构体中的hEvent事件关连起来
	if(!::ReadFile(hCom,buffer,bufferLength,&readLength,NULL))
	{
		TRACE("读串口出错\n");
		return FALSE;
	}
	return readLength;
}

DWORD CSerialPort::WriteCom(LPVOID buffer, DWORD bufferLength)
{
	//判断是否连接
	if(hCom == NULL)
	{
		TRACE("串口以关闭\n");
		return (DWORD)0;
	}

	
	DWORD writeLength;
	DWORD dwError;
	COMSTAT comStat;
	if(!ClearCommError(hCom,&dwError,&comStat))
		return FALSE;
	//对于同步来说要定读这次读取的字节数,即第三个参数
	//对于异步方式要指定重叠结构,可不指定已写入字节数  将写入操作跟m_OverlappedWrite结构体中的hEvent事件关连起来
	if(!WriteFile(hCom,buffer,bufferLength,&writeLength,&m_OverlappedWrite))
	{
		TRACE("写入串口出错");
		return FALSE;
	}
	return writeLength;
}

⌨️ 快捷键说明

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