📄 winceserialdlg.cpp
字号:
// WinCESerialDlg.cpp : implementation file
//
#include "stdafx.h"
#include "WinCESerial.h"
#include "WinCESerialDlg.h"
#include <atlstr.h>
using namespace ATL;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
HANDLE hPort = INVALID_HANDLE_VALUE;
CString strInChar;
// CWinCESerialDlg dialog
CWinCESerialDlg::CWinCESerialDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWinCESerialDlg::IDD, pParent)
, m_iport(0)
, m_com1state(_T(""))
, m_com2state(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CWinCESerialDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_READ, m_ceReadSerial);
DDX_Control(pDX, IDC_EDIT_SEND, m_ceSendserial);
DDX_CBIndex(pDX, IDC_COMBO_SERIAL_NAME, m_iport);
DDX_Text(pDX, IDC_STATIC_COM1_STATE, m_com1state);
DDX_Text(pDX, IDC_STATIC_COM2_STATE, m_com2state);
}
BEGIN_MESSAGE_MAP(CWinCESerialDlg, CDialog)
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
ON_WM_SIZE()
#endif
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_SERIAL_OPEN, &CWinCESerialDlg::OnBnClickedButtonSerialOpen)
ON_BN_CLICKED(IDC_BUTTON_SERIAL_WRITE, &CWinCESerialDlg::OnBnClickedButtonSerialWrite)
ON_BN_CLICKED(IDC_BUTTON_SERIAL_CLOSE, &CWinCESerialDlg::OnBnClickedButtonSerialClose)
ON_BN_CLICKED(IDC_BUTTON_CLEAN_DATA, &CWinCESerialDlg::OnBnClickedButtonCleanData)
END_MESSAGE_MAP()
// CWinCESerialDlg message handlers
BOOL CWinCESerialDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 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
return TRUE; // return TRUE unless you set the focus to a control
}
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CWinCESerialDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
if (AfxIsDRAEnabled())
{
DRA::RelayoutDialog(
AfxGetResourceHandle(),
this->m_hWnd,
DRA::GetDisplayMode() != DRA::Portrait ?
MAKEINTRESOURCE(IDD_WINCESERIAL_DIALOG_WIDE) :
MAKEINTRESOURCE(IDD_WINCESERIAL_DIALOG));
}
}
#endif
BOOL CWinCESerialDlg::InitCommTimeouts()
{
COMMTIMEOUTS CommTimeouts;
DWORD dwError;
// 得到超时参数
GetCommTimeouts(hPort, &CommTimeouts);
// 改变COMMTIMEOUTS结构设置
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
// 设置端口超时值
if (!SetCommTimeouts(hPort, &CommTimeouts))
{
// 不能设置超时值
//MessageBox(NULL, TEXT("Unable to set the time-out parameters"),
// TEXT("Error"), MB_OK);
AfxMessageBox(TEXT("Unable to set the time-out parameters"),
MB_OK, MB_ICONERROR);
dwError = GetLastError();
return FALSE;
}
return TRUE;
}
BOOL CWinCESerialDlg::InitDCB()
{
DCB PortDCB;
DWORD dwError;
PortDCB.DCBlength = sizeof(DCB);
// 得到端口的默认设置信息
GetCommState(hPort, &PortDCB);
// 改变DCB结构设置
PortDCB.BaudRate = 9600; // 波特率
PortDCB.fBinary = TRUE; // Win32不支持非二进制串行传输模式,必须为TRUE
PortDCB.fParity = TRUE; // 启用奇偶校验
PortDCB.fOutxCtsFlow = TRUE; // 串行端口的输出由CTS线控制
PortDCB.fOutxDsrFlow = FALSE; // 关闭串行端口的DSR流控制
PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // 启用DTR线
PortDCB.fDsrSensitivity = FALSE; // 如果设为TRUE将忽略任何输入的字节,除非DSR线被启用
//PortDCB.fTXContinueOnXoff = TRUE; // 当为TRUE时,如果接收缓冲区已满且驱动程序已
// 传送XOFF字符,将使驱动程序停止传输字符
PortDCB.fTXContinueOnXoff = FALSE;
PortDCB.fOutX = FALSE; // 设为TRUE指定XON/XOFF控制被用于控制串行输出
PortDCB.fInX = FALSE; // 设为TRUE指定XON/XOFF控制被用于控制串行输入
PortDCB.fErrorChar = FALSE; // WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.fNull = FALSE; // 设为TRUE将使串行驱动程序忽略收到的空字节
PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // 启用RTS线
PortDCB.fAbortOnError = FALSE; // WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.ByteSize = 8; // 每字节的位数
PortDCB.Parity = NOPARITY; // 无奇偶校验
PortDCB.StopBits = ONESTOPBIT; // 每字节一位停止位
// 根据DCB结构配置端口
if (!SetCommState(hPort, &PortDCB))
{
// 不能配置串行端口
//MessageBox(NULL, TEXT("Unable to configure the serial port"),
// TEXT("Error"), MB_OK);
AfxMessageBox(TEXT("Unable to configure the serial port"),
MB_OK, MB_ICONERROR);
dwError = GetLastError();
return FALSE;
}
return TRUE;
}
BOOL CWinCESerialDlg::ClosePort(HANDLE hCommPort)
{
if (hCommPort != INVALID_HANDLE_VALUE)
{
// 设置连接属性为FALSE
m_bConnected = FALSE;
// 结束线程中WaitCommEvent的等待
SetCommMask(hPort, 0);
// 阻塞至线程停止
if (hReadThread)
{
TerminateThread(hReadThread, 0);
CloseHandle(hReadThread);
}
// 清除端口上指定信号的状态
EscapeCommFunction(hPort, CLRDTR);
EscapeCommFunction(hPort, CLRRTS);
// 清除驱动程序内部的发送和接收队列
PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
// 关闭串口
CloseHandle(hCommPort);
hCommPort = INVALID_HANDLE_VALUE;
hPort = INVALID_HANDLE_VALUE;
return TRUE;
}
else
{
return TRUE;
}
}
DWORD CWinCESerialDlg::WritePort(TCHAR *buf, DWORD dwCharToWrite)
{
BOOL fWriteState;
DWORD dwBytesWritten;
// 写入数据
fWriteState = WriteFile(hPort, buf, dwCharToWrite * sizeof(TCHAR),
&dwBytesWritten, NULL);
if (!fWriteState)
{
// 不能写数据
//MessageBox(NULL, TEXT("Can't Write String to Comm"),
// TEXT("Error"), MB_OK);
AfxMessageBox(TEXT("Can't Write String to Comm"),
MB_OK, MB_ICONERROR);
dwBytesWritten = 0;
}
return dwBytesWritten;
}
DWORD WINAPI ReadPortThread(LPVOID lpvoid)
{
BOOL fReadState;
DWORD dwCommModemStatus;
DWORD dwLength;
COMSTAT ComStat;
DWORD dwErrorFlags;
while (hPort != INVALID_HANDLE_VALUE)
{
// 等待串口的事件发生
WaitCommEvent(hPort, &dwCommModemStatus, 0);
if (dwCommModemStatus & EV_RXCHAR)
{
ClearCommError(hPort, &dwErrorFlags, &ComStat);
// cbInQue返回在串行驱动程序输入队列中的字符数
dwLength = ComStat.cbInQue;
if (dwLength > 0)
{
// 从串口读取数据
TCHAR *buf = new TCHAR[256];
fReadState = ReadFile(hPort, buf, dwLength, &dwLength, NULL);
if (!fReadState)
{
// 不能从串口读取数据
MessageBox(NULL, TEXT("Error in read from serial port"),
TEXT("Read Error"), MB_OK);
}
else
{
// 把数据赋值给全局变量
strInChar = buf;
((CEdit *)lpvoid)->SetSel(-1, -1); // 自动滚屏
((CEdit *)lpvoid)->ReplaceSel(strInChar); // 自动换行
TRACE(_T("read serial data = %s\n"), strInChar);
}
delete[] buf;
}
}
GetCommModemStatus(hPort, &dwCommModemStatus);
}
return 0;
}
BOOL CWinCESerialDlg::OpenPort(LPTSTR lpszPortName)
{
DWORD dwError, dwThreadID;
if (hPort != INVALID_HANDLE_VALUE)
{
return FALSE;
}
// 打开串口
if (m_iport=0)
{
lpszPortName ==_T("COM1");
}
else lpszPortName ==_T("COM2");
hPort = CreateFile(lpszPortName, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if (hPort == INVALID_HANDLE_VALUE) // 如果打开端口出错, 返回FALSE
{
// 不能打开端口
CString strError;
strError.Format(_T("Unable to open %s, Error No.=%d"),
lpszPortName, GetLastError());
//MessageBox(NULL, strError, TEXT("Error"), MB_OK);
AfxMessageBox(strError, MB_OK, MB_ICONERROR);
return FALSE;
}
// 指定端口监测的事件集
SetCommMask(hPort, EV_RXCHAR);
// 分配设备缓冲区
SetupComm(hPort, 512, 512);
// 初始化缓冲区中的信息
PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
// 配置串行端口
if (!InitDCB())
return FALSE;
// 设置端口超时值
if (!InitCommTimeouts())
return FALSE;
// 设置端口上指定信号的状态
// SETDTR: 发送DTR (data-terminal-ready)信号
// SETRTS: 发送RTS (request-to-send)信号
EscapeCommFunction(hPort, SETDTR);
EscapeCommFunction(hPort, SETRTS);
// 创建一个从串口读取数据的线程
if (hReadThread = CreateThread(NULL, 0, ReadPortThread, m_ceReadSerial, 0, &dwThreadID))
{
}
else
{
// 不能创建线程
//MessageBox(NULL, TEXT("Unable to create the read thread"),
// TEXT("Error"), MB_OK);
AfxMessageBox(TEXT("Unable to create the read thread"),
MB_OK, MB_ICONERROR);
dwError = GetLastError();
return FALSE;
}
m_bConnected = TRUE;
return TRUE;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
if (m_iport = 0 && hPort != INVALID_HANDLE_VALUE)
{
m_com1state == _T("ON");
m_com2state == _T("OFF");
if (m_iport == 1 && hPort != INVALID_HANDLE_VALUE)
{
m_com1state == _T("OFF");
m_com2state == _T("ON");
}
else
m_com1state == _T("OFF");
m_com2state == _T("OFF");
}
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
}
void CWinCESerialDlg::OnBnClickedButtonSerialOpen()
{
// TODO: Add your control notification handler code here
OpenPort(_T("COM1:"));
}
void CWinCESerialDlg::OnBnClickedButtonSerialWrite()
{
// TODO: Add your control notification handler code here
/*
TCHAR tcBuf[64];
int len = 0;
wsprintf(tcBuf, _T("Test serial"));
len = _tcslen(tcBuf);
TRACE(_T("len = %d.\n"), len);
WritePort(tcBuf, len);*/
CString strSend = _T("");
m_ceSendserial.GetWindowText(strSend); //m_SendDataEdit:Edit控件的CEdit对象
WritePort((LPTSTR)(LPCTSTR)strSend,strSend.GetLength());
}
void CWinCESerialDlg::OnBnClickedButtonSerialClose()
{
// TODO: Add your control notification handler code here
if (hPort != INVALID_HANDLE_VALUE)
ClosePort(hPort);
}
void CWinCESerialDlg::OnBnClickedButtonCleanData()
{
// TODO: Add your control notification handler code here
//m_ceSendserial = _T("");
//m_ceReadSerial = _T("");
//UpdateData(false);
m_ceSendserial.SetWindowText(_T(""));
m_ceReadSerial.SetWindowText(_T(""));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -