?? winceserialdlg.cpp
字號(hào):
// 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;
// 得到超時(shí)參數(shù)
GetCommTimeouts(hPort, &CommTimeouts);
// 改變COMMTIMEOUTS結(jié)構(gòu)設(shè)置
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
// 設(shè)置端口超時(shí)值
if (!SetCommTimeouts(hPort, &CommTimeouts))
{
// 不能設(shè)置超時(shí)值
//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);
// 得到端口的默認(rèn)設(shè)置信息
GetCommState(hPort, &PortDCB);
// 改變DCB結(jié)構(gòu)設(shè)置
PortDCB.BaudRate = 9600; // 波特率
PortDCB.fBinary = TRUE; // Win32不支持非二進(jìn)制串行傳輸模式,必須為TRUE
PortDCB.fParity = TRUE; // 啟用奇偶校驗(yàn)
PortDCB.fOutxCtsFlow = TRUE; // 串行端口的輸出由CTS線控制
PortDCB.fOutxDsrFlow = FALSE; // 關(guān)閉串行端口的DSR流控制
PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // 啟用DTR線
PortDCB.fDsrSensitivity = FALSE; // 如果設(shè)為TRUE將忽略任何輸入的字節(jié),除非DSR線被啟用
//PortDCB.fTXContinueOnXoff = TRUE; // 當(dāng)為TRUE時(shí),如果接收緩沖區(qū)已滿且驅(qū)動(dòng)程序已
// 傳送XOFF字符,將使驅(qū)動(dòng)程序停止傳輸字符
PortDCB.fTXContinueOnXoff = FALSE;
PortDCB.fOutX = FALSE; // 設(shè)為TRUE指定XON/XOFF控制被用于控制串行輸出
PortDCB.fInX = FALSE; // 設(shè)為TRUE指定XON/XOFF控制被用于控制串行輸入
PortDCB.fErrorChar = FALSE; // WINCE串行驅(qū)動(dòng)程序的默認(rèn)執(zhí)行將忽略這個(gè)字段
PortDCB.fNull = FALSE; // 設(shè)為TRUE將使串行驅(qū)動(dòng)程序忽略收到的空字節(jié)
PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // 啟用RTS線
PortDCB.fAbortOnError = FALSE; // WINCE串行驅(qū)動(dòng)程序的默認(rèn)執(zhí)行將忽略這個(gè)字段
PortDCB.ByteSize = 8; // 每字節(jié)的位數(shù)
PortDCB.Parity = NOPARITY; // 無(wú)奇偶校驗(yàn)
PortDCB.StopBits = ONESTOPBIT; // 每字節(jié)一位停止位
// 根據(jù)DCB結(jié)構(gòu)配置端口
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)
{
// 設(shè)置連接屬性為FALSE
m_bConnected = FALSE;
// 結(jié)束線程中WaitCommEvent的等待
SetCommMask(hPort, 0);
// 阻塞至線程停止
if (hReadThread)
{
TerminateThread(hReadThread, 0);
CloseHandle(hReadThread);
}
// 清除端口上指定信號(hào)的狀態(tài)
EscapeCommFunction(hPort, CLRDTR);
EscapeCommFunction(hPort, CLRRTS);
// 清除驅(qū)動(dòng)程序內(nèi)部的發(fā)送和接收隊(duì)列
PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
// 關(guān)閉串口
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;
// 寫入數(shù)據(jù)
fWriteState = WriteFile(hPort, buf, dwCharToWrite * sizeof(TCHAR),
&dwBytesWritten, NULL);
if (!fWriteState)
{
// 不能寫數(shù)據(jù)
//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)
{
// 等待串口的事件發(fā)生
WaitCommEvent(hPort, &dwCommModemStatus, 0);
if (dwCommModemStatus & EV_RXCHAR)
{
ClearCommError(hPort, &dwErrorFlags, &ComStat);
// cbInQue返回在串行驅(qū)動(dòng)程序輸入隊(duì)列中的字符數(shù)
dwLength = ComStat.cbInQue;
if (dwLength > 0)
{
// 從串口讀取數(shù)據(jù)
TCHAR *buf = new TCHAR[256];
fReadState = ReadFile(hPort, buf, dwLength, &dwLength, NULL);
if (!fReadState)
{
// 不能從串口讀取數(shù)據(jù)
MessageBox(NULL, TEXT("Error in read from serial port"),
TEXT("Read Error"), MB_OK);
}
else
{
// 把數(shù)據(jù)賦值給全局變量
strInChar = buf;
((CEdit *)lpvoid)->SetSel(-1, -1); // 自動(dòng)滾屏
((CEdit *)lpvoid)->ReplaceSel(strInChar); // 自動(dòng)換行
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;
}
// 打開(kāi)串口
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) // 如果打開(kāi)端口出錯(cuò), 返回FALSE
{
// 不能打開(kāi)端口
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;
}
// 指定端口監(jiān)測(cè)的事件集
SetCommMask(hPort, EV_RXCHAR);
// 分配設(shè)備緩沖區(qū)
SetupComm(hPort, 512, 512);
// 初始化緩沖區(qū)中的信息
PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
// 配置串行端口
if (!InitDCB())
return FALSE;
// 設(shè)置端口超時(shí)值
if (!InitCommTimeouts())
return FALSE;
// 設(shè)置端口上指定信號(hào)的狀態(tài)
// SETDTR: 發(fā)送DTR (data-terminal-ready)信號(hào)
// SETRTS: 發(fā)送RTS (request-to-send)信號(hào)
EscapeCommFunction(hPort, SETDTR);
EscapeCommFunction(hPort, SETRTS);
// 創(chuàng)建一個(gè)從串口讀取數(shù)據(jù)的線程
if (hReadThread = CreateThread(NULL, 0, ReadPortThread, m_ceReadSerial, 0, &dwThreadID))
{
}
else
{
// 不能創(chuàng)建線程
//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對(duì)象
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(""));
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -