
1、新建MFC对话框工程如下
2、给编辑框控件添加变量,其中Edit Box添加Value变量,Button添加Control变量,ID和变量分别为:
IDC_BTNOPEN() 数橘源 伍链 CButton m_cBtnOpen
IDC_BTNSEND() CButton m_cBtnSend
IDC_EDIT_RXDATA() CString m_sRXDATA
IDC_EDIT_TXDATA() CString m_sTXDATA
3、右击插入Active X控件:
右击电话图标选择“Class Wirzard”,添加变量m_comm1,添加Function:
双击两个薯态Button按钮;
代码中显示如下:
[cpp] view plain copy print?
void CMSCommTestDlg::OnBnClickedBtnopen()
{
// TODO: Add your control notification handler code here
}
void CMSCommTestDlg::OnBnClickedBtnsend()
{
// TODO: Add your control notification handler code here
}
void CMSCommTestDlg::OnOncommMscomm1()
{
// TODO: Add your message handler code here
}
void CMSCommTestDlg::OnBnClickedBtnopen(){
// TODO: Add your control notification handler code here
}
void CMSCommTestDlg::OnBnClickedBtnsend()
{
// TODO: Add your control notification handler code here
}
void CMSCommTestDlg::OnOncommMscomm1()
{
// TODO: Add your message handler code here
}
5、将上面代码补全如下:
[cpp] view plain copy print?
void CMSCommTestDlg::OnClickedBtnopen()
{
// TODO: Add your control notification handler code here
//如果端口已经开启,那么先关闭
if (m_comm1.get_PortOpen())
{
m_comm1.put_PortOpen(FALSE)
}
m_comm1.put_CommPort(3) //选择com3,可以根据具体情况更改
m_comm1.put_InBufferSize(1024) //设置输入缓冲区的大小,Bytes
m_comm1.put_OutBufferSize(1024) //设置输出缓冲区的大小,Bytes
m_comm1.put_Settings(_T("9600,n,8,1")) //波特率9600,无校验,8个数据位,停止位1
m_comm1.put_InputMode(1) //1:表示以二进制方式检索数据
m_comm1.put_RThreshold(1) //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_comm1.put_InputLen(0) //设置当前接收区长度是0
if (!m_comm1.get_PortOpen())
{
m_comm1.put_PortOpen(TRUE)
}
else
{
AfxMessageBox(_T("Can not open serial port!"))
}
m_comm1.get_Input() //先预读缓冲区以清除残留数据
UpdateData(FALSE)
}
void CMSCommTestDlg::OnClickedBtnsend()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE)
m_comm1.put_Output(COleVariant(m_sTXDATA))//发送数据
}
void CMSCommTestDlg::OnOncommMscomm1()
{
// TODO: Add your message handler code here
VARIANT variant_inp
COleSafeArray safearray_inp
LONG len, k
BYTE rxdata[2048]
CString strtemp
if (m_comm1.get_CommEvent() == 2) //事件值为2表示缓冲区内有字符
{
variant_inp = m_comm1.get_Input() //读缓冲区
safearray_inp = variant_inp //VARIANT型变量转换为ColeSafeArray型变量
len = safearray_inp.GetDim() //得到有效数据长度
for (k = 0 k < len k++)
{
safearray_inp.GetElement(&k, rxdata + k)//转换为BYTE型数组
}
for (k = 0 k < len k++) //将数组转换为CString型变量
{
BYTE bt = *(char*)(rxdata + k) //字符型
strtemp.Format(_T("%c"), bt) //将字符送入临时变量strtemp存放
m_sRXDATA += strtemp //接收到的数据放到编辑框对应的变量中
}
}
SetDlgItemText(IDC_EDIT_RXDATA, m_sRXDATA)
}
我这边有,已经成功应用于项目中!//送到窗口的消息 WPARAM 端口号
#define ON_COMM_RECEIVE WM_USER+2009
#define ON_COMM_ERROR WM_USER+2010
#define ON_COMM_CTS WM_USER+2011
#define ON_COMM_DSR WM_USER+2012
#define ON_COMM_BREAK WM_USER+2013
#define ON_COMM_TXEMPTY WM_USER+2014
#define ON_COMM_RING WM_USER+2015
#define ON_COMM_RLSD WM_USER+2016
// changed 2011.4.07 收到特定字符事件 而不是收到任何字符 EV_RXCHAR-->EV_RXFLAG
#define DEFALUT_COM_MASK_EVENT EV_RXFLAG | EV_ERR | EV_CTS | EV_DSR | EV_BREAK | EV_TXEMPTY | EV_RING | EV_RLSD
class CCom
{
public:
//------------------------------Construction-----------------------------------
//第1个参数为是否在打开串口时启动监视线程, 第2个参数为IO方式 阻塞方式(0)/ 异步重叠方式(默认)
CCom(BOOL bAutoBeginThread = TRUE, DWORD dwIOMode = FILE_FLAG_OVERLAPPED)
virtual ~CCom()
//----------------------------------Operations----------------------------------
//打开串口 缺省 9600, 8, n, 1
BOOL Open(DWORD dwPort)
//打开串口 缺省 baud_rate, 8, n, 1
BOOL Open(DWORD dwPort, DWORD dwBautRate)
//打开串口, 使用类似"9600, 8, n, 1"的设置字符串设置串口
BOOL Open(DWORD dwPort, char* szSetStr)
//读取串口 dwBufferLength个字符到 Buffer 返回实际读到的字符数 可读任意数据
DWORD Read(LPVOID Buffer, DWORD dwBufLength, DWORD dwWaitTime = 10)
//读取串口 dwBufferLength - 1 个字符到 szBuffer 返回ANSI C 模式字符串指针 适合一般字符通讯
char* ReadString(char* szBuffer, DWORD dwBufferLength, DWORD dwWaitTime = 20)
//读串口 同步应用
DWORD ReadSync(LPVOID Buffer, DWORD dwBufferLength)
//写串口 可写任意数据 "abcd" or "\x0\x1\x2"
DWORD Write(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime = 20) // changed 2011.4.1 增加了第三个默认参数
//写串口 写ANSI C 模式字符串指针
DWORD Write(const char* szBuffer)
//写串口 同步罩棚并应用
DWORD WriteSync(LPVOID Buffer, DWORD dwBufferLength)
//写串口 szBuffer 可以输出格式字符串 包含缓冲区长度物迹
DWORD Write(char* szBuffer, DWORD dwBufferLength, char* szFormat, ...)
//写串口 szBuffer 可以输出格式字符串 不检查缓冲区长度 小心溢和明出
DWORD Write(char* szBuffer, char* szFormat)
//关闭串口 同时也关闭关联线程
virtual void Close()
struct InnerLock
{
CCom* ptr
InnerLock(CCom* p) : ptr(p)
{
ptr->Lock()
}
~InnerLock()
{
ptr->UnLock()
}
}
//锁定资源
void Lock()
{
::EnterCriticalSection(&m_mutex)
}
void UnLock()
{
::LeaveCriticalSection(&m_mutex)
}
//DTR 电平控制
BOOL SetDtr(BOOL OnOrOff)
{
return IsOpen()? EscapeCommFunction(m_hComHandle, OnOrOff? SETDTR : CLRDTR) !=0 : FALSE
}
//RTS 电平控制
BOOL SetRts(BOOL OnOrOff)
{
return IsOpen()? EscapeCommFunction(m_hComHandle, OnOrOff? SETRTS : CLRRTS) != 0 : FALSE
}
BOOL SetBreak(BOOL OnOrOff)
{
return IsOpen()? EscapeCommFunction(m_hComHandle, OnOrOff? SETBREAK : CLRBREAK) != 0 : FALSE
}
//辅助线程控制 建监视线程
BOOL BeginThread()
//暂停监视线程
inline BOOL SuspendThread()
{
return IsThreadRunning()? ::SuspendThread(m_hThreadHandle) != 0xFFFFFFFF : FALSE
}
//恢复监视线程
inline BOOL ResumeThread()
{
return IsThreadRunning()? ::ResumeThread(m_hThreadHandle) != 0xFFFFFFFF : FALSE
}
//终止线程
BOOL EndThread(DWORD dwWaitTime = 100)
//----------------------------------Attributes----------------------------------
//判断串口是或打开
inline BOOL IsOpen() {return m_hComHandle != INVALID_HANDLE_VALUE}
//获得串口句炳
HANDLE GetHandle() {return m_hComHandle}
//获得串口序号
const int GetPortID() {return m_dwPort}
//获得串口全名
const char* GetPortName() {return m_szComStr}
//获得串口参数 DCB
DCB* GetState()
{
return IsOpen() &&::GetCommState(m_hComHandle, &m_DCB) == TRUE ? &m_DCB : NULL
}
//设置串口参数 DCB
BOOL SetState(DCB* pDCB = NULL)
{
return IsOpen() ? SetCommState(m_hComHandle, pDCB == NULL? &m_DCB : pDCB) == TRUE : FALSE
}
//设置串口参数:波特率,停止位,等 支持设置字符串 "9600, 8, n, 1"
BOOL SetState(char* szSetStr)
//设置串口参数:波特率,停止位,等
BOOL SetState(DWORD dwBautRate, DWORD dwByteSize = 8, DWORD dwParity = NOPARITY, DWORD dwStopBits = ONESTOPBIT)
//获得超时结构
LPCOMMTIMEOUTS GetTimeouts()
{
return IsOpen()&&::GetCommTimeouts(m_hComHandle, &m_ComTimeOuts) == TRUE ? &m_ComTimeOuts : NULL
}
//设置超时
BOOL SetTimeouts(LPCOMMTIMEOUTS lpCO)
{
return IsOpen()? ::SetCommTimeouts(m_hComHandle, lpCO) == TRUE : FALSE
}
//设置串口的I/O缓冲区大小
BOOL SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize)
{
return IsOpen()? ::SetupComm(m_hComHandle, dwInputSize, dwOutputSize) == TRUE : FALSE
}
//清除接受缓冲区
void ClearInputBuffer()
{
if(IsOpen())
PurgeComm(m_hComHandle, PURGE_RXABORT|PURGE_RXCLEAR)
}
//清除发送缓冲区
void ClearOutputBuffer()
{
if (IsOpen())
PurgeComm(m_hComHandle, PURGE_TXABORT|PURGE_TXCLEAR)
}
//关联消息的窗口句柄
inline void SetWnd(HWND hWnd)
{
assert(::IsWindow(hWnd))
m_hNotifyWnd = hWnd
}
//设定发送通知, 接受字符最小值
inline void SetNotifyNum(DWORD dwNum)
{
m_dwNotifyNum = dwNum
}
//线程是否运行
inline BOOL IsThreadRunning() {return m_hThreadHandle != NULL}
//获得线程句柄
inline HANDLE GetThread()
{
return m_hThreadHandle
}
//设置要监视的事件, 打开前设置有效
void SetMaskEvent(DWORD dwEvent = DEFALUT_COM_MASK_EVENT)
{
m_dwMaskEvent = dwEvent
}
//获得读缓冲区的字符数
int GetInputSize()
{
COMSTAT Stat
DWORD dwError
return ::ClearCommError(m_hComHandle, &dwError, &Stat) == TRUE? Stat.cbInQue : (DWORD)-1L
}
//Attributes
protected:
volatile DWORD m_dwPort //串口号
volatile HANDLE m_hComHandle //串口句柄
char m_szComStr[20] //保存Com1类似的字符串
DCB m_DCB //定义波特率,停止位,等
COMMTIMEOUTS m_ComTimeOuts //超时结构
DWORD m_dwIOMode //0,同步 默认 FILE_FLAG_OVERLAPPED 重叠I/O 异步
OVERLAPPED m_overlappedRead, m_overlappedWrite
volatile HANDLE m_hThreadHandle //辅助线程
volatile HWND m_hNotifyWnd //通知窗口
volatile DWORD m_dwNotifyNum//接受多少字节(>=m_dwNotifyNum)发送通知消息
volatile DWORD m_dwMaskEvent //监视的事件
volatile BOOL m_bRunFlag //线程运行循环标志
BOOL m_bAutoBeginThread //open() 自动BeginThread()
OVERLAPPED m_overlappedWait
protected:
//初始化
virtual void Init()
//析构
virtual void Destroy()
//绑定串口
void BindCommPort(DWORD dwPort)
//打开串口
virtual BOOL OpenCommPort()
//设置串口
virtual BOOL SetUpPort()
//---------------------------------------threads callback-----------------------------------------------------
//线程收到消息自动调用, 如窗口句柄有效, 送出消息, 包含串口编号, 均为虚函数可以在基层类中扩展
virtual DWORD ThreadFunc()
virtual void OnReceive()
virtual void OnCts()
virtual void OnDsr()
virtual void OnRing()
virtual void OnRlsd()
virtual void OnBreak()
virtual void OnTxEmpty()
virtual void OnError()
private:
CCom(const CCom&)
CCom&operator = (const CCom&)
CRITICAL_SECTION m_mutex
#ifdef _MT
static UINT APIENTRY CommThreadProc(LPVOID lpPara)
#else
static DWORD WINAPI CommThreadProc(LPVOID lpPara)
#endif
{
return ((CCom*)lpPara)->ThreadFunc()
}
}
#endif
#endif // !defined(AFX_COM_H__5427C4C8_CC6C_4135_9607_AF8BF6C1C679__INCLUDED_)
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)