【用MFC写串口调试助手】

这篇具有很好参考价值的文章主要介绍了【用MFC写串口调试助手】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

界面设计

【用MFC写串口调试助手】

各控件说明

ID Type Member 说明
IDC_BUTTON_SERCHSEL 检测串口按钮
IDC_BUTTON_OPENSEL 打开串口按钮
IDC_BUTTON_CLOSESEL 关闭串口按钮
IDC_BUTTON_CLEARGETDATA 清空接收区按钮
IDC_BUTTON_SENDDATA 发送数据按钮
IDC_BUTTON_CLEARSENDDATA 清空发送区按钮
IDC_COMBO_CHOOSESEL CComboBox m_COMBO_ChooseSel 串口选择下拉框
IDC_COMBO_BOTRAT CComboBox m_COMBO_BotRat 波特率选择下拉框
IDC_COMBO_DABIT CComboBox m_COMBO_DaBit 数据位选择下拉框
IDC_COMBO_CKBIT CComboBox m_COMBO_CkBit 校验位选择下拉框
IDC_COMBO_STOPBIT CComboBox m_COMBO_StopBit 停止位选择下拉框
IDC_CHECK_SENDDATATIME BOOL m_SendDataTime 定时发送复选框
IDC_CHECK_GETHEXDATA BOOL m_GetHexData HEX接收复选框
IDC_CHECK_SENDHEXDATA BOOL m_SendHexData HEX发送复选框
IDC_EDIT_GETDATA CString m_EDIT_GetData 显示接收数据编辑框
IDC_EDIT_GETDATABATE CString m_EDIT_GetDataBate 显示已接收数据长度编辑框
IDC_EDIT_SENDDATA CString m_EDIT_SendData 显示发送数据编辑框
IDC_EDIT_SENDDATABATE CString m_EDIT_SendDataBate 显示已发送数据长度编辑框
IDC_EDIT_SENDDATATIME int m_EDIT_SendDataTime 设置定时发送时间编辑框
IDC_MSCOMM CMSComm m_Comm 串口控件

串口控件的插入

在页面设计界面点击鼠标右键,选择插入ActiveX控件…,在弹出的界面选择Microsoft Communications Control, Version 5…,点击确定进行串口控件的插入。

若出现Active X控件不能例示可到网上下载MSDATGRD.OCX和MSADODC.OCX两个文件,注册一下就好了,具体步骤如下:

1.先下载这两个文件

使用说明:
如果是64位系统:
请分别将MSADODC.OCX放入C:\Windows\SysWOW64目录下
MSDATGRD.OCX放入C:\Windows\System32目录下

如果是32位系统:
请将MSADODC.OCX和MSDATGRD.OCX都放入C:\Windows\System32目录下

2.对文件进行注册

按win+r开打“运行”对话框,输入"cmd",打开命令提示符,
输入"regsvr32 C:\Windows\SysWOW64\MSADODC.OCX"命令注册MSADODC.OCX
输入"regsvr32 C:\Windows\System32\MSDATGRD.OCX"命令注册MSDATGRD.OCX

再次打开工程文件,现在是不是已经可以正常使用了。

若还是无法运行便可此文件进行注册表注册 注册表。文章来源地址https://www.toymoban.com/news/detail-470632.html

程序设计

初始化函数添加

// TODO: Add extra initialization here
	// 波特率设置
	m_COMBO_BotRat.AddString(_T("110"));
	m_COMBO_BotRat.AddString(_T("300"));
	m_COMBO_BotRat.AddString(_T("600"));
	m_COMBO_BotRat.AddString(_T("1200"));
	m_COMBO_BotRat.AddString(_T("2400"));
	m_COMBO_BotRat.AddString(_T("4800"));
	m_COMBO_BotRat.AddString(_T("9600"));
	m_COMBO_BotRat.AddString(_T("11400"));
	m_COMBO_BotRat.AddString(_T("19200"));
	m_COMBO_BotRat.AddString(_T("38400"));
	m_COMBO_BotRat.AddString(_T("56000"));
	m_COMBO_BotRat.AddString(_T("57600"));
	m_COMBO_BotRat.AddString(_T("115200"));
	m_COMBO_BotRat.AddString(_T("128000"));
	m_COMBO_BotRat.AddString(_T("256000"));
	m_COMBO_BotRat.SetCurSel(6);

	// 数据位设置
	for (int i = 5; i <= 8; i++ )
	{
		CString strBit;
		strBit.Format("%d", i);
		m_COMBO_DaBit.AddString(strBit);
	}
	m_COMBO_DaBit.SetCurSel(3);

	// 检验位设置
	m_COMBO_CkBit.AddString(_T("NONE"));
	m_COMBO_CkBit.AddString(_T("ODD"));
	m_COMBO_CkBit.AddString(_T("EVEN"));
	m_COMBO_CkBit.AddString(_T("MARK"));
	m_COMBO_CkBit.AddString(_T("SPACE"));
	m_COMBO_CkBit.SetCurSel(0);

	// 停止位设置
	m_COMBO_StopBit.AddString(_T("1"));
	m_COMBO_StopBit.AddString(_T("1.5"));
	m_COMBO_StopBit.AddString(_T("2"));
	m_COMBO_StopBit.SetCurSel(0);

	SendDataTimeState = 0;
	GetHexDataState = 0;
	SendHexDataState = 0;

	OnButtonSerchsel();  // 串口检测函数

串口检测按钮相关函数

CUIntArray ports;	//所有存在的串口
CUIntArray portse;	//可用的串口
CUIntArray portsu;	//已占用的串口
#define MAX_SCAN_CNT 128

void CSerial_DemoDlg::OnButtonSerchsel() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	
	unsigned short com_cnt;
	while (m_COMBO_ChooseSel.DeleteString(0) >= 0);
	com_cnt = AddCom(&m_COMBO_ChooseSel);
	if(com_cnt)
	{
		m_COMBO_ChooseSel.DeleteString(com_cnt + 1);
		m_COMBO_ChooseSel.SetCurSel(0);
	}
	UpdateData(FALSE);
}

void CSerial_DemoDlg::EnumerateSerialPorts(CUIntArray& porta, CUIntArray& portse, CUIntArray& portsu)
{
	//清除串口数组内容 
	porta.RemoveAll();
	portse.RemoveAll();
	portsu.RemoveAll();
	//因为至多有255个串口,所以依次检查各串口是否存在                                                   
	//如果能打开某一串口,或打开串口不成功,但返回的是 ERROR_ACCESS_DENIED错误信息,                    
	//都认为串口存在,只不过后者表明串口已经被占用                                                      
	//否则串口不存在
	for (int i = 1;i < MAX_SCAN_CNT;i++)
	{
		//形成原始设备名称
		CString sPort;
		sPort.Format(_T("\\\\.\\COM%d"),i);
		//尝试打开该端口
		BOOL bSuccess = FALSE;
		HANDLE hPort = ::CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
		if (hPort == INVALID_HANDLE_VALUE)
		{
			DWORD dwError = GetLastError();
			
			if (dwError == ERROR_ACCESS_DENIED)
			{
				bSuccess = TRUE;
				portsu.Add(i);//已占用的串口
			}
		}
		else
		{
			//该端口已成功打开
			bSuccess = TRUE;
			portse.Add(i);//可用串口
			//不要忘记关闭端口,因为我们不会对它做任何事情
			CloseHandle(hPort);
		}
		//将端口号添加到将要返回的数组中
		if (bSuccess)
			porta.Add(i);//所有存在的串口
	}
}

UShort CSerial_DemoDlg::AddCom(CComboBox* pvect)
{
	UShort uicounter; //串口数量
	UShort uisetcom;
	CString str;
 
	EnumerateSerialPorts(ports, portse, portsu);  //获得可用串口数
	//获取可用串口个数  
	uicounter = portse.GetSize();
	//如果个数大于0  
	if (uicounter > 0)
	{
		//初始化串口列表框
		for (int i = 0;i < uicounter;i++)
		{
			uisetcom = portse.ElementAt(i);
			str.Format(_T("COM%d "), uisetcom);
			pvect->InsertString(i, str);
		}
	}
	return uicounter;
}

打开按钮相关函数

void CSerial_DemoDlg::OnButtonOpensel() 
{
	// TODO: Add your control notification handler code here
	DWORD nCommPort;
	nCommPort = (unsigned)GetCommPortN();		// 获取串口号

	CString strPara = GetCommPortParameter();
	if(strPara.GetLength() <= 0)
		MessageBox(_T("参数获取错误!"), _T("Error"), MB_ICONERROR | MB_OK);
	char *pszPara = strPara.GetBuffer(0);
	strPara.ReleaseBuffer();

	// 打开串口
	if(m_Comm.GetPortOpen())
		MessageBox(_T("串口已打开", _T("Warning"), MB_ICONWARNING | MB_OK));

	m_Comm.SetCommPort(nCommPort);		// 选择串口号
	m_Comm.SetInBufferSize(1024);		// 设置输入缓冲区的大小,Bytes
	m_Comm.SetOutBufferSize(1024);		// 设置输入缓冲区的大小,Bytes//
	m_Comm.SetSettings(strPara);
	m_Comm.SetInputMode(1);			// 1:表示以二进制方式检取数据
	m_Comm.SetRThreshold(1);			// 参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnOnCommMscomm事件
	m_Comm.SetInputLen(0);				// 设置当前接收区数据长度为0
	if( !m_Comm.GetPortOpen())
	{
		m_Comm.SetPortOpen(TRUE);
		GetDlgItem(IDC_BUTTON_OPENSEL)->EnableWindow(FALSE);
		GetDlgItem(IDC_BUTTON_CLOSESEL)->EnableWindow(TRUE);
	}
	else
		AfxMessageBox("cannot open serial port");
	m_Comm.GetInput();//先预读缓冲区以清除残留数据
	UpdateData(false);

}

long CSerial_DemoDlg::GetCommPortN() // 获取COMBO BOX上的串口编号
{
	CString strCommPort;
	m_COMBO_ChooseSel.GetWindowText(strCommPort);
	strCommPort = strCommPort.Mid(3);
	return _ttol(strCommPort);
}

CString CSerial_DemoDlg::GetCommPortParameter() //	获取串口参数
{
	CString strParameter = "";
	CString strBaudRate;	// 波特率
	CString strDataBit;		// 数据位
	CString strCheckBit;	// 校验位
	CString strStopBit;		// 停止位

	m_COMBO_BotRat.GetWindowText(strBaudRate);
	m_COMBO_CkBit.GetWindowText(strCheckBit);
	m_COMBO_DaBit.GetWindowText(strDataBit);
	m_COMBO_StopBit.GetWindowText(strStopBit);

	strCheckBit = strCheckBit.Left(1);
	strCheckBit.MakeLower();
	
	strParameter += strBaudRate;
	strParameter += _T(",");
	strParameter += strCheckBit;
	strParameter += _T(",");
	strParameter += strDataBit;
	strParameter += _T(",");
	strParameter += strStopBit;

	return strParameter;
}

void CSerial_DemoDlg::OnOnCommMscomm() // 该函数可在类向导中ID选择IDC_MSCOMM,Messages选择OnComm创建
{
	// TODO: Add your control notification handler code here
	VARIANT variant_inp;
	COleSafeArray safearray_inp;
	LONG len,k;
	BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
	CString strtemp;
	if(m_Comm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
	{
		variant_inp=m_Comm.GetInput(); //读缓冲区
		safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
		len = 0;
		len=safearray_inp.GetOneDimSize(); //得到有效数据长度
		for(k=0;k<len;k++)
			safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组

		if(GetHexDataState == 1) // 16进制接收
		{
			for (k = 0; k < len; k++)
			{
				switch (rxdata[k] / 16)
				{
				case 0:  m_EDIT_GetData += '0'; break;
				case 1:  m_EDIT_GetData += '1'; break;
				case 2:  m_EDIT_GetData += '2'; break;
				case 3:  m_EDIT_GetData += '3'; break;
				case 4:  m_EDIT_GetData += '4'; break;
				case 5:  m_EDIT_GetData += '5'; break;
				case 6:  m_EDIT_GetData += '6'; break;
				case 7:  m_EDIT_GetData += '7'; break;
				case 8:  m_EDIT_GetData += '8'; break;
				case 9:  m_EDIT_GetData += '9'; break;
				case 10:  m_EDIT_GetData += 'A'; break;
				case 11:  m_EDIT_GetData += 'B'; break;
				case 12:  m_EDIT_GetData += 'C'; break;
				case 13:  m_EDIT_GetData += 'D'; break;
				case 14:  m_EDIT_GetData += 'E'; break;
				case 15:  m_EDIT_GetData += 'F'; break;
				}
				switch (rxdata[k] % 16)
				{
				case 0:  m_EDIT_GetData += '0'; break;
				case 1:  m_EDIT_GetData += '1'; break;
				case 2:  m_EDIT_GetData += '2'; break;
				case 3:  m_EDIT_GetData += '3'; break;
				case 4:  m_EDIT_GetData += '4'; break;
				case 5:  m_EDIT_GetData += '5'; break;
				case 6:  m_EDIT_GetData += '6'; break;
				case 7:  m_EDIT_GetData += '7'; break;
				case 8:  m_EDIT_GetData += '8'; break;
				case 9:  m_EDIT_GetData += '9'; break;
				case 10:  m_EDIT_GetData += 'A'; break;
				case 11:  m_EDIT_GetData += 'B'; break;
				case 12:  m_EDIT_GetData += 'C'; break;
				case 13:  m_EDIT_GetData += 'D'; break;
				case 14:  m_EDIT_GetData += 'E'; break;
				case 15:  m_EDIT_GetData += 'F'; break;
				}
				m_EDIT_GetData += ' ';
			}
			SetDlgItemText(IDC_EDIT_GETDATA,m_EDIT_GetData);	// 显示接受数据
		}
		if(GetHexDataState == 0)
		{
			for(k=0;k<len;k++) //将数组转换为Cstring型变量
			{
				BYTE bt=*(char*)(rxdata+k); //字符型
				strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
				if(strtemp == '\n' || strtemp == '\r')
					strtemp = "\r\n";
				m_EDIT_GetData+=strtemp; //加入接收编辑框对应字符串 
			}
			SetDlgItemText(IDC_EDIT_GETDATA,m_EDIT_GetData);	// 显示接受数据
		}

		CString string;
		GetDataBata += len;
		string.Format(_T("%ld"), GetDataBata);
		SetDlgItemText(IDC_EDIT_GETDATABATE,string);	// 显示接受字节

	}
}

发送数据按钮相关函数

void CSerial_DemoDlg::OnButtonSenddata() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE); //读取编辑框内容
	CByteArray HexDataBuf;
	int i = 0;
	BYTE SendBuf[128]={0};
	BYTE GetData[256]={0};
	int SendLen = 0;
	int GetLen = 0;
	CString string;

	if(m_EDIT_SendData.IsEmpty())
	{
		AfxMessageBox(_T("发送数据为空!"));
		return;
	}
	HexDataBuf.RemoveAll();    //清空数组

	if (SendHexDataState == 0)
	{
		m_Comm.SetOutput(COleVariant(m_EDIT_SendData));//发送数据
		m_Comm.SetOutput(COleVariant("\r\n"));//发送回车
		SendDataBata += m_EDIT_SendData.GetLength()+2;
	}
	if (SendHexDataState == 1)
	{
		GetLen = m_EDIT_SendData.GetLength();
		for(i=0; i<GetLen; i++)
			GetData[i] = (BYTE)m_EDIT_SendData.GetBuffer(GetLen)[i];
		StringtoHex(GetData, GetLen, SendBuf, &SendLen);//将字符串转化为字节数据

		HexDataBuf.SetSize(SendLen);   //设置数组大小为帧长度 
		for(i=0; i<SendLen; i++)
			HexDataBuf.SetAt(i,SendBuf[i]);
		m_Comm.SetOutput(COleVariant(HexDataBuf)); //发送十六进制数据

		SendDataBata += SendLen;
	}
	
	string.Format("%d", SendDataBata);
	SetDlgItemText(IDC_EDIT_SENDDATABATE,string);
}

void CSerial_DemoDlg::StringtoHex(BYTE *GB, int glen, BYTE* SB, int* slen)
{
	int i; //遍历输入的字符串
	int a = 0; 
	char temp; //接收字符,用来判断是否为空格,若是则跳过
	char temp1,temp2; //接收一个字节的两个字符 例如EB,则temp1='E',temp2 = 'B'
	*slen = 0; //输出的16进制字符串长度
	for(i=0;i<glen;i++)
	{
		temp = GB[i];
		if(temp==' ')
			continue;
		if(a == 0)
			temp1 = GB[i];
		if(a == 1)
			temp2 = GB[i];
		a++;
		
		if(a==2)
		{
			a = 0;
			temp1 = temp1 - '0';
			if (temp1>10)
				temp1 = temp1 -7;
			temp2 = temp2 - '0';
			if (temp2>10)
				temp2 = temp2 -7;
			
			SB[*slen] = temp1*16+temp2;
			(*slen)++;
		}
	}
}

点选定时发送复选框

void CSerial_DemoDlg::OnCheckSenddatatime() 
{
	// TODO: Add your control notification handler code here
	if (SendDataTimeState == 0)
	{
		if( m_Comm.GetPortOpen())
		{
			UpdateData(TRUE); //读取编辑框内容
			SetTimer( IDC_TIMER, m_EDIT_SendDataTime, NULL );
		}
	}
	else
	{
		KillTimer( IDC_TIMER );
		SendDataTimeState = 0;
	}
	
}

void CSerial_DemoDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	OnButtonSenddata();
	SendDataTimeState = 1;
	CDialog::OnTimer(nIDEvent);
}

点选HEX发送复选框相关函数

void CSerial_DemoDlg::OnCheckGethexdata() 
{
	// TODO: Add your control notification handler code here
	if(GetHexDataState == 0)
		GetHexDataState = 1;
	else if(GetHexDataState == 1)
		GetHexDataState = 0;
}

点选HEX接收复选框相关函数

void CSerial_DemoDlg::OnCheckSendhexdata() 
{
	// TODO: Add your control notification handler code here
	if (SendHexDataState == 0)
		SendHexDataState = 1;
	else if (SendHexDataState == 1)
		SendHexDataState = 0;
}

清空接收区按钮相关函数

void CSerial_DemoDlg::OnButtonCleargetdata() 
{
	// TODO: Add your control notification handler code here
	m_EDIT_GetData = _T("");
	SetDlgItemText(IDC_EDIT_GETDATA,"");
}

清空发送区按钮相关函数

void CSerial_DemoDlg::OnButtonClearsenddata() 
{
	// TODO: Add your control notification handler code here
	SetDlgItemText(IDC_EDIT_SENDDATA,"");
}

关闭串口按钮相关函数

void CSerial_DemoDlg::OnButtonClosesel() 
{
	// TODO: Add your control notification handler code here
	if(m_Comm.GetPortOpen())
	{
		m_Comm.SetPortOpen(FALSE);
		GetDlgItem(IDC_BUTTON_OPENSEL)->EnableWindow(TRUE);
		GetDlgItem(IDC_BUTTON_CLOSESEL)->EnableWindow(FALSE);
		GetDataBata = 0;
		SendDataBata = 0;
		SetDlgItemText(IDC_EDIT_GETDATABATE,"");
		SetDlgItemText(IDC_EDIT_SENDDATABATE,"");
	}
}

完整程序

.cpp文件

// Serial_DemoDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Serial_Demo.h"
#include "Serial_DemoDlg.h"

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

/
// CAboutDlg dialog used for App About

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

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
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)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CSerial_DemoDlg dialog

CSerial_DemoDlg::CSerial_DemoDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSerial_DemoDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSerial_DemoDlg)
	m_GetHexData = FALSE;
	m_SendDataTime = FALSE;
	m_SendHexTime = FALSE;
	m_EDIT_GetData = _T("");
	m_EDIT_SendData = _T("");
	m_EDIT_SendDataTime = 1000;
	SendDataTimeState = 0;
	GetHexDataState = 0;
	SendHexDataState = 0;
	GetDataBata = 0;
	SendDataBata = 0;
	m_EDIT_GetDataBate = _T("");
	m_EDIT_SendDataBate = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSerial_DemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSerial_DemoDlg)
	DDX_Control(pDX, IDC_COMBO_STOPBIT, m_COMBO_StopBit);
	DDX_Control(pDX, IDC_COMBO_DABIT, m_COMBO_DaBit);
	DDX_Control(pDX, IDC_COMBO_CKBIT, m_COMBO_CkBit);
	DDX_Control(pDX, IDC_COMBO_CHOOSESEL, m_COMBO_ChooseSel);
	DDX_Control(pDX, IDC_COMBO_BOTRAT, m_COMBO_BotRat);
	DDX_Check(pDX, IDC_CHECK_GETHEXDATA, m_GetHexData);
	DDX_Check(pDX, IDC_CHECK_SENDDATATIME, m_SendDataTime);
	DDX_Check(pDX, IDC_CHECK_SENDHEXDATA, m_SendHexTime);
	DDX_Text(pDX, IDC_EDIT_GETDATA, m_EDIT_GetData);
	DDX_Text(pDX, IDC_EDIT_SENDDATA, m_EDIT_SendData);
	DDX_Text(pDX, IDC_EDIT_SENDDATATIME, m_EDIT_SendDataTime);
	DDX_Control(pDX, IDC_MSCOMM1, m_Comm);
	DDX_Text(pDX, IDC_EDIT_GETDATABATE, m_EDIT_GetDataBate);
	DDX_Text(pDX, IDC_EDIT_SENDDATABATE, m_EDIT_SendDataBate);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSerial_DemoDlg, CDialog)
	//{{AFX_MSG_MAP(CSerial_DemoDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_OPENSEL, OnButtonOpensel)
	ON_BN_CLICKED(IDC_BUTTON_SERCHSEL, OnButtonSerchsel)
	ON_BN_CLICKED(IDC_BUTTON_SENDDATA, OnButtonSenddata)
	ON_BN_CLICKED(IDC_BUTTON_CLOSESEL, OnButtonClosesel)
	ON_BN_CLICKED(IDC_CHECK_SENDDATATIME, OnCheckSenddatatime)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BUTTON_CLEARGETDATA, OnButtonCleargetdata)
	ON_BN_CLICKED(IDC_BUTTON_CLEARSENDDATA, OnButtonClearsenddata)
	ON_BN_CLICKED(IDC_CHECK_GETHEXDATA, OnCheckGethexdata)
	ON_BN_CLICKED(IDC_CHECK_SENDHEXDATA, OnCheckSendhexdata)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CSerial_DemoDlg message handlers

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

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	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);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	// 波特率设置
	m_COMBO_BotRat.AddString(_T("110"));
	m_COMBO_BotRat.AddString(_T("300"));
	m_COMBO_BotRat.AddString(_T("600"));
	m_COMBO_BotRat.AddString(_T("1200"));
	m_COMBO_BotRat.AddString(_T("2400"));
	m_COMBO_BotRat.AddString(_T("4800"));
	m_COMBO_BotRat.AddString(_T("9600"));
	m_COMBO_BotRat.AddString(_T("11400"));
	m_COMBO_BotRat.AddString(_T("19200"));
	m_COMBO_BotRat.AddString(_T("38400"));
	m_COMBO_BotRat.AddString(_T("56000"));
	m_COMBO_BotRat.AddString(_T("57600"));
	m_COMBO_BotRat.AddString(_T("115200"));
	m_COMBO_BotRat.AddString(_T("128000"));
	m_COMBO_BotRat.AddString(_T("256000"));
	m_COMBO_BotRat.SetCurSel(6);

	// 数据位设置
	for (int i = 5; i <= 8; i++ )
	{
		CString strBit;
		strBit.Format("%d", i);
		m_COMBO_DaBit.AddString(strBit);
	}
	m_COMBO_DaBit.SetCurSel(3);

	// 检验位设置
	m_COMBO_CkBit.AddString(_T("NONE"));
	m_COMBO_CkBit.AddString(_T("ODD"));
	m_COMBO_CkBit.AddString(_T("EVEN"));
	m_COMBO_CkBit.AddString(_T("MARK"));
	m_COMBO_CkBit.AddString(_T("SPACE"));
	m_COMBO_CkBit.SetCurSel(0);

	// 停止位设置
	m_COMBO_StopBit.AddString(_T("1"));
	m_COMBO_StopBit.AddString(_T("1.5"));
	m_COMBO_StopBit.AddString(_T("2"));
	m_COMBO_StopBit.SetCurSel(0);

	SendDataTimeState = 0;
	GetHexDataState = 0;
	SendHexDataState = 0;

	OnButtonSerchsel();

	return TRUE;  // return TRUE  unless you set the focus to a control
}

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

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSerial_DemoDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

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

		// Center icon in client rectangle
		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;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSerial_DemoDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

BEGIN_EVENTSINK_MAP(CSerial_DemoDlg, CDialog)
    //{{AFX_EVENTSINK_MAP(CSerial_DemoDlg)
	ON_EVENT(CSerial_DemoDlg, IDC_MSCOMM1, 1 /* OnComm */, OnOnCommMscomm, VTS_NONE)
	//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

// 检测按钮相关 
CUIntArray ports;	//所有存在的串口
CUIntArray portse;	//可用的串口
CUIntArray portsu;	//已占用的串口
#define MAX_SCAN_CNT 128

void CSerial_DemoDlg::OnButtonSerchsel() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	
	unsigned short com_cnt;
	while (m_COMBO_ChooseSel.DeleteString(0) >= 0);
	com_cnt = AddCom(&m_COMBO_ChooseSel);
	if(com_cnt)
	{
		m_COMBO_ChooseSel.DeleteString(com_cnt + 1);
		m_COMBO_ChooseSel.SetCurSel(0);
	}
	UpdateData(FALSE);
}

void CSerial_DemoDlg::EnumerateSerialPorts(CUIntArray& porta, CUIntArray& portse, CUIntArray& portsu)
{
	//清除串口数组内容 
	porta.RemoveAll();
	portse.RemoveAll();
	portsu.RemoveAll();
	//因为至多有255个串口,所以依次检查各串口是否存在                                                   
	//如果能打开某一串口,或打开串口不成功,但返回的是 ERROR_ACCESS_DENIED错误信息,                    
	//都认为串口存在,只不过后者表明串口已经被占用                                                      
	//否则串口不存在
	for (int i = 1;i < MAX_SCAN_CNT;i++)
	{
		//形成原始设备名称
		CString sPort;
		sPort.Format(_T("\\\\.\\COM%d"),i);
		//尝试打开该端口
		BOOL bSuccess = FALSE;
		HANDLE hPort = ::CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
		if (hPort == INVALID_HANDLE_VALUE)
		{
			DWORD dwError = GetLastError();
			
			if (dwError == ERROR_ACCESS_DENIED)
			{
				bSuccess = TRUE;
				portsu.Add(i);//已占用的串口
			}
 
		}
		else
		{
			//该端口已成功打开
			bSuccess = TRUE;
			portse.Add(i);//可用串口
			//不要忘记关闭端口,因为我们不会对它做任何事情
			CloseHandle(hPort);
		}
		//将端口号添加到将要返回的数组中
		if (bSuccess)
		{
			porta.Add(i);//所有存在的串口
		}
	}
}
 
 
 
UShort CSerial_DemoDlg::AddCom(CComboBox* pvect)
{
	UShort uicounter; //串口数量
	UShort uisetcom;
	CString str;
 
	EnumerateSerialPorts(ports, portse, portsu);  //获得可用串口数
	//获取可用串口个数  
	uicounter = portse.GetSize();
	//如果个数大于0  
	if (uicounter > 0)
	{
		//初始化串口列表框
		for (int i = 0;i < uicounter;i++)
		{
			uisetcom = portse.ElementAt(i);
			str.Format(_T("COM%d "), uisetcom);
			pvect->InsertString(i, str);
		}
	}
	return uicounter;
}

// 打开按钮相关 
void CSerial_DemoDlg::OnButtonOpensel() 
{
	// TODO: Add your control notification handler code here
	DWORD nCommPort;
	nCommPort = (unsigned)GetCommPortN();		// 获取串口号

	CString strPara = GetCommPortParameter();
	if(strPara.GetLength() <= 0)
		MessageBox(_T("参数获取错误!"), _T("Error"), MB_ICONERROR | MB_OK);
	char *pszPara = strPara.GetBuffer(0);
	strPara.ReleaseBuffer();

	// 打开串口
	if(m_Comm.GetPortOpen())
		MessageBox(_T("串口已打开", _T("Warning"), MB_ICONWARNING | MB_OK));

	m_Comm.SetCommPort(nCommPort);		// 选择串口号
	m_Comm.SetInBufferSize(1024);		// 设置输入缓冲区的大小,Bytes
	m_Comm.SetOutBufferSize(1024);		// 设置输入缓冲区的大小,Bytes//
	m_Comm.SetSettings(strPara);
	m_Comm.SetInputMode(1);			// 1:表示以二进制方式检取数据
	m_Comm.SetRThreshold(1);			// 参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnOnCommMscomm事件
	m_Comm.SetInputLen(0);				// 设置当前接收区数据长度为0
	if( !m_Comm.GetPortOpen())
	{
		m_Comm.SetPortOpen(TRUE);
		GetDlgItem(IDC_BUTTON_OPENSEL)->EnableWindow(FALSE);
		GetDlgItem(IDC_BUTTON_CLOSESEL)->EnableWindow(TRUE);
	}
	else
		AfxMessageBox("cannot open serial port");
	m_Comm.GetInput();//先预读缓冲区以清除残留数据
	UpdateData(false);

}

long CSerial_DemoDlg::GetCommPortN() // 获取COMBO BOX上的串口编号
{
	CString strCommPort;
	m_COMBO_ChooseSel.GetWindowText(strCommPort);
	strCommPort = strCommPort.Mid(3);
	return _ttol(strCommPort);
}

CString CSerial_DemoDlg::GetCommPortParameter() //	获取串口参数
{
	CString strParameter = "";
	CString strBaudRate;	// 波特率
	CString strDataBit;		// 数据位
	CString strCheckBit;	// 校验位
	CString strStopBit;		// 停止位

	m_COMBO_BotRat.GetWindowText(strBaudRate);
	m_COMBO_CkBit.GetWindowText(strCheckBit);
	m_COMBO_DaBit.GetWindowText(strDataBit);
	m_COMBO_StopBit.GetWindowText(strStopBit);

	strCheckBit = strCheckBit.Left(1);
	strCheckBit.MakeLower();
	
	strParameter += strBaudRate;
	strParameter += _T(",");
	strParameter += strCheckBit;
	strParameter += _T(",");
	strParameter += strDataBit;
	strParameter += _T(",");
	strParameter += strStopBit;

	return strParameter;
}

void CSerial_DemoDlg::OnOnCommMscomm() 
{
	// TODO: Add your control notification handler code here
	VARIANT variant_inp;
	COleSafeArray safearray_inp;
	LONG len,k;
	BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
	CString strtemp;
	if(m_Comm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
	{
		variant_inp=m_Comm.GetInput(); //读缓冲区
		safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
		len = 0;
		len=safearray_inp.GetOneDimSize(); //得到有效数据长度
		for(k=0;k<len;k++)
			safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组

		if(GetHexDataState == 1) // 16进制接收
		{
			for (k = 0; k < len; k++)
			{
				switch (rxdata[k] / 16)
				{
				case 0:  m_EDIT_GetData += '0'; break;
				case 1:  m_EDIT_GetData += '1'; break;
				case 2:  m_EDIT_GetData += '2'; break;
				case 3:  m_EDIT_GetData += '3'; break;
				case 4:  m_EDIT_GetData += '4'; break;
				case 5:  m_EDIT_GetData += '5'; break;
				case 6:  m_EDIT_GetData += '6'; break;
				case 7:  m_EDIT_GetData += '7'; break;
				case 8:  m_EDIT_GetData += '8'; break;
				case 9:  m_EDIT_GetData += '9'; break;
				case 10:  m_EDIT_GetData += 'A'; break;
				case 11:  m_EDIT_GetData += 'B'; break;
				case 12:  m_EDIT_GetData += 'C'; break;
				case 13:  m_EDIT_GetData += 'D'; break;
				case 14:  m_EDIT_GetData += 'E'; break;
				case 15:  m_EDIT_GetData += 'F'; break;
				}
				switch (rxdata[k] % 16)
				{
				case 0:  m_EDIT_GetData += '0'; break;
				case 1:  m_EDIT_GetData += '1'; break;
				case 2:  m_EDIT_GetData += '2'; break;
				case 3:  m_EDIT_GetData += '3'; break;
				case 4:  m_EDIT_GetData += '4'; break;
				case 5:  m_EDIT_GetData += '5'; break;
				case 6:  m_EDIT_GetData += '6'; break;
				case 7:  m_EDIT_GetData += '7'; break;
				case 8:  m_EDIT_GetData += '8'; break;
				case 9:  m_EDIT_GetData += '9'; break;
				case 10:  m_EDIT_GetData += 'A'; break;
				case 11:  m_EDIT_GetData += 'B'; break;
				case 12:  m_EDIT_GetData += 'C'; break;
				case 13:  m_EDIT_GetData += 'D'; break;
				case 14:  m_EDIT_GetData += 'E'; break;
				case 15:  m_EDIT_GetData += 'F'; break;
				}
				m_EDIT_GetData += ' ';
			}
			SetDlgItemText(IDC_EDIT_GETDATA,m_EDIT_GetData);	// 显示接受数据
		}
		if(GetHexDataState == 0)
		{
			for(k=0;k<len;k++) //将数组转换为Cstring型变量
			{
				BYTE bt=*(char*)(rxdata+k); //字符型
				strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
				if(strtemp == '\n' || strtemp == '\r')
					strtemp = "\r\n";
				m_EDIT_GetData+=strtemp; //加入接收编辑框对应字符串 
			}
			SetDlgItemText(IDC_EDIT_GETDATA,m_EDIT_GetData);	// 显示接受数据
		}

		CString string;
		GetDataBata += len;
		string.Format(_T("%ld"), GetDataBata);
		SetDlgItemText(IDC_EDIT_GETDATABATE,string);	// 显示接受字节

	}
}

void CSerial_DemoDlg::OnButtonSenddata() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE); //读取编辑框内容
	CByteArray HexDataBuf;
	int i = 0;
	BYTE SendBuf[128]={0};
	BYTE GetData[256]={0};
	int SendLen = 0;
	int GetLen = 0;
	CString string;

	if(m_EDIT_SendData.IsEmpty())
	{
		AfxMessageBox(_T("发送数据为空!"));
		return;
	}
	HexDataBuf.RemoveAll();    //清空数组

	if (SendHexDataState == 0)
	{
		m_Comm.SetOutput(COleVariant(m_EDIT_SendData));//发送数据
		m_Comm.SetOutput(COleVariant("\r\n"));//发送回车
		SendDataBata += m_EDIT_SendData.GetLength()+2;
	}
	if (SendHexDataState == 1)
	{
		GetLen = m_EDIT_SendData.GetLength();
		for(i=0; i<GetLen; i++)
			GetData[i] = (BYTE)m_EDIT_SendData.GetBuffer(GetLen)[i];
		StringtoHex(GetData, GetLen, SendBuf, &SendLen);//将字符串转化为字节数据

		HexDataBuf.SetSize(SendLen);   //设置数组大小为帧长度 
		for(i=0; i<SendLen; i++)
			HexDataBuf.SetAt(i,SendBuf[i]);
		m_Comm.SetOutput(COleVariant(HexDataBuf)); //发送十六进制数据

		SendDataBata += SendLen;
	}
	
	string.Format("%d", SendDataBata);
	SetDlgItemText(IDC_EDIT_SENDDATABATE,string);
}

// 关闭串口 
void CSerial_DemoDlg::OnButtonClosesel() 
{
	// TODO: Add your control notification handler code here
	if(m_Comm.GetPortOpen())
	{
		m_Comm.SetPortOpen(FALSE);
		GetDlgItem(IDC_BUTTON_OPENSEL)->EnableWindow(TRUE);
		GetDlgItem(IDC_BUTTON_CLOSESEL)->EnableWindow(FALSE);
		GetDataBata = 0;
		SendDataBata = 0;
		SetDlgItemText(IDC_EDIT_GETDATABATE,"");
		SetDlgItemText(IDC_EDIT_SENDDATABATE,"");
	}
}

void CSerial_DemoDlg::OnCheckSenddatatime() 
{
	// TODO: Add your control notification handler code here
	if (SendDataTimeState == 0)
	{
		if( m_Comm.GetPortOpen())
		{
			UpdateData(TRUE); //读取编辑框内容
			SetTimer( IDC_TIMER, m_EDIT_SendDataTime, NULL );
		}
	}
	else
	{
		KillTimer( IDC_TIMER );
		SendDataTimeState = 0;
	}
	
}

void CSerial_DemoDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	OnButtonSenddata();
	SendDataTimeState = 1;
	CDialog::OnTimer(nIDEvent);
}

void CSerial_DemoDlg::OnButtonCleargetdata() 
{
	// TODO: Add your control notification handler code here
	m_EDIT_GetData = _T("");
	SetDlgItemText(IDC_EDIT_GETDATA,"");
}

void CSerial_DemoDlg::OnButtonClearsenddata() 
{
	// TODO: Add your control notification handler code here
	SetDlgItemText(IDC_EDIT_SENDDATA,"");
}

void CSerial_DemoDlg::OnCheckGethexdata() 
{
	// TODO: Add your control notification handler code here
	if(GetHexDataState == 0)
		GetHexDataState = 1;
	else if(GetHexDataState == 1)
		GetHexDataState = 0;
}

void CSerial_DemoDlg::OnCheckSendhexdata() 
{
	// TODO: Add your control notification handler code here
	if (SendHexDataState == 0)
		SendHexDataState = 1;
	else if (SendHexDataState == 1)
		SendHexDataState = 0;
}

void CSerial_DemoDlg::StringtoHex(BYTE *GB, int glen, BYTE* SB, int* slen)
{
	int i; //遍历输入的字符串
	int a = 0; 
	char temp; //接收字符,用来判断是否为空格,若是则跳过
	char temp1,temp2; //接收一个字节的两个字符 例如EB,则temp1='E',temp2 = 'B'
	*slen = 0; //输出的16进制字符串长度
	for(i=0;i<glen;i++)
	{
		temp = GB[i];
		if(temp==' ')
			continue;
		if(a == 0)
			temp1 = GB[i];
		if(a == 1)
			temp2 = GB[i];
		a++;
		
		if(a==2)
		{
			a = 0;
			temp1 = temp1 - '0';
			if (temp1>10)
				temp1 = temp1 -7;
			temp2 = temp2 - '0';
			if (temp2>10)
				temp2 = temp2 -7;
			
			SB[*slen] = temp1*16+temp2;
			(*slen)++;
		}
	}
}

.h文件

// Serial_DemoDlg.h : header file
//
//{{AFX_INCLUDES()
#include "mscomm.h"
//}}AFX_INCLUDES

#if !defined(AFX_SERIAL_DEMODLG_H__DE508F99_1751_4DEB_A238_570FE83B6374__INCLUDED_)
#define AFX_SERIAL_DEMODLG_H__DE508F99_1751_4DEB_A238_570FE83B6374__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/
// CSerial_DemoDlg dialog

typedef unsigned short  UShort;

class CSerial_DemoDlg : public CDialog
{
// Construction
public:
	CSerial_DemoDlg(CWnd* pParent = NULL);	// standard constructor

public:
	void EnumerateSerialPorts(CUIntArray& porta, CUIntArray& portse, CUIntArray& portsu);
	UShort AddCom(CComboBox* pvect);
	long GetCommPortN(); // 获取COMBO BOX上的串口编号
	CString GetCommPortParameter(); //	获取串口参数
	void StringtoHex(BYTE *GB, int glen, BYTE* SB, int* slen);
	


// Dialog Data
	//{{AFX_DATA(CSerial_DemoDlg)
	enum { IDD = IDD_SERIAL_DEMO_DIALOG };
	CComboBox	m_COMBO_StopBit;
	CComboBox	m_StopBit;
	CComboBox	m_COMBO_DaBit;
	CComboBox	m_COMBO_CkBit;
	CComboBox	m_COMBO_ChooseSel;
	CComboBox	m_COMBO_BotRat;
	BOOL	m_GetHexData;
	BOOL	m_SendDataTime;
	BOOL	m_SendHexTime;
	CString	m_EDIT_GetData;
	CString	m_EDIT_SendData;
	int		m_EDIT_SendDataTime;
	CMSComm	m_Comm;
	int SendDataTimeState;
	int GetHexDataState;
	int SendHexDataState;
	int SendDataBata;
	long GetDataBata;
	CString	m_EDIT_GetDataBate;
	CString	m_EDIT_SendDataBate;
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CSerial_DemoDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	//{{AFX_MSG(CSerial_DemoDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg void OnButtonOpensel();
	afx_msg void OnButtonSerchsel();
	afx_msg void OnOnCommMscomm();
	afx_msg void OnButtonSenddata();
	afx_msg void OnButtonClosesel();
	afx_msg void OnCheckSenddatatime();
	afx_msg void OnTimer(UINT nIDEvent);
	afx_msg void OnButtonCleargetdata();
	afx_msg void OnButtonClearsenddata();
	afx_msg void OnCheckGethexdata();
	afx_msg void OnCheckSendhexdata();
	DECLARE_EVENTSINK_MAP()
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SERIAL_DEMODLG_H__DE508F99_1751_4DEB_A238_570FE83B6374__INCLUDED_)

Resource.h文件

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Serial_Demo.rc
//
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_SERIAL_DEMO_DIALOG          102
#define IDR_MAINFRAME                   128
#define IDC_BUTTON_SERCHSEL             1000
#define IDC_COMBO_CHOOSESEL             1001
#define IDC_COMBO_BOTRAT                1002
#define IDC_COMBO_DABIT                 1003
#define IDC_COMBO_CKBIT                 1004
#define IDC_COMBO_STOPBIT               1005
#define IDC_BUTTON_OPENSEL              1006
#define IDC_BUTTON_CLOSESEL             1007
#define IDC_EDIT_GETDATABATE            1008
#define IDC_EDIT_SENDDATABATE           1009
#define IDC_EDIT_GETDATA                1010
#define IDC_EDIT_SENDDATA               1011
#define IDC_CHECK_SENDDATATIME          1012
#define IDC_EDIT_SENDDATATIME           1013
#define IDC_CHECK_GETHEXDATA            1014
#define IDC_BUTTON_CLEARGETDATA         1015
#define IDC_CHECK_SENDHEXDATA           1016
#define IDC_BUTTON_CLEARSENDDATA        1017
#define IDC_MSCOMM1                     1018
#define IDC_BUTTON_SENDDATA             1019
#define IDC_TIMER						1020

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        130
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1020
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

到了这里,关于【用MFC写串口调试助手】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PyQt5设计好UI界面后,通过Python文件打开,控件集中在左上角问题解决方案

            在用PyQt5做GUI界面时遇到的一个问题,在QtDesigner预览的界面正常,但是转换成.py文件后show()出来的界面,控件都挤在左上角无法使用。 目录 一、问题 1.QtDesigner预览的界面正常​编辑 2.转换.py文件后通过show()方法,显示异常 二,解决方法 1.在MainWindow = QtWidgets.QM

    2024年02月04日
    浏览(37)
  • 人工智能交互系统界面设计(Tkinter界面设计)

    在现代信息化时代,图形化用户界面(Graphical User Interface, GUI)已经成为各种软件应用和设备交互的主流方式,与传统的命令行界面(CLI)相比,GUI 具有直观性、易用性、交互性、可视化和多任务处理等优势。设计良好的用户交互界面可以让用户以更加直观、友好的方式与计

    2024年01月16日
    浏览(34)
  • 【UI 设计】触摸界面设计

    触摸界面设计是一种以触摸操作为主的用户界面设计。以下是一些触摸界面设计的要点: 界面布局:设计简洁、直观的界面布局,使用户可以快速找到所需的功能和信息。避免过于拥挤的布局,保持按钮和菜单的大小适中,以便用户能够准确地点击它们。 可视化元素:使用

    2024年02月06日
    浏览(30)
  • 【HTML界面设计(二)】说说模块、登录界面

    记录很早之前写的前端界面(具体时间有点久远) 采用 适配器(Adapter)原理 来设计这款说说模板,首先看一下完整效果 这是demo样图,需要通过业务需求进行修改的部分 这一部分,就是demo代码了 效果图(因为我这个项目有二维码登录的需求,所以有一个扫描图标,但dem

    2024年02月09日
    浏览(35)
  • VOFA+ 串口调试助手

    人生如逆旅,我亦是行人。 最近看学习视频看到一位博主用了一个十分酷、之前都没怎么见过的串口调试助手,深深地被吸引了,然后去了解了一下,发现这款串口调试助手软件还挺不错的,最起码比我之前用过的都要更酷,而且适合用来显示波形,与我最近需要用到的数据

    2024年02月15日
    浏览(32)
  • python美化图形化界面设计,pythontkinter界面美化

    大家好,本文将围绕python美化图形化界面设计展开说明,pythontkinter界面美化是一个很多人都想弄明白的事情,想搞清楚python美化输出模块需要先了解以下几个事情。 PyQt,一个基于Qt的Python接口包,可以直接使用Qt的控件薯轿茄,还可以使用QSS进行界面美化,下面我简单介绍一

    2024年02月08日
    浏览(34)
  • python怎么做gui界面,python gui界面设计

    本篇文章给大家谈谈python怎么做gui界面,以及python gui界面设计,希望对各位有所帮助,不要忘了收藏本站喔。 开发图形用户界面(GUI)应用程序是Python的重要应用之一,标准库tkinter用来实现图形用户界面。 tkinter模块是Python事实上的GUI库,包含在Python的基本安装包中Python自动化

    2024年04月14日
    浏览(41)
  • Android Studio欢迎界面和登陆界面的设计(小白)

            最近学校开设了Android Studio的开发课程,跟着书上的例子和小破站的视频开启了安卓小白之旅,今天主要整理了一下\\\"欢迎界面\\\"和\\\"登陆界面\\\"的相关内容。         首先新建一个项目,按照自己的需求命名项目 新建一个类,命名为Splash  欢迎界面的页面布局 在layout中

    2024年02月10日
    浏览(56)
  • Unity 界面设计

    练习项目: unityUI 定义“UI”以及用户界面在实时 3D 体验中的作用。 学习如何使用 Unity 的 UI 系统创建交互式设置屏幕。 区分 Unity 的三种可用 UI 系统:uGUI(或 Unity UI)、IMGUI(或“立即模式”GUI)和 UI Toolkit。 在实时 3D 项目中,UI 通常是文本、按钮、复选框、滑块和切换开

    2024年03月25日
    浏览(32)
  • 【AndroidUI设计】主界面设计-Toolbar的简单使用

    描述:需要设计一个主界面,菜单通过主界面的左边界划入,实现点击跳转修改主界面内容的一个效果,并且点击非内容区域恢复原界面的一个效果。做到菜单的弹出,其实还可以加难度,通过向右滑动实现菜单的弹出。这里就作为一个思考问题,其实在我之前的几篇博客里

    2024年02月10日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包