📄 sercomv5view.cpp
字号:
// SerComV5View.cpp : implementation of the CSerComV5View class
//
#include "stdafx.h"
#include "SerComV5.h"
#include "SerComV5Doc.h"
#include "SerComV5View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSerComV5View
IMPLEMENT_DYNCREATE(CSerComV5View, CFormView)
BEGIN_MESSAGE_MAP(CSerComV5View, CFormView)
//{{AFX_MSG_MAP(CSerComV5View)
ON_COMMAND(ID_FILE_CONNECT, OnFileConnect)
ON_COMMAND(ID_FILE_DISCONNECT, OnFileDisconnect)
ON_UPDATE_COMMAND_UI(ID_FILE_CONNECT, OnUpdateFileConnect)
ON_BN_CLICKED(IDC_SEND, OnSend)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSerComV5View construction/destruction
CSerComV5View::CSerComV5View()
: CFormView(CSerComV5View::IDD)
{
//{{AFX_DATA_INIT(CSerComV5View)
m_sSendData = _T("");
//}}AFX_DATA_INIT
// TODO: add construction code here
}
CSerComV5View::~CSerComV5View()
{
}
void CSerComV5View::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSerComV5View)
DDX_Control(pDX, IDC_RECVDATA, m_listRecvData);
DDX_Text(pDX, IDC_SENDDATA, m_sSendData);
//}}AFX_DATA_MAP
}
BOOL CSerComV5View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CFormView::PreCreateWindow(cs);
}
void CSerComV5View::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
}
/////////////////////////////////////////////////////////////////////////////
// CSerComV5View printing
BOOL CSerComV5View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CSerComV5View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CSerComV5View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
void CSerComV5View::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/)
{
// TODO: add customized printing code here
}
/////////////////////////////////////////////////////////////////////////////
// CSerComV5View diagnostics
#ifdef _DEBUG
void CSerComV5View::AssertValid() const
{
CFormView::AssertValid();
}
void CSerComV5View::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
CSerComV5Doc* CSerComV5View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSerComV5Doc)));
return (CSerComV5Doc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSerComV5View message handlers
// 串口句柄
HANDLE hCOM1;
HANDLE hCOM2;
// 数据接收线程
UINT ReadProc(LPVOID lpVoid )
{
// 得到视指针
CSerComV5View* pView = (CSerComV5View*)lpVoid;
if (pView == NULL)
return -1;
// 中间变量
DWORD dwErrorMask;
DWORD dwEvtMask = 0;
DWORD dwActRead = 0;
DWORD dwPoint = 0;
char Buf[4096];
// 串口状态结构对象
COMSTAT comstat;
// 异步结构对象
OVERLAPPED ov;
ov.Internal = 0;
ov.InternalHigh = 0;
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// 设置事件驱动的类型
if (!SetCommMask(hCOM2, EV_RXCHAR))
return -1;
while (true)
{
// 等待接收事件
WaitCommEvent(hCOM2, &dwEvtMask, NULL);
if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
// 确定接收缓冲中处于等待的字节数
ClearCommError(hCOM2, &dwErrorMask, &comstat);
if (comstat.cbInQue > 0)
{
// 异步读取数据
if (!ReadFile(hCOM2, Buf + dwPoint, comstat.cbInQue, &dwActRead, &ov))
{
if (GetLastError() == ERROR_IO_PENDING)
{
// 检测数据是否接收完毕
while (!GetOverlappedResult(hCOM2, &ov, &dwActRead, FALSE))
{
// 数据尚未接收完毕
if (GetLastError() == ERROR_IO_INCOMPLETE)
continue;
}
// 对接收到的数据进行处理
if (dwActRead > 0)
{
// 判断一条数据是否接受完毕
if (Buf[dwPoint + dwActRead - 1] == 13)
{
// 将接收到的数据插入到列表控件
Buf[dwPoint + dwActRead - 1] = 0;
pView->m_listRecvData.InsertString(0, CString(Buf));
// 复位
memset(Buf, 0, sizeof(Buf));
dwPoint = 0;
}
else
{
// 修正接收缓存指针
dwPoint += dwActRead;
}
}
}
}
else
{
// 对接收到的数据进行处理
if (dwActRead > 0)
{
// 判断一条数据是否接受完毕
if (Buf[dwPoint + dwActRead - 1] == 13)
{
// 将接收到的数据插入到列表控件
Buf[dwPoint + dwActRead - 1] = 0;
pView->m_listRecvData.InsertString(0, CString(Buf));
// 复位
memset(Buf, 0, sizeof(Buf));
dwPoint = 0;
}
else
{
// 修正接收缓存指针
dwPoint += dwActRead;
}
}
// 手动复位
ResetEvent(ov.hEvent);
}
}
}
}
return 1;
}
BOOL CSerComV5View::OnFileConnect()
{
// TODO: Add your command handler code here
//设备控制块结构对象设置
DCB dcb1, dcb2;
//超时结构对象
COMMTIMEOUTS CommTimeOuts;
//对COM1进行设置
hCOM1 = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL ); // 重叠方式
if(hCOM1==INVALID_HANDLE_VALUE)
{
return FALSE;
}
if(!GetCommState(hCOM1, &dcb1))
{
return FALSE;
}
//dcb.fBinary=TRUE;
dcb1.BaudRate=9600; // 波特率
dcb1.ByteSize=1; // 每字节位数
//dcb.fParity=TRUE;
dcb1.Parity=NOPARITY;
dcb1.StopBits=ONESTOPBIT;
//配置串口设置
SetCommState(hCOM1, &dcb1);
//超时设置
// 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作
CommTimeOuts.ReadIntervalTimeout=MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier=0;
CommTimeOuts.ReadTotalTimeoutConstant=0;
/* 设置写超时以指定WriteComm成员函数中的
GetOverlappedResult函数的等待时间*/
CommTimeOuts.WriteTotalTimeoutMultiplier=50;
CommTimeOuts.WriteTotalTimeoutConstant=2000;
SetCommTimeouts(hCOM1, &CommTimeOuts);
//设置缓冲区大小
SetupComm( hCOM1, 4096, 4096);
//对COM2进行设置
hCOM2 = CreateFile( "COM2", GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL ); // 重叠方式
if(hCOM2==INVALID_HANDLE_VALUE)
{
return FALSE;
}
if(!GetCommState(hCOM2, &dcb2))
{
return FALSE;
}
//dcb.fBinary=TRUE;
dcb2.BaudRate=9600; // 波特率
dcb2.ByteSize=1; // 每字节位数
//dcb.fParity=TRUE;
dcb2.Parity=NOPARITY;
dcb2.StopBits=ONESTOPBIT;
//配置串口设置
SetCommState(hCOM2, &dcb2);
//超时设置
// 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作
CommTimeOuts.ReadIntervalTimeout=MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier=0;
CommTimeOuts.ReadTotalTimeoutConstant=0;
/* 设置写超时以指定WriteComm成员函数中的
GetOverlappedResult函数的等待时间*/
CommTimeOuts.WriteTotalTimeoutMultiplier=50;
CommTimeOuts.WriteTotalTimeoutConstant=2000;
SetCommTimeouts(hCOM2, &CommTimeOuts);
//设置缓冲区大小
SetupComm( hCOM2, 4096, 4096);
// 开启数据接收线程
AfxBeginThread(ReadProc, this);
return TRUE;
}
BOOL CSerComV5View::OnFileDisconnect()
{
// TODO: Add your command handler code here
// 释放资源
if (hCOM1!= INVALID_HANDLE_VALUE)
{
CloseHandle(hCOM1);
hCOM1 = INVALID_HANDLE_VALUE;
}
if (hCOM2!= INVALID_HANDLE_VALUE)
{
CloseHandle(hCOM2);
hCOM2 = INVALID_HANDLE_VALUE;
}
return CFormView::DestroyWindow();
}
void CSerComV5View::OnUpdateFileConnect(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
}
void CSerComV5View::OnSend()
{
// TODO: Add your control notification handler code here
// 确保串口已打开
if (hCOM1 == INVALID_HANDLE_VALUE)
return;
// 更新数据
UpdateData(TRUE);
// 异步结构对象
OVERLAPPED ov;
ov.Internal = 0;
ov.InternalHigh = 0;
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// 发送数据
DWORD dwActWrite;
if (!WriteFile(hCOM1, m_sSendData + CString(13), m_sSendData.GetLength() + 1, &dwActWrite, &ov))
{
if (GetLastError() == ERROR_IO_PENDING)
{
// 检测数据是否发送完毕
while (!GetOverlappedResult(hCOM1, &ov, &dwActWrite, FALSE))
{
// 数据尚未发送完毕
if (GetLastError() == ERROR_IO_INCOMPLETE)
continue;
}
}
}
// 手动复位异步事件
ResetEvent(ov.hEvent);
// 清除发送数据
m_sSendData = "";
UpdateData(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -