?? serialdlg.cpp
字號:
// SerialDlg.cpp : 實現(xiàn)文件
//
#include "stdafx.h"
#include "Serial.h"
#include "SerialDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSerialDlg 對話框
CSerialDlg::CSerialDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSerialDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSerialDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX,IDC_CLOSE_BUTTON ,ButClose);
DDX_Control(pDX,IDC_OPEN_BUTTON ,ButOpen);
DDX_Control(pDX,IDC_SEND_BUTTON ,ButSend);
DDX_Text(pDX,IDC_SEND ,strSendEdit);
}
BEGIN_MESSAGE_MAP(CSerialDlg, CDialog)
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
ON_WM_SIZE()
#endif
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_OPEN_BUTTON, OnOpenCom)
ON_BN_CLICKED(IDC_CLOSE_BUTTON, OnCloseCom)
ON_BN_CLICKED(IDC_SEND_BUTTON, OnSend)
ON_WM_DESTROY()
END_MESSAGE_MAP()
// CSerialDlg 消息處理程序
BOOL CSerialDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動
// 執(zhí)行此操作
SetIcon(m_hIcon, TRUE); // 設置大圖標
SetIcon(m_hIcon, FALSE); // 設置小圖標
// TODO: 在此添加額外的初始化代碼
strRecDisp=_T("");
CenterWindow(GetDesktopWindow());
hComm = INVALID_HANDLE_VALUE; /* 串口操作句柄無效 */
ExitThreadEvent=NULL; /* 關閉線程事件句柄無效*/
ButClose.EnableWindow(FALSE); /* "關閉串口"按鍵無效 */
UpdateData(FALSE); /*把變量的值傳給控件*/
return TRUE; // 除非將焦點設置到控件,否則返回 TRUE
}
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CSerialDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
DRA::RelayoutDialog(
AfxGetInstanceHandle(),
this->m_hWnd,
DRA::GetDisplayMode() != DRA::Portrait ?
MAKEINTRESOURCE(IDD_SERIAL_DIALOG_WIDE) :
MAKEINTRESOURCE(IDD_SERIAL_DIALOG));
}
#endif
BOOL CSerialDlg::OpenPort(LPCTSTR Port, int BaudRate, int DataBits, int StopBits, int Parity)
{
COMMTIMEOUTS CommTimeOuts; //創(chuàng)建超時變量參數
DWORD error; //獲得錯誤代碼
hComm = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(hComm == INVALID_HANDLE_VALUE)
{
error=GetLastError();
MessageBox(_T("無法打開端口或端口已打開!請檢查是否已被占用."));
return FALSE;
}
GetCommState(hComm, &dcb); /* 讀取串口的DCB */
dcb.BaudRate= BaudRate; /*設置波特率*/
dcb.ByteSize = DataBits; /*設置數據位*/
dcb.Parity= Parity; /*設置校驗位*/
dcb.StopBits= StopBits; /*設置停止位*/
dcb.fParity= FALSE; /* 禁止奇偶校驗 */
dcb.fBinary= TRUE;
dcb.fOutX= 0;
dcb.fInX= 0;
//設置狀態(tài)參數
SetCommMask(hComm, EV_RXCHAR); /* 串口事件:接收到一個字符 */
SetupComm(hComm, 16384, 16384); /* 設置接收與發(fā)送的緩沖區(qū)大小 */
SetCommState(hComm, &dcb);
BOOL isSucces=SetCommState(hComm, &dcb);/* 設置串口的DCB */
if(!isSucces)
{
error=GetLastError();
MessageBox(_T("無法按當前參數配置端口,請檢查參數!"));
ClosePort();
return FALSE;
}
GetCommTimeouts(hComm, &CommTimeOuts); /*獲得超時參數*/
//設置超時參數
CommTimeOuts.ReadIntervalTimeout = 100; /* 接收字符間最大時間間隔 */
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
CommTimeOuts.ReadTotalTimeoutConstant = 100; /* 讀數據總超時常量 */
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
if(!SetCommTimeouts(hComm, &CommTimeOuts))
{
MessageBox(_T("無法設置超時參數!"));
ClosePort();
return FALSE;
}
PurgeComm(hComm, PURGE_TXCLEAR | PURGE_RXCLEAR); /* 清除收/發(fā)緩沖區(qū) */
return TRUE;
}
BOOL CSerialDlg::ClosePort(void)
{
if(hComm != INVALID_HANDLE_VALUE)
{
SetCommMask(hComm, 0); //disables all events
PurgeComm(hComm, PURGE_TXCLEAR | PURGE_RXCLEAR); /* 清除收/發(fā)緩沖 */
CloseHandle(hComm); /* 關閉串口操作句柄 */
hComm = INVALID_HANDLE_VALUE;
return TRUE;
}
return FALSE;
}
void CALLBACK CSerialDlg::OnComRecv(CWnd* pWnd, char *buf, int buflen)
{
CString tmp;
CSerialDlg *pDlg = (CSerialDlg*)pWnd;
CEdit *pRecvStrEdit = (CEdit*)pDlg->GetDlgItem(IDC_REV);
for (int i = 0; i < buflen; i++, buf++)
{
tmp.Format(_T("%c"), *buf); /* 將字符轉換為字符串 */
pDlg->strRecDisp += tmp;
}
pRecvStrEdit->SetWindowText(pDlg->strRecDisp); /* 顯示在窗口上 */
}
DWORD CSerialDlg::ComRecvThread(LPVOID lparam)
{
DWORD dwLength;
char *recvBuf = new char[1024];
CSerialDlg *pDlg = (CSerialDlg*)lparam;
while(TRUE)
{
/* 等待線程退出事件 */
if (WaitForSingleObject(pDlg->ExitThreadEvent, 0) == WAIT_OBJECT_0)
break;
if (pDlg->hComm != INVALID_HANDLE_VALUE)
{ /* 從串口讀取數據 */
BOOL fReadState = ReadFile(pDlg->hComm, recvBuf, 1024, &dwLength, NULL);
if(!fReadState)
{
//MessageBox(_T("無法從串口讀取數據!"));
}
else
{
if(dwLength != 0)
OnComRecv(pDlg, recvBuf, dwLength-2); /* 接收成功調用回調函數 */
}
}
}
delete[] recvBuf;
return 0;
}
void CSerialDlg::OnOpenCom()
{
DWORD IDThread;
HANDLE hRecvThread;
UpdateData(TRUE); /*把控件的值傳給變量*/
CString strPort =_T("COM1:"); /* 設置參數值 */
DWORD baud = 115200;
DWORD databit = 8;
BYTE stopbit = ONESTOPBIT;
BYTE parity = NOPARITY;
BOOL ret = OpenPort(strPort, baud, databit, stopbit, parity); /* 打開串口 */
if (ret == FALSE)
return;
ExitThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* 創(chuàng)建串口接收線程退出事件*/
hRecvThread = CreateThread(0, 0, ComRecvThread, this, 0, &IDThread);
if (hRecvThread == NULL)
{
MessageBox(_T("創(chuàng)建接收線程失敗!"));
return;
}
CloseHandle(hRecvThread);
ButOpen.EnableWindow(FALSE); /* 打開端口按鍵禁止 */
ButClose.EnableWindow(TRUE); /* 關閉端口按鍵使能 */
MessageBox(_T("打開串口COM1成功!"));
}
void CSerialDlg::OnCloseCom()
{
if (ExitThreadEvent != NULL)
{
SetEvent(ExitThreadEvent); /* 通知線程退出 */
Sleep(1000);
CloseHandle(ExitThreadEvent);
ExitThreadEvent = NULL;
}
ButOpen.EnableWindow(TRUE); /* 打開端口按鍵禁止 */
ButClose.EnableWindow(FALSE); /* 關閉端口按鍵使能 */
ClosePort();
}
void CSerialDlg::OnSend()
{
DWORD dwactlen;
char *recvBuf = new char[1024];
if (hComm == INVALID_HANDLE_VALUE)
{
MessageBox(_T("串口未打開!"));
return;
}
UpdateData(TRUE);
int len = strSendEdit.GetLength(); /* 取得輸入字符串長度 */
char *psendbuf = new char[len];
for(int i = 0; i < len;i++)
psendbuf[i] = (char)strSendEdit.GetAt(i); /* 轉換為單字節(jié)字符 */
WriteFile(hComm, psendbuf, len, &dwactlen, NULL); /* 從串口發(fā)送數據 */
WriteFile(hComm, "\r", 1, &dwactlen, NULL); /* 發(fā)送回車,weibing */
delete[] psendbuf;
}
void CSerialDlg::OnDestroy()
{
CDialog::OnDestroy();
if (ExitThreadEvent != NULL)
{
SetEvent(ExitThreadEvent); /* 通知串口接收線程退出 */
Sleep(1000);
CloseHandle(ExitThreadEvent); /* 關閉接收線程退出事件句柄 */
ExitThreadEvent = NULL;
}
ClosePort(); /* 關閉串口 */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -