📄 comportdlg.cpp
字号:
// ComPortDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ComPort.h"
#include "ComPortDlg.h"
#include "Setting.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// 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()
/////////////////////////////////////////////////////////////////////////////
// CComPortDlg dialog
CComPortDlg::CComPortDlg(CWnd* pParent /*=NULL*/)
: CDialog(CComPortDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CComPortDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_bConnected = FALSE;
m_strPort = "COM1";
m_nDataBits = 8;
m_nParity = 0;
m_nBaud = 9600;
m_nStopBits = 0;
m_nFlowCtrl = 0;
log.m_strlog = "";
m_pThread = NULL;
m_testreadthread = NULL;
m_strrecordlog_temp = "";
m_strbuffer = "";
m_bbufferopen = TRUE;
m_bisonchar = FALSE;
m_stronchar = "";
m_strtestbuffer ="";
m_testfindstring = "";
starttime = endtime = CTime::GetCurrentTime();
m_bcalltestfindstring = FALSE;
m_bsendonetime = FALSE;
m_bcallexpectstring = FALSE;
m_bexpectonetime = FALSE;
m_testthread = NULL;
starttest = FALSE;
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CComPortDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CComPortDlg)
DDX_Control(pDX, IDC_edtlog, m_edtlog);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CComPortDlg, CDialog)
//{{AFX_MSG_MAP(CComPortDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_btnOpen, OnbtnOpen)
ON_BN_CLICKED(IDC_btnClosed, OnbtnClosed)
ON_BN_CLICKED(IDC_btnSetting, OnbtnSetting)
ON_BN_CLICKED(IDC_btnShowLog, OnbtnShowLog)
ON_BN_CLICKED(IDC_btnlastlog, Onbtnlastlog)
ON_BN_CLICKED(IDC_btnsendcommand, Onbtnsendcommand)
ON_BN_CLICKED(IDC_btngetbuffer, Onbtngetbuffer)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CComPortDlg message handlers
BOOL CComPortDlg::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
if((m_hPostMsgEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL)
return FALSE;
memset(&m_osRead, 0, sizeof(OVERLAPPED));
memset(&m_osWrite, 0, sizeof(OVERLAPPED));
if((m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))== NULL)
return FALSE;
if((m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
return FALSE;
return TRUE; // return TRUE unless you set the focus to a control
}
void CComPortDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 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 CComPortDlg::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 CComPortDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CComPortDlg::OnbtnOpen()
{
if(m_bConnected)
{
MessageBox("Com Port was opened!");
return ;
}
pcomopen = AfxBeginThread(comopenfunc,this,THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED,NULL);
if(pcomopen == NULL)
{
return ;
}
else
{
pcomopen->ResumeThread();
}
}
UINT comopenfunc(LPVOID lParam)
{
CComPortDlg* pcomportdlg = (CComPortDlg*)lParam;
if(!pcomportdlg->ComOpen())
AfxMessageBox("无法建立连接!");
return 1;
}
UINT ComPorc(LPVOID pParam)
{
OVERLAPPED os;
DWORD dwMask, dwTrans;
COMSTAT ComStat;
DWORD dwErrorFlags;
CComPortDlg* pDlg = (CComPortDlg*)pParam;
memset(&os, 0, sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(os.hEvent == NULL)
{
AfxMessageBox("无法创建事件对象!");
return (UINT)-1;
}
while(pDlg->m_bConnected)
{
ClearCommError(pDlg->m_hCom, &dwErrorFlags, &ComStat);
if(ComStat.cbInQue)//有ComPort中等待要取出来的字符数
{
WaitForSingleObject(pDlg->m_hPostMsgEvent, INFINITE);
ResetEvent(pDlg->m_hPostMsgEvent);
pDlg->OnCom(EV_RXCHAR, 0);
continue;
}
dwMask = 0;
if(!WaitCommEvent(pDlg->m_hCom, &dwMask, &os))
{
if(GetLastError() == ERROR_IO_PENDING)
GetOverlappedResult(pDlg->m_hCom, &os, &dwTrans, TRUE);
else
{
CloseHandle(os.hEvent);
return (UINT)-1;
}
}
}
CloseHandle(os.hEvent);
return 0;
}
LRESULT CComPortDlg::OnCom(WPARAM wParam, LPARAM lParam)
{
char buf[MAXBLOCK/4];
CString str;
int nLength, nTextLength;
if(!m_bConnected || (wParam & EV_RXCHAR) != EV_RXCHAR)
{
SetEvent(m_hPostMsgEvent);
return 0L;
}
nLength = ReadCom(buf, 100);
if(nLength)
{
// recordlog(buf,nLength); //记录 log.
nTextLength = m_edtlog.GetWindowTextLength();
m_edtlog.SetSel(nTextLength, nTextLength);
for(int i=0; i<nLength; i++)
{
switch(buf[i])
{
case '\n':
str += "\n";
break;
case '\b':
m_edtlog.SetSel(-1, 0);
m_edtlog.ReplaceSel(str);
nTextLength = m_edtlog.GetWindowTextLength();
m_edtlog.SetSel(nTextLength-1, nTextLength);
m_edtlog.ReplaceSel("");
str = "";
break;
case '\a':
MessageBeep((UINT)-1);
break;
default:
str += buf[i];
}
}
m_edtlog.SetSel(-1, 0);
m_edtlog.ReplaceSel(str);
recordlog(str);
getcomportbuffer(str);
// m_strbuffer += str;
}
SetEvent(m_hPostMsgEvent);
return 0L;
}
DWORD CComPortDlg::ReadCom(char *buf, DWORD dwLength)
{
DWORD length = 0;
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(m_hCom, &dwErrorFlags, &ComStat);
length = min(dwLength, ComStat.cbInQue);
ReadFile(m_hCom, buf, length, &length, &m_osRead);
return length;
}
BOOL CComPortDlg::comconfig()
{
CString str;
DCB dcb;
if(!GetCommState(m_hCom, &dcb))
{
MessageBox("Return False!");
return FALSE;
}
dcb.fBinary = TRUE;
dcb.BaudRate = m_nBaud;
CString str1;
str1.Format("new BaudRate = %d", dcb.BaudRate);
//MessageBox(str1);
dcb.ByteSize = m_nDataBits;
dcb.fParity = TRUE;
m_nStopBits = 0;
str.Format("m_strPort = %s, m_nBaud = %d, m_nDataBits = %d, \
m_nParity = %d, m_nStopBits = %d, m_nFlowCtrl = %d",
m_strPort, m_nBaud, m_nDataBits, m_nParity, m_nStopBits, m_nFlowCtrl);
//MessageBox(str);
switch(m_nParity)
{
case 0:
dcb.Parity = NOPARITY;
break;
case 1:
dcb.Parity = EVENPARITY;
break;
case 2:
dcb.Parity = ODDPARITY;
break;
default:;
}
switch(m_nStopBits)
{
case 0:
dcb.StopBits = ONESTOPBIT;
break;
case 1:
dcb.StopBits = ONE5STOPBITS;
break;
case 2:
dcb.StopBits = TWOSTOPBITS;
break;
default:;
}
str.Format("BaudRate= %d",dcb.BaudRate);
//MessageBox(str);
switch(m_nFlowCtrl)
{
case 0:
//无,指无流量控制.
dcb.fOutxCtsFlow = FALSE; //打开硬件流控制
dcb.fRtsControl = FALSE; //打开硬件流控制
dcb.fInX = dcb.fOutX = FALSE; //关闭软件流控制
break;
case 1:
//RTS/CTS 硬件流控程
dcb.fOutxCtsFlow = TRUE; //打开硬件流控制
dcb.fRtsControl = TRUE; //打开硬件流控制
dcb.fInX = dcb.fOutX = FALSE; //关闭软件流控制
break;
case 2:
//XON XOFF 软件流控制
dcb.fOutxCtsFlow = FALSE; //关闭硬件流控制
dcb.fRtsControl = FALSE; //关闭硬件流控制
dcb.fInX = dcb.fOutX = TRUE; //打开软件流控制
dcb.XonChar = XON;
dcb.XoffChar = XOFF;
dcb.XonLim = 50;
dcb.XoffLim = 50;
break;
default:;
}
str.Format("m_strPort = %s, dcb.BaudRate = %d, m_nDataBits = %d, \
m_nParity = %d, dcb.StopBits = %d, m_nFlowCtrl = %d",
m_strPort, dcb.BaudRate, m_nDataBits, m_nParity, dcb.StopBits, m_nFlowCtrl);
//MessageBox(str);
return SetCommState(m_hCom, &dcb);
}
BOOL CComPortDlg::ComOpen()
{
COMMTIMEOUTS TimeOuts;
CString threadid;
m_hCom = CreateFile(m_strPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if(m_hCom == INVALID_HANDLE_VALUE)
{
MessageBox("Com Port no existing");
return FALSE;
}
SetupComm(m_hCom, MAXBLOCK, MAXBLOCK);
SetCommMask(m_hCom, EV_RXCHAR | EV_CTS|EV_DSR|EV_RING);
TimeOuts.ReadIntervalTimeout = MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier = 0;
TimeOuts.ReadTotalTimeoutConstant = 0;
TimeOuts.WriteTotalTimeoutMultiplier = 50;
TimeOuts.WriteTotalTimeoutConstant = 2000;
SetCommTimeouts(m_hCom, &TimeOuts);
if(comconfig())
{
m_pThread = AfxBeginThread(
ComPorc,
this,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,
NULL);
if(m_pThread == NULL)
{
CloseHandle(m_hCom);
return FALSE;
}
else
{
m_bConnected = TRUE;
m_pThread->ResumeThread();
}
CComPortDlg::testreadthread();
CComPortDlg::testthread();
}
else
{
CloseHandle(m_hCom);
return FALSE;
}
return TRUE;
}
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
CComPortDlg* pDlgtest = (CComPortDlg*)lpParameter;
int i=0;
// FILE *tfile = fopen("test.log","a+");
while(i<1000)
{
i++;
pDlgtest->m_strtestbuffer= pDlgtest->m_strbuffer;
// Sleep(500);
// AfxMessageBox(pDlgtest->m_strtestbuffer);
// FILE *tfile = fopen("ding1.log","a+");
// fwrite(pDlgtest->m_strtestbuffer,1, strlen(pDlgtest->m_strtestbuffer), tfile);
// fclose(tfile);
Sleep(1500);
}
return 1;
}
DWORD CComPortDlg::SendCom(char *buf, DWORD dwLength)
{
BOOL fState;
DWORD length = dwLength;
COMSTAT ComStat;
DWORD dwErrorFlags;
CString charleng;
if(m_bisonchar) //如果是由OnChar传来的字符,将进行组合成字符串m_stronchar.
{
if(buf[0] != '\r')
m_stronchar +=buf[0];
}
if(length)
{
//每一次对输入的字符进行分析,如果遇到回车或换行的时候,将把m_strbuffer进行清空,把*buf的字
//符赋给m_strbuffer中.
for(DWORD i=0; i<length; i++)
{
switch(buf[i])
{
case '\r':
m_strbuffer = "";
if(m_bisonchar)
{
m_strbuffer += m_stronchar;
m_stronchar = "";
}
m_bbufferopen= TRUE;
break;
case '\n':
m_strbuffer = "";
m_bbufferopen= TRUE;
break;
default:
m_strbuffer += buf[i]; //不放在这里后面会多带一个回车, 在Buffer中会多一行.
break;
}
}
}
//写入数据
ClearCommError(m_hCom, &dwErrorFlags, &ComStat);
fState = WriteFile(m_hCom, buf, length, &length, &m_osWrite);
if(!fState)
{
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(m_hCom, &m_osWrite, &length, TRUE);
}
else
{
length = 0;
}
}
return length;
}
void CComPortDlg::ComClose()
{
SetEvent(m_hPostMsgEvent);
SetCommMask(m_hCom,0);
WaitForSingleObject(m_pThread->m_hThread, INFINITE);
m_pThread = NULL;
CloseHandle(m_hCom);
}
void CComPortDlg::OnbtnClosed()
{
thiscomclose();
}
void CComPortDlg::OnbtnSetting()
{
CSetting comSetting;
CString str;
comSetting.m_strPort = m_strPort;
str.Format("%d",m_nBaud);
comSetting.m_strBaudRate =str;
str.Format("%d",m_nDataBits);
comSetting.m_strDataBits = str;
str.Format("m_nParity = %d, m_nFlowCtrl= %d",m_nParity,m_nFlowCtrl);
switch(m_nParity)
{
case 0:
comSetting.m_nParity = "NONE";
break;
case 1:
comSetting.m_nParity = "EVEN";
break;
case 2:
comSetting.m_nParity = "ODD";
break;
default:;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -