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

📄 comtooldlg.cpp

📁 一个串口通信小工具
💻 CPP
字号:
// ComToolDlg.cpp : 僀儞僾儕儊儞僥乕僔儑儞 僼傽僀儖
//

#include "stdafx.h"
#include "ComTool.h"
#include "ComToolDlg.h"

#include <Winspool.h>

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

static DWORD g_arrBaudRate[] = { CBR_2400, CBR_4800, CBR_9600,
								 CBR_14400, CBR_19200, CBR_38400,
								 CBR_56000, CBR_57600};
static BYTE g_arrParity[] = { NOPARITY, ODDPARITY, EVENPARITY,
							  MARKPARITY, SPACEPARITY};
static BYTE g_arrStopBits[] = { ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS};
static BYTE g_arrByteSize[] = {  5, 6, 7, 8};
static BYTE g_arrFlowCtrl[] = {  RTS_CONTROL_DISABLE, RTS_CONTROL_HANDSHAKE};
static BOOL g_arrOutxCts[] = {  FALSE, TRUE};

static int g_iColIndex = 0;
/////////////////////////////////////////////////////////////////////////////
// 傾僾儕働乕僔儑儞偺僶乕僕儑儞忣曬偱巊傢傟偰偄傞 CAboutDlg 僟僀傾儘僌

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// 僟僀傾儘僌 僨乕僞
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard 偼壖憐娭悢偺僆乕僶乕儔僀僪傪惗惉偟傑偡
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 偺僒億乕僩
	//}}AFX_VIRTUAL

// 僀儞僾儕儊儞僥乕僔儑儞
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// 儊僢僙乕僕 僴儞僪儔偑偁傝傑偣傫丅
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CComToolDlg 僟僀傾儘僌

CComToolDlg::CComToolDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CComToolDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CComToolDlg)
	m_iBaudrate = -1;
	m_iBytesize = -1;
	m_iParity = -1;
	m_iStopbits = -1;
	m_iComport = -1;
	m_iDisptype = -1;
	m_iDatatype = -1;
	m_iFlowctrl = -1;
	//}}AFX_DATA_INIT
	// 儊儌: LoadIcon 偼 Win32 偺 DestroyIcon 偺僒僽僔乕働儞僗傪梫媮偟傑偣傫丅
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	m_hPort = INVALID_HANDLE_VALUE;
}

CComToolDlg::~CComToolDlg( )
{
	if( INVALID_HANDLE_VALUE != m_hPort)
	{
		CloseHandle( m_hPort);
		m_hPort = INVALID_HANDLE_VALUE;
	}
}

void CComToolDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CComToolDlg)
	DDX_Control(pDX, IDC_EDITSEND, m_editSend);
	DDX_Control(pDX, IDC_COMPORT, m_comboPort);
	DDX_Control(pDX, IDC_EDITRECV, m_editRecv);
	DDX_Control(pDX, IDC_STATIC_STATUS, m_barStatus);
	DDX_CBIndex(pDX, IDC_BAUDRATE, m_iBaudrate);
	DDX_CBIndex(pDX, IDC_BYTESIZE, m_iBytesize);
	DDX_CBIndex(pDX, IDC_PARITY, m_iParity);
	DDX_CBIndex(pDX, IDC_STOPBITS, m_iStopbits);
	DDX_CBIndex(pDX, IDC_COMPORT, m_iComport);
	DDX_Radio(pDX, IDC_DISPTYPE, m_iDisptype);
	DDX_Radio(pDX, IDC_DATATYPE, m_iDatatype);
	DDX_CBIndex(pDX, IDC_FLOWCONTROL, m_iFlowctrl);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CComToolDlg, CDialog)
	//{{AFX_MSG_MAP(CComToolDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_OPENPORT, OnOpenport)
	ON_BN_CLICKED(IDC_WRITEPORT, OnWriteport)
	ON_BN_CLICKED(IDC_CLOSEPORT, OnCloseport)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CComToolDlg 儊僢僙乕僕 僴儞僪儔

BOOL CComToolDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// "僶乕僕儑儞忣曬..." 儊僯儏乕崁栚傪僔僗僥儉 儊僯儏乕傊捛壛偟傑偡丅

	// IDM_ABOUTBOX 偼僐儅儞僪 儊僯儏乕偺斖埻偱側偗傟偽側傝傑偣傫丅
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 偙偺僟僀傾儘僌梡偺傾僀僐儞傪愝掕偟傑偡丅僼儗乕儉儚乕僋偼傾僾儕働乕僔儑儞偺儊僀儞
	// 僂傿儞僪僂偑僟僀傾儘僌偱側偄帪偼帺摦揑偵愝掕偟傑偣傫丅
	SetIcon(m_hIcon, TRUE);			// 戝偒偄傾僀僐儞傪愝掕
	SetIcon(m_hIcon, FALSE);		// 彫偝偄傾僀僐儞傪愝掕
	
	// TODO: 摿暿側弶婜壔傪峴偆帪偼偙偺応強偵捛壛偟偰偔偩偝偄丅
	GetSystemPorts( );

	GetDlgItem( IDC_COMPORT)->EnableWindow( TRUE);
	GetDlgItem( IDC_BAUDRATE)->EnableWindow( TRUE);
	GetDlgItem( IDC_PARITY)->EnableWindow( TRUE);
	GetDlgItem( IDC_BYTESIZE)->EnableWindow( TRUE);
	GetDlgItem( IDC_STOPBITS)->EnableWindow( TRUE);
	GetDlgItem( IDC_FLOWCONTROL)->EnableWindow( TRUE);
	GetDlgItem( IDC_DISPTYPE)->EnableWindow( TRUE);
	GetDlgItem( IDC_DISPTYPE2)->EnableWindow( TRUE);
	GetDlgItem( IDC_OPENPORT)->EnableWindow( TRUE);

	GetDlgItem( IDC_WRITEPORT)->EnableWindow( FALSE);
	GetDlgItem( IDC_DATATYPE)->EnableWindow( FALSE);
	GetDlgItem( IDC_DATATYPE2)->EnableWindow( FALSE);
	GetDlgItem( IDC_CLOSEPORT)->EnableWindow( FALSE);

	m_iBaudrate = 2;
	m_iBytesize = 3;
	m_iParity = 0;
	m_iStopbits = 0;
	m_iFlowctrl = 0;
	m_iComport = -1;
	m_iDisptype = 0;
	m_iDatatype = 0;
	UpdateData( FALSE);

	return TRUE;  // TRUE 傪曉偡偲僐儞僩儘乕儖偵愝掕偟偨僼僅乕僇僗偼幐傢傟傑偣傫丅
}

void CComToolDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 傕偟僟僀傾儘僌儃僢僋僗偵嵟彫壔儃僞儞傪捛壛偡傞側傜偽丄傾僀僐儞傪昤夋偡傞
// 僐乕僪傪埲壓偵婰弎偡傞昁梫偑偁傝傑偡丅MFC 傾僾儕働乕僔儑儞偼 document/view
// 儌僨儖傪巊偭偰偄傞偺偱丄偙偺張棟偼僼儗乕儉儚乕僋偵傛傝帺摦揑偵張棟偝傟傑偡丅

void CComToolDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 昤夋梡偺僨僶僀僗 僐儞僥僉僗僩

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// 僋儔僀傾儞僩偺嬮宍椞堟撪偺拞墰
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 傾僀僐儞傪昤夋偟傑偡丅
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// 僔僗僥儉偼丄儐乕僓乕偑嵟彫壔僂傿儞僪僂傪僪儔僢僌偟偰偄傞娫丄
// 僇乕僜儖傪昞帵偡傞偨傔偵偙偙傪屇傃弌偟傑偡丅
HCURSOR CComToolDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

//open COM port
void CComToolDlg::OnOpenport() 
{
	int iBaudrate,
		iParity,
		iStopbit,
		iBytesize;

	CString strPort = "COM1";

	DCB dCB;
	COMMTIMEOUTS ct;

	UpdateData( TRUE);

	//check parameters
	if( 0 > m_iComport ||
		0 > m_iBaudrate ||
		0 > m_iBytesize ||
		0 > m_iParity ||
		0 > m_iStopbits ||
		0 > m_iFlowctrl)
	{
		m_barStatus.SetWindowText( " Invalid paramter");
		return;
	}

	//set paramters
	iBaudrate = g_arrBaudRate[ m_iBaudrate];
	iParity = g_arrParity[ m_iParity];
	iStopbit = g_arrStopBits[ m_iStopbits];
//	iFlowctrl = g_arrFlowCtrl[ m_iFlowctrl];
	iBytesize = g_arrByteSize[ m_iBytesize];
	m_comboPort.GetLBText( m_iComport, strPort);

	m_hPort = CreateFile( strPort,
						GENERIC_READ | GENERIC_WRITE,
						0,
						NULL,
						OPEN_EXISTING,
						0,
						NULL);
	if( INVALID_HANDLE_VALUE == m_hPort)
	{
		m_barStatus.SetWindowText( " Cannot open port");
		return;
	}

	//get state
	if( !GetCommState( m_hPort, &dCB))
	{
		m_barStatus.SetWindowText( " Get com state error");
		CloseHandle( m_hPort);
		return;
	}
	//set state
	dCB.BaudRate = iBaudrate;
	dCB.ByteSize = iBytesize;
	dCB.Parity = iParity;
	dCB.StopBits = iStopbit;
	dCB.fOutxCtsFlow = g_arrOutxCts[ m_iFlowctrl];
	dCB.fRtsControl = g_arrFlowCtrl[ m_iFlowctrl];

	if( !SetCommState( m_hPort, &dCB))
	{
		m_barStatus.SetWindowText( " Set com state error");
		CloseHandle( m_hPort);
		return;
	}

	//set timeout
	ct.ReadIntervalTimeout = MAXDWORD;
	ct.ReadTotalTimeoutConstant = 0;
	ct.ReadTotalTimeoutMultiplier = 0;
	ct.WriteTotalTimeoutConstant = 0;
	ct.WriteTotalTimeoutMultiplier = 0;
	if( !SetCommTimeouts( m_hPort, &ct))
	{
		m_barStatus.SetWindowText( " Set timeout error");
		CloseHandle( m_hPort);
		return;
	}

	SetTimer(1, 1000, NULL);

	GetDlgItem( IDC_COMPORT)->EnableWindow( FALSE);
	GetDlgItem( IDC_BAUDRATE)->EnableWindow( FALSE);
	GetDlgItem( IDC_PARITY)->EnableWindow( FALSE);
	GetDlgItem( IDC_BYTESIZE)->EnableWindow( FALSE);
	GetDlgItem( IDC_STOPBITS)->EnableWindow( FALSE);
	GetDlgItem( IDC_FLOWCONTROL)->EnableWindow( FALSE);
	GetDlgItem( IDC_DISPTYPE)->EnableWindow( FALSE);
	GetDlgItem( IDC_DISPTYPE2)->EnableWindow( FALSE);
	GetDlgItem( IDC_OPENPORT)->EnableWindow( FALSE);

	GetDlgItem( IDC_WRITEPORT)->EnableWindow( TRUE);
	GetDlgItem( IDC_DATATYPE)->EnableWindow( TRUE);
	GetDlgItem( IDC_DATATYPE2)->EnableWindow( TRUE);
	GetDlgItem( IDC_CLOSEPORT)->EnableWindow( TRUE);
	//clear status bar
	m_barStatus.SetWindowText( "");
	//clear display edit box
	m_editRecv.SetWindowText( "");
	g_iColIndex = 0;
}

void CComToolDlg::OnWriteport() 
{
	unsigned long iWritelen = 0;
	int iDatalen = 0;

	TCHAR buf[ 2050];

	BYTE bufNumber[1024];
	TCHAR *pIndex = NULL;
	TCHAR strVal[3];
	TCHAR *stopstring = NULL;
	long lVal = 0;
	int iNumberLen = 0;

	UpdateData( TRUE);

	//check parameter
	if( INVALID_HANDLE_VALUE == m_hPort)
	{
		m_barStatus.SetWindowText( " Please open a port first");
		return;
	}

	memset( bufNumber, 0x00, sizeof( bufNumber));
	memset( buf, 0x00, sizeof( buf));
	iDatalen = m_editSend.GetWindowText( buf, 2046);

	if( 0 == m_iDatatype)	//string type
	{
		WriteFile( m_hPort, buf, iDatalen, &iWritelen, NULL);
	} else {
		pIndex = buf;
		while( NULL != pIndex && 0 != *pIndex)
		{
			memset( strVal, 0x00, 3 * sizeof( TCHAR));
			if( _T( ' ') == *pIndex || _T( '\t') == *pIndex)
				pIndex ++;

			strVal[0] = *pIndex;
			strVal[1] = *(pIndex+1);

			//convert data to number
			lVal = strtol( strVal, &stopstring, 16);
			bufNumber[ iNumberLen] = ( BYTE)lVal;

			iNumberLen ++;
			pIndex += 2;
		}

		WriteFile( m_hPort, bufNumber, iNumberLen, &iWritelen, NULL);
	}

	//clear status bar
	m_barStatus.SetWindowText( "");
}

void CComToolDlg::OnCloseport() 
{
	if( INVALID_HANDLE_VALUE != m_hPort)
	{
		CloseHandle( m_hPort);
		m_hPort = INVALID_HANDLE_VALUE;
	}

	KillTimer(1);

	GetDlgItem( IDC_COMPORT)->EnableWindow( TRUE);
	GetDlgItem( IDC_BAUDRATE)->EnableWindow( TRUE);
	GetDlgItem( IDC_PARITY)->EnableWindow( TRUE);
	GetDlgItem( IDC_BYTESIZE)->EnableWindow( TRUE);
	GetDlgItem( IDC_STOPBITS)->EnableWindow( TRUE);
	GetDlgItem( IDC_FLOWCONTROL)->EnableWindow( TRUE);
	GetDlgItem( IDC_DISPTYPE)->EnableWindow( TRUE);
	GetDlgItem( IDC_DISPTYPE2)->EnableWindow( TRUE);
	GetDlgItem( IDC_OPENPORT)->EnableWindow( TRUE);

	GetDlgItem( IDC_WRITEPORT)->EnableWindow( FALSE);
	GetDlgItem( IDC_DATATYPE)->EnableWindow( FALSE);
	GetDlgItem( IDC_DATATYPE2)->EnableWindow( FALSE);
	GetDlgItem( IDC_CLOSEPORT)->EnableWindow( FALSE);
	//clear status bar
	m_barStatus.SetWindowText( "");
}

void CComToolDlg::OnTimer(UINT nIDEvent) 
{
	BYTE buf[256];	//buf to receive data from port
	unsigned long iReadlen = 0;	//length of data received from port
	int iRet = 0;	//return value of reading
	TCHAR bufTemp[2048] = _T( "");	//temporary buf, used to convert data to hexadecimal format
	TCHAR *pIdx = NULL;	//buf pointer, used to convert data to hexadecimal format
	unsigned long i = 0;	//loop

	memset( buf, 0x00, sizeof( buf));

	//parameter chech
	if( INVALID_HANDLE_VALUE == m_hPort)
	{
		return;
	}

	//read data from COM port
	iRet = ReadFile( m_hPort, buf, 255, &iReadlen, NULL);
	if( 0 == iRet)
		return;
	if( iReadlen <= 0)
		return;

	if( 1 == m_iDisptype)	//display as ASCII
	{
		AppendText( (LPCTSTR)buf);
	} else {				//display as HEX
		pIdx = bufTemp;

		//convert data to hexadecimal format
		for( i=0; i<iReadlen; i++)
		{
			_stprintf( pIdx, "%02X ", buf[i]);
			pIdx += 3;

			g_iColIndex++;
			if( 0 == ( g_iColIndex%16) && 0 != g_iColIndex)
			{
				//add a new line
				pIdx[0] = _T( '\r');
				pIdx[1] = _T( '\n');
				pIdx += 2;
				g_iColIndex = 0;
			}
		}

		AppendText( bufTemp);
	}
}

void CComToolDlg::GetSystemPorts()
{
	PORT_INFO_2		*pAllPortsInfo_2 = NULL;
	DWORD			dwPortInfoSize = 0,
		    		dwPortCount = 0;
    DWORD           i;
	CString			strPort = _T( "");

	m_comboPort.ResetContent();

    //enumerate system ports
	EnumPorts(NULL, 2, NULL, 0, &dwPortInfoSize, &dwPortCount);
	pAllPortsInfo_2 = (PORT_INFO_2 *)malloc( dwPortInfoSize);
	if ( NULL == pAllPortsInfo_2)
        return ;
	EnumPorts(NULL, 2, (LPBYTE)pAllPortsInfo_2, dwPortInfoSize, &dwPortInfoSize, &dwPortCount);

    for (i = 0; i < dwPortCount; i++) {
		if (strstr(pAllPortsInfo_2[i].pPortName, "COM") != 0) {
			strPort = pAllPortsInfo_2[i].pPortName;
			if( ':' == strPort[4])
				strPort.SetAt( 4, 0);
			else if( ':' == strPort[5])
				strPort.SetAt( 5, 0);
			m_comboPort.AddString( strPort);
		}
	}
	free(pAllPortsInfo_2);
}

void CComToolDlg::AppendText(LPCTSTR strText)
{
	int iLen = m_editRecv.GetWindowTextLength();
	if( iLen > 4096)
	{
		m_editRecv.SetSel( 0, iLen);
		m_editRecv.Clear();

		iLen = 0;
		g_iColIndex = 0;
	}

	m_editRecv.SetFocus();
	m_editRecv.SetSel( iLen, iLen);
	m_editRecv.ReplaceSel( strText);
}

⌨️ 快捷键说明

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