📄 commdlg.cpp
字号:
// CommDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Comm.h"
#include "CommDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////
/////////////////////////////////////
DCB dcb; //编程配置串口结构
HANDLE hCom; //句柄
DWORD dwError,dwEvtMask,dwEvent;
BOOL fSuccess;//判断是否成功
OVERLAPPED o;
COMMPROP CommProp; //串口信息结构,不可更改
COMMTIMEOUTS timeouts; //定义超时设置结构
COMSTAT cs;
BOOL test=TRUE;
char input[1000];
CString receiveData,sendData;
HWND hWndUpdate;
int t=50;
/////////////////////////////////////////////////////////////////////////////
// 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()
/////////////////////////////////////////////////////////////////////////////
// CCommDlg dialog
CCommDlg::CCommDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCommDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCommDlg)
m_sendData = _T("");
m_receiveData = _T("");
m_sleepTime = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCommDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCommDlg)
DDX_Text(pDX, IDC_EDIT1, m_sendData);
DDX_Text(pDX, IDC_EDIT2, m_receiveData);
DDX_Text(pDX, IDC_EDIT3, m_sleepTime);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCommDlg, CDialog)
//{{AFX_MSG_MAP(CCommDlg)
ON_WM_SYSCOMMAND()
ON_WM_DESTROY()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnSend)
ON_BN_CLICKED(IDC_BUTTON2, OnReceive)
ON_BN_CLICKED(IDC_BUTTON3, OnCommCfgDlg)
ON_MESSAGE(WM_USERUPDATE,OnUserUpdate)
ON_BN_CLICKED(IDC_BUTTON4, OnSleepTime)
ON_BN_CLICKED(IDC_BUTTON5, OnRTSON)
ON_BN_CLICKED(IDC_BUTTON6, OnRTSOFF)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCommDlg message handlers
BOOL CCommDlg::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
//////////////////////////////////////////////////////////////
//打开COM2口
hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,//访问类型可读写
0,//独占串口
NULL,//无安全属性
OPEN_EXISTING,//打开已存在的串口
FILE_FLAG_OVERLAPPED,//异步串口
NULL);//模块句柄为空
if(hCom==INVALID_HANDLE_VALUE) //检测打开是否成功。
{
dwError=GetLastError();
MessageBox("Error");
}
SetupComm(hCom,1024,1024); //设置接收,发送缓冲区各1024字节
GetCommProperties(hCom,&CommProp); //获取串口信息
////////////////定义串口//////////////////////////////////
//////获取DCB结构
fSuccess=GetCommState(hCom,&dcb);
if(!fSuccess)
MessageBox("获取DCB结构错误!");
//检测串口是否支持19200的波特率
if(CommProp.dwSettableBaud&BAUD_19200)
dcb.BaudRate=19200; //定义19200的波特率
dcb.ByteSize=8; //定义串口的数据位数8
dcb.Parity=NOPARITY; //无奇偶校验
dcb.StopBits=ONESTOPBIT;//一位停止位
dcb.EvtChar=0x7e; //定义当接收此字符时,产生一事件
fSuccess=SetCommState(hCom,&dcb);//设置串口
if(!fSuccess) //检测串口DCB结构设置是否正确
MessageBox("DCB结构设置错误!");
//////////////////超时设定///////////////////////////////////
GetCommTimeouts(hCom,&timeouts);
timeouts.ReadIntervalTimeout=MAXDWORD;//读区间超时设定
timeouts.ReadTotalTimeoutConstant=1000;
timeouts.WriteTotalTimeoutConstant=1000;
SetCommTimeouts(hCom,&timeouts);
//////////////////////////////////////////////////////////////
m_sleepTime=t;
UpdateData(FALSE);
OnReceive();
return TRUE; // return TRUE unless you set the focus to a control
}
void CCommDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CCommDlg::OnDestroy()
{
WinHelp(0L, HELP_QUIT);
CDialog::OnDestroy();
}
// 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 CCommDlg::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 CCommDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
///////////////////////////////////////////////////////////////
////////////////TimeProc定时线程///////////////////////////////
/*UINT TimeProc(LPVOID param)
{
::Sleep(5000);//延时0.5秒
if(test==FALSE)
{
SetCommMask(hCom,0); //取消读串口通讯等待事件
PurgeComm(hCom,PURGE_RXCLEAR);
}
return 0;
}
*/
///////////////////ReadProc读线程///////////////////////
UINT ReadProc(LPVOID param)
{
unsigned long nBytesRead;
while(test)
{
//设置通信检测事件。检测到。
SetCommMask(hCom,EV_RXCHAR);//EV_RXFLAG);
// AfxMessageBox("等待通信事件!");
//检测通信事件。
if(WaitCommEvent(hCom,&dwEvent,NULL))
{
::Sleep(t);
// AfxMessageBox("准备读串口!");
//获取缓冲区字节数。
ClearCommError(hCom,&dwError,&cs);
if(/*(dwEvent&EV_RXCHAR)&&*/cs.cbInQue)
{
// AfxMessageBox("读串口!");
//读串口
if(!ReadFile(hCom,input,cs.cbInQue,
&nBytesRead,NULL))
{
// AfxMessageBox("读串口失败!");
return 0;
}
else
{
// AfxMessageBox("读串口成功!");
receiveData=CString(input,nBytesRead);
char stest[2];
sprintf(stest,"%d",nBytesRead);
// AfxMessageBox(receiveData);
::PostMessage(hWndUpdate,WM_USERUPDATE,0,0);
}
}
}
PurgeComm(hCom,PURGE_RXCLEAR);
}
return 1;
}
///////////////////////////////////////////////////////////////
void CCommDlg::OnSend()
{
// TODO: Add your control notification handler code here
unsigned long nToWrite;
UpdateData();
PurgeComm(hCom,PURGE_TXCLEAR);//清发送缓冲区。
PurgeComm(hCom,PURGE_RXCLEAR);//清接受缓冲区。
//::MessageBox((HWND)param,"正在写串口","写串口",MB_OK);
WriteFile(hCom,m_sendData,m_sendData.GetLength(),&nToWrite,NULL);
PurgeComm(hCom,PURGE_TXCLEAR);
}
void CCommDlg::OnReceive()
{
// TODO: Add your control notification handler code here
//定义四个句柄,用于读线程,写线程,定时线程,反馈函数。
HWND hWndread=GetSafeHwnd();
// HWND hWndTime=GetSafeHwnd();
hWndUpdate=GetSafeHwnd();
//test=FALSE;
//启动读线程.
AfxBeginThread(ReadProc,hWndread,THREAD_PRIORITY_NORMAL);
//启动定时线程.
// AfxBeginThread(TimeProc,hWndTime,THREAD_PRIORITY_NORMAL);
}
//OnUserUpDate 处理反馈信息
LONG CCommDlg::OnUserUpdate(WPARAM wParam,LPARAM lParam)
{
//等待读线程完毕,或超出定时。
m_receiveData=receiveData;
UpdateData(FALSE);
return 0;
}
void CCommDlg::OnCommCfgDlg()
{
// TODO: Add your control notification handler code here
COMMCONFIG cc;
cc.dcb=dcb;
if(!CommConfigDialog("com2",GetSafeHwnd(),&cc))
return;
dcb=cc.dcb;
SetCommState(hCom,&dcb);
}
void CCommDlg::OnSleepTime()
{
// TODO: Add your control notification handler code here
UpdateData();
t=m_sleepTime;
}
void CCommDlg::OnRTSON()
{
// TODO: Add your control notification handler code here
/*
CLRDTR DTR置OFF
CLRRTS RTS置OFF
SETDTR DTR置ON
SETRTS RTS置ON
SETXOFF 模拟XOFF字符的接收
SETXON 模拟XON字符的接收
SETBREAK 在发送中产生一个中止(与SetCommBreak)
CLRBREAK 在发送中清除中止(与ClearCommBreak)
*/
EscapeCommFunction(hCom,SETRTS);
}
void CCommDlg::OnRTSOFF()
{
// TODO: Add your control notification handler code here
EscapeCommFunction(hCom,CLRRTS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -