?? serialportdlg.cpp
字號:
// SerialPortDlg.cpp : implementation file
//
#include "stdafx.h"
#include "SerialPort.h"
#include "SerialPortDlg.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()
/////////////////////////////////////////////////////////////////////////////
// CSerialPortDlg dialog
CSerialPortDlg::CSerialPortDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSerialPortDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSerialPortDlg)
m_sSendMsg = _T("");
m_sShow = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSerialPortDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSerialPortDlg)
DDX_Text(pDX, IDC_SEND_MSG, m_sSendMsg);
DDX_Text(pDX, IDC_SHOW, m_sShow);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSerialPortDlg, CDialog)
//{{AFX_MSG_MAP(CSerialPortDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(ID_SP_CONNECT, OnSpConnect)
ON_BN_CLICKED(ID_SP_DISCONNECT, OnSpDisconnect)
ON_BN_CLICKED(ID_SP_SETTINGS, OnSpSettings)
ON_BN_CLICKED(ID_SP_SEND, OnSpSend)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSerialPortDlg message handlers
BOOL CSerialPortDlg::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
// TODO: Add extra initialization here
m_bConnected=FALSE;
m_pThread=NULL;
m_sPort="COM1";
m_nBaud=9600;
m_nDataBits=8;
m_sParity="None";
m_sStopBits="1";
m_nFlowCtrl=0;
m_sSendMsg="";
m_sShow="";
GetDlgItem(ID_SP_DISCONNECT)->EnableWindow(m_bConnected);
GetDlgItem(ID_SP_SEND)->EnableWindow(m_bConnected);
memset(&m_osRead,0,sizeof(OVERLAPPED));
memset(&m_osWrite,0,sizeof(OVERLAPPED));
if(!(m_osRead.hEvent=CreateEvent(NULL,TRUE,TRUE,NULL))) return FALSE;
if(!(m_osWrite.hEvent=CreateEvent(NULL,TRUE,TRUE,NULL))) return FALSE;
return TRUE; // return TRUE unless you set the focus to a control
}
void CSerialPortDlg::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 CSerialPortDlg::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 CSerialPortDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CSerialPortDlg::OnSpConnect()
{
// TODO: Add your control notification handler code here
COMMTIMEOUTS TimeOuts;
if(m_bConnected) return;
m_hSPCom=CreateFile(m_sPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
if(m_hSPCom==INVALID_HANDLE_VALUE)
{
AfxMessageBox("Can't open connection!");
return;
}
SetupComm(m_hSPCom,MAXBLOCK,MAXBLOCK);
SetCommMask(m_hSPCom,EV_RXCHAR);
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutConstant=0;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.WriteTotalTimeoutConstant=2000;
TimeOuts.WriteTotalTimeoutMultiplier=50;
SetCommTimeouts(m_hSPCom,&TimeOuts);
if(ConfigConnection())
{
m_pThread=AfxBeginThread(SPCommProc,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL);
if(m_pThread==NULL)
{
CloseHandle(m_hSPCom);
AfxMessageBox("Can't open connection!");
return;
}
else{
m_bConnected=TRUE;
m_pThread->ResumeThread();
}
}
else{
CloseHandle(m_hSPCom);
AfxMessageBox("Can't open connection!");
return;
}
GetDlgItem(ID_SP_CONNECT)->EnableWindow(!m_bConnected);
GetDlgItem(ID_SP_DISCONNECT)->EnableWindow(m_bConnected);
GetDlgItem(ID_SP_SEND)->EnableWindow(m_bConnected);
}
void CSerialPortDlg::OnSpDisconnect()
{
// TODO: Add your control notification handler code here
if(!m_bConnected) return;
m_bConnected=FALSE;
SetCommMask(m_hSPCom,0);
WaitForSingleObject(m_pThread->m_hThread,INFINITE);
m_pThread=NULL;
CloseHandle(m_hSPCom);
GetDlgItem(ID_SP_CONNECT)->EnableWindow(!m_bConnected);
GetDlgItem(ID_SP_DISCONNECT)->EnableWindow(m_bConnected);
GetDlgItem(ID_SP_SEND)->EnableWindow(m_bConnected);
}
void CSerialPortDlg::OnCancel()
{
// TODO: Add extra cleanup here
if(m_bConnected) OnSpDisconnect();
if(m_osRead.hEvent) CloseHandle(m_osRead.hEvent);
if(m_osWrite.hEvent) CloseHandle(m_osWrite.hEvent);
CDialog::OnCancel();
}
void CSerialPortDlg::OnSpSettings()
{
// TODO: Add your control notification handler code here
CSetupDlg dlg;
CString str;
dlg.m_bConnected=m_bConnected;
dlg.m_sPort=m_sPort;
str.Format("%d",m_nBaud);
dlg.m_sBaud=str;
str.Format("%d",m_nDataBits);
dlg.m_sDataBits=str;
dlg.m_sParity=m_sParity;
dlg.m_sStopBits=m_sStopBits;
dlg.m_nFlowCtrl=m_nFlowCtrl;
if(dlg.DoModal()==IDOK)
{
m_sPort=dlg.m_sPort;
m_nBaud=atoi(dlg.m_sBaud);
m_nDataBits=atoi(dlg.m_sDataBits);
m_sParity=dlg.m_sParity;
m_sStopBits=dlg.m_sStopBits;
m_nFlowCtrl=dlg.m_nFlowCtrl;
if(m_bConnected)
if(!ConfigConnection()) AfxMessageBox("Can't realize the settings!");
}
}
BOOL CSerialPortDlg::ConfigConnection()
{
DCB dcb;
if(!GetCommState(m_hSPCom,&dcb)) return FALSE;
dcb.fBinary=TRUE;
dcb.BaudRate=m_nBaud;
dcb.ByteSize=m_nDataBits;
dcb.fParity=TRUE;
if(strcmp(m_sParity,"None")==0) dcb.Parity=NOPARITY;
else if(strcmp(m_sParity,"Even")==0) dcb.Parity=EVENPARITY;
else if(strcmp(m_sParity,"Odd")==0) dcb.Parity=ODDPARITY;
if(strcmp(m_sStopBits,"1")==0) dcb.StopBits=ONESTOPBIT;
else if(strcmp(m_sStopBits,"1.5")==0) dcb.StopBits=ONE5STOPBITS;
else if(strcmp(m_sStopBits,"2")==0) dcb.StopBits=TWOSTOPBITS;
dcb.fOutxCtsFlow=dcb.fRtsControl=(m_nFlowCtrl==1);
dcb.fInX=dcb.fOutX=(m_nFlowCtrl==2);
dcb.XonChar=XON;
dcb.XoffChar=XOFF;
dcb.XonLim=dcb.XoffLim=50;
return SetCommState(m_hSPCom,&dcb);
}
DWORD CSerialPortDlg::ReadComm(char *buf, DWORD dwLength)
{
DWORD length=0;
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(m_hSPCom,&dwErrorFlags,&ComStat);
length=min(dwLength,ComStat.cbInQue);
ReadFile(m_hSPCom,buf,length,&length,&m_osRead);
return length;
}
DWORD CSerialPortDlg::WriteComm(char *buf, DWORD dwLength)
{
DWORD length=dwLength;
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(m_hSPCom,&dwErrorFlags,&ComStat);
WriteFile(m_hSPCom,buf,length,&length,&m_osWrite);
if(GetLastError()==ERROR_IO_PENDING) GetOverlappedResult(m_hSPCom,&m_osWrite,&length,TRUE);
else length=0;
return length;
}
void CSerialPortDlg::OnSpSend()
{
// TODO: Add your control notification handler code here
DWORD length;
CString str;
UpdateData(TRUE);
length=WriteComm(m_sSendMsg.LockBuffer(),m_sSendMsg.GetLength());
str.Format("本機發送數據:\r\n");
m_sShow+=str;
m_sShow+=m_sSendMsg.Left(length);
m_sShow+="\r\n\r\n";
UpdateData(FALSE);
}
UINT SPCommProc(LPVOID pParam)
{
OVERLAPPED os;
DWORD dwMask,dwTrans;
COMSTAT ComStat;
DWORD dwErrorFlags;
char buf[MAXBLOCK/4];
DWORD length,i;
CString str;
CSerialPortDlg *pDlg=(CSerialPortDlg *)pParam;
memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(os.hEvent==NULL)
{
AfxMessageBox("Can't create event object!");
return -1;
}
while(pDlg->m_bConnected)
{
ClearCommError(pDlg->m_hSPCom,&dwErrorFlags,&ComStat);
if(ComStat.cbInQue)
{
length=pDlg->ReadComm(buf,100);
str.Format("本機收到數據:\r\n");
pDlg->m_sShow+=str;
for(i=0;i<length;i++) pDlg->m_sShow+=buf[i];
pDlg->m_sShow+="\r\n\r\n";
pDlg->UpdateData(FALSE);
}
dwMask=0;
if(!WaitCommEvent(pDlg->m_hSPCom,&dwMask,&os))
{
if(GetLastError()==ERROR_IO_PENDING)
GetOverlappedResult(pDlg->m_hSPCom,&os,&dwTrans,TRUE);
else{
CloseHandle(os.hEvent);
return -1;
}
}
}
CloseHandle(os.hEvent);
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -