📄 serialasdlg.cpp
字号:
// SerialAsDlg.cpp : implementation file
//
#include "stdafx.h"
#include "SerialAs.h"
#include "SerialAsDlg.h"
#include <afx.h>
#include "FilePro.h"
#include <limits.h>
#include "Shlwapi.h"
#include "shlobj.h"
#include "StatLink.h"
#include "CreditStatic.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
#define ID_PORTSTATUS 0
#define ID_COMSTATUS 1
#define ID_TIME 2
static const UINT BASED_CODE indicators[] =
{
ID_PORTSTATUS,
ID_COMSTATUS,
ID_TIME
};
static const TIME_ID_TIME = 1;
static const TIME_ID_SEND = 2;
static const TIME_ID_REV = 3;
typedef struct _SEND
{
BOOL bFlag;
DOUBLE value;
}SEND;
class CAboutDlg : public CDialog
{
public:
BOOL m_bAbout;
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
CMacButton m_btSwitch;
CStaticLink m_staticMail;
CRichEditCtrl m_reditHelpText;
CMacButton m_btOK;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
CBrush m_bkBrush;
//{{AFX_MSG(CAboutDlg)
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
virtual BOOL OnInitDialog();
afx_msg void OnButtonswitch();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
CToolTipCtrl m_ToolTipMail ;
CCreditStatic m_DyCredits;
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
m_bAbout = TRUE;
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
DDX_Control(pDX, IDC_BUTTONSWITCH, m_btSwitch);
DDX_Control(pDX, IDC_STATIC_MAIL, m_staticMail);
DDX_Control(pDX, IDC_RICHEDITHELP, m_reditHelpText);
DDX_Control(pDX, IDOK, m_btOK);
DDX_Control(pDX, IDC_DYCREDITS, m_DyCredits);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_BUTTONSWITCH, OnButtonswitch)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSerialAsDlg dialog
CSerialAsDlg::CSerialAsDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSerialAsDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSerialAsDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_hCom = NULL;
m_bRun = FALSE;
m_dwRevCount = 0;
m_dwSendCount = 0;
m_sRev = _T("");
m_bRevUpdate = FALSE;
m_bHexDisplay = FALSE;
m_bAutoSend = FALSE;
m_bAutoClear = FALSE;
m_bHEXSend = FALSE;
m_dwSendFileLen = 0;
m_bSendFlag = FALSE;
m_hEventSendFile = CreateEvent(
NULL, // no security attributes
TRUE, // manual-reset event
FALSE, // initial state is nosignaled
NULL // object name
);
m_bCancelSend = TRUE;
m_bkBrush.CreateSolidBrush(DLGBK_COLOR);
}
void CSerialAsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSerialAsDlg)
DDX_Control(pDX, IDC_MYHELP, m_btHelp);
DDX_Control(pDX, IDC_STATIC_NAIL, m_staticNail);
DDX_Control(pDX, IDC_STATIC_STR_PERIOD, m_staticStrPeriod);
DDX_Control(pDX, IDC_STATIC_STR_MS, m_staticStrMS);
DDX_Control(pDX, IDC_SAVEFILENAME, m_editSavefileName);
DDX_Control(pDX, IDC_CLEARREVDATA, m_btClearRevData);
DDX_Control(pDX, IDC_CHECKHEXSEND, m_checkHEXSend);
DDX_Control(pDX, IDC_CHECKAUTOSEND, m_checkAutoSend);
DDX_Control(pDX, IDC_BTNSAVEFILE, m_btSaveFile);
DDX_Control(pDX, IDC_BTNPORTCONFIG, m_btConfigPort);
DDX_Control(pDX, IDC_BTNOPENPORT, m_btOpenPort);
DDX_Control(pDX, IDC_BTNCLOSEPORT, m_btClosePort);
DDX_Control(pDX, IDC_BTNCHANGESAVEFILEPATH, m_btChangeSaveFilePath);
DDX_Control(pDX, IDCANCEL, m_btCancel);
DDX_Control(pDX, IDC_EDITSENDCOUNT, m_editSendCount);
DDX_Control(pDX, IDC_BTNCLEARREVCOUNT, m_btClearRevCount);
DDX_Control(pDX, IDC_BTNCLEARSENDCOUNT, m_btClearSendCount);
DDX_Control(pDX, IDC_CLEARSENDDATA, m_btClearSendData);
DDX_Control(pDX, IDC_EDITSENDFILEPATH, m_editSendFilePath);
DDX_Control(pDX, IDC_STARTSENDFILE, m_btStartSendFile);
DDX_Control(pDX, IDC_SELECTSENDFILE, m_btSelectSendFile);
DDX_Control(pDX, IDC_EDITSENDPERIOD, m_editSendPeriod);
DDX_Control(pDX, IDC_MANUALSEND, m_btManualSend);
DDX_Control(pDX, IDC_RICHEDITSENDDATA, m_Send);
DDX_Control(pDX, IDC_RICHEDITREVDATA, m_Rev);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSerialAsDlg, CDialog)
//{{AFX_MSG_MAP(CSerialAsDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTNPORTCONFIG, OnBtnportconfig)
ON_BN_CLICKED(IDC_BTNOPENPORT, OnBtnopenport)
ON_BN_CLICKED(IDC_BTNCLOSEPORT, OnBtncloseport)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_SELECTSENDFILE, OnSelectsendfile)
ON_BN_CLICKED(IDC_BTNCLEARREVCOUNT, OnBtnclearrevcount)
ON_BN_CLICKED(IDC_BTNCLEARSENDCOUNT, OnBtnclearsendcount)
ON_BN_CLICKED(IDC_CLEARREVDATA, OnClearrevdata)
ON_WM_LBUTTONDOWN()
ON_BN_CLICKED(IDC_CHECKHEXDISPLAY, OnCheckhexdisplay)
ON_BN_CLICKED(IDC_STARTSENDFILE, OnStartsendfile)
ON_BN_CLICKED(IDC_CHECKAUTOSEND, OnCheckautosend)
ON_BN_CLICKED(IDC_MANUALSEND, OnManualsend)
ON_BN_CLICKED(IDC_CHECKAUTOCLEAR, OnCheckautoclear)
ON_BN_CLICKED(IDC_CLEARSENDDATA, OnClearsenddata)
ON_BN_CLICKED(IDC_CHECKHEXSEND, OnCheckhexsend)
ON_BN_CLICKED(IDC_BTNSAVEFILE, OnBtnsavefile)
ON_BN_CLICKED(IDC_BTNCHANGESAVEFILEPATH, OnBtnchangesavefilepath)
ON_EN_CHANGE(IDC_SAVEFILENAME, OnChangeSavefilename)
ON_WM_ERASEBKGND()
ON_WM_CTLCOLOR()
ON_WM_SIZE()
ON_WM_GETMINMAXINFO()
ON_WM_SIZING()
ON_BN_CLICKED(IDC_STATIC_NAIL, OnStaticNail)
ON_BN_CLICKED(IDC_MYHELP, OnMyhelp)
ON_WM_HELPINFO()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_RECEIVE,OnReceive)
ON_MESSAGE(WM_SEND,OnSend)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSerialAsDlg message handlers
BOOL CSerialAsDlg::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
//创建状态条
DWORD style = WS_CHILD|WS_VISIBLE|CBRS_BOTTOM;
style &= ~WS_THICKFRAME;
m_StatusBar.CreateEx(this,SBT_TOOLTIPS,style, AFX_IDW_STATUS_BAR);
m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));
CRect rect,rect1;
GetClientRect(&rect);
m_staticNail.GetWindowRect(&rect1);
m_StatusBar.SetPaneInfo(0,ID_PORTSTATUS,SBPS_NORMAL,rect.Width()*2/5-5);
m_StatusBar.SetPaneInfo(1,ID_COMSTATUS,SBPS_STRETCH,rect.Width()*2/5-rect1.Width());
m_StatusBar.SetPaneInfo(2,ID_TIME,SBPS_NORMAL ,rect.Width()*1/5);
m_StatusBar.MoveWindow(rect.left+20,rect.bottom-rect1.Height(),
rect.Width()-rect1.Width()-5,rect1.Height(),TRUE);
m_StatusBar.GetStatusBarCtrl().SetBkColor(DLGBK_COLOR);
m_hIconClosed = AfxGetApp()->LoadIcon(IDI_ICONCLOSED);
m_hIconOpened = AfxGetApp()->LoadIcon(IDI_ICONOPENED);
m_StatusBar.GetStatusBarCtrl().SetIcon(0,m_hIconClosed);
EnableCtrl(TRUE);
UpdateStatusBar();
SetTimer(TIME_ID_TIME,1000,NULL);
GetDlgItem(IDC_EDITREVCOUNT)->SetWindowText(_T("RX:0"));
GetDlgItem(IDC_EDITSENDCOUNT)->SetWindowText(_T("TX:0"));
GetDlgItem(IDC_EDITSENDPERIOD)->SetWindowText(_T("1000"));
SetDlgItemText(IDC_RICHEDITSENDDATA,_T("lxg215@hotmail.com"));
m_hSendEvent = CreateEvent(
NULL, // no security attributes
TRUE, // manual-reset event
FALSE, // initial state is nosignaled
NULL // object name
);
if(m_hSendEvent==NULL)
return false;
SetDlgItemText(IDC_SAVEFILENAME,_T("Rev.dat"));
CString str;
str = STR_ROOT_DIR ;
str += _T("\\Rev.dat");
SetDlgItemText(IDC_STATICSAVEFILEPATH,str);
m_sSaveDir = STR_ROOT_DIR;
m_OldSaveFileName = _T("Rev.dat") ;
GetClientRect(&m_OldRect);
return TRUE; // return TRUE unless you set the focus to a control
}
void CSerialAsDlg::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 CSerialAsDlg::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 CSerialAsDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CSerialAsDlg::OnBtnportconfig()
{
// TODO: Add your control notification handler code here
if(m_ConfigPort.DoModal()==IDOK)
{
if(m_ConfigPort.m_bOpen)
{
OnBtnopenport();
}
UpdateStatusBar();
}
}
UINT CSerialAsDlg::RevThreadProc(LPVOID pParam)
{
HANDLE h_gEvent;
DWORD dwBytesRead;
OVERLAPPED Overlapped;
CSerialAsDlg *pDlg = (CSerialAsDlg*) pParam;
BOOL bReadStatus = FALSE;
dwBytesRead = 0;
memset(&Overlapped,0,sizeof(OVERLAPPED));
h_gEvent = NULL;
h_gEvent = CreateEvent(
NULL,
TRUE, //手工设置事件有无信号
FALSE, //初始化事件为无信号状态
NULL
);
if(h_gEvent == NULL) return 0;
Overlapped.hEvent = h_gEvent;
#define BUFSIZE 1024
BYTE data[BUFSIZE];
ZeroMemory(data,BUFSIZE);
DWORD dwEvtMask=0;
GetCommMask(pDlg->m_hCom,&dwEvtMask);
dwEvtMask |= EV_RXCHAR;
SetCommMask(pDlg->m_hCom,dwEvtMask);
while(pDlg->m_bRun)
{
WaitCommEvent(pDlg->m_hCom,&dwEvtMask,NULL);
if(pDlg->m_hCom==NULL)
return 0;
if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR){
COMSTAT ComStat ;
DWORD dwLength,dwErrorFlags;
ClearCommError(pDlg->m_hCom, &dwErrorFlags, &ComStat ) ;
dwLength = ComStat.cbInQue ; //输入缓冲区有多少数据?
if (dwLength > 0){
bReadStatus = ReadFile( pDlg->m_hCom, data,dwLength, &dwBytesRead,
&Overlapped); //读数据
if(!bReadStatus)
{
if(GetLastError()==ERROR_IO_PENDING)
{
while(!GetOverlappedResult(pDlg->m_hCom,
&Overlapped, &dwBytesRead, TRUE ))
{
if(GetLastError() == ERROR_IO_INCOMPLETE)
continue;
}
pDlg->m_bRevCS.Lock();
for(int i = 0;i<dwBytesRead;i++)
{
pDlg->m_dequeRevData.push_back(data[i]);
}
pDlg->m_bRevCS.Unlock();
pDlg->PostMessage(WM_RECEIVE,0,0);
}
}
else
{
pDlg->m_bRevCS.Lock();
for(int i = 0;i<dwLength;i++)
{
pDlg->m_dequeRevData.push_back(data[i]);
}
pDlg->m_bRevCS.Unlock();
pDlg->PostMessage(WM_RECEIVE,0,0);
}
}
}
}
//////////////////////////////////////////////////////////////////
return 0;
}
void CSerialAsDlg::OnBtnopenport()
{
// TODO: Add your control notification handler code here
CString sPort;
DWORD dwBaudRate;
BYTE byDataBits;
BYTE byParity;
BYTE byStopBits;
m_ConfigPort.GetParam(sPort,dwBaudRate,byDataBits,byParity,byStopBits);
m_hCom = m_Port.OpenPort(sPort,dwBaudRate,byDataBits,byParity,byStopBits);
if(m_hCom)
{
EnableCtrl(FALSE);
UpdateStatusBar();
m_bRun = TRUE;
SetTimer(TIME_ID_REV,50,NULL);
AfxBeginThread(RevThreadProc,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
AfxBeginThread(SendThreadProc,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
////////////////////////////////////
CString str;
GetDlgItem(IDC_EDITSENDFILEPATH)->GetWindowText(str);
CFile file;
if(!file.Open(str,CFile::modeRead,NULL))
return;
m_dwSendFileLen = file.GetLength();
if(m_dwSendFileLen<1024)
str.Format(_T("文件大小:%d字节,发送时间:%d秒"),m_dwSendFileLen, int(m_dwSendFileLen/GetByteRate()+1));
else if(m_dwSendFileLen>1024&&m_dwSendFileLen<1024*1024)
str.Format(_T("文件大小:%.1fK,发送时间:%d秒"),m_dwSendFileLen/1024.0, int(m_dwSendFileLen/GetByteRate()));
else
str.Format(_T("文件大小:%.2fM,发送时间:%d秒"),m_dwSendFileLen/1024.0/1024.0, int(m_dwSendFileLen/GetByteRate()));
this->UpdateStatusBarInfo(m_StatusBar,1,str);
file.Close();
}
else
{
CString str = m_Port.GetError();
MessageBox(str,_T("串口打开失败!"),MB_ICONERROR);
}
}
void CSerialAsDlg::EnableCtrl(BOOL bFlag)
{
GetDlgItem(IDC_BTNOPENPORT)->EnableWindow(bFlag);
GetDlgItem(IDC_BTNCLOSEPORT)->EnableWindow(!bFlag);
GetDlgItem(IDC_BTNPORTCONFIG)->EnableWindow(bFlag);
GetDlgItem(IDC_CHECKAUTOSEND)->EnableWindow(!bFlag);
GetDlgItem(IDC_STARTSENDFILE)->EnableWindow(!bFlag);
GetDlgItem(IDC_MANUALSEND)->EnableWindow(!bFlag);
}
void CSerialAsDlg::OnBtncloseport()
{
// TODO: Add your control notification handler code here
m_bRun = FALSE;
if(m_Port.ClosePort())
{
m_hCom = NULL;
EnableCtrl(TRUE);
UpdateStatusBar();
KillTimer(TIME_ID_REV);
::SetEvent(m_hSendEvent);
}
else
{
AfxMessageBox(" Fatal Error!");
}
}
void CSerialAsDlg::UpdateStatusBar()
{
CString sPort;
CString sBaudRate;
CString sDataBits;
CString sParity;
CString sStopBits;
m_ConfigPort.GetParamString(sPort,sBaudRate,
sDataBits,sParity,sStopBits);
CString sStatus;
if(m_hCom!=NULL)
{
sStatus = _T("Opened");
}
else
{
sStatus = _T("Closed");
}
CString str;
str = sPort+_T(",")+sStatus+_T(",") +CString(sBaudRate)+_T(",")
+sDataBits+_T(",")+sParity+_T(",")+sStopBits;
UpdateStatusBarInfo(m_StatusBar,0,str);
if(m_hCom)
{
m_StatusBar.GetStatusBarCtrl().SetIcon(0,NULL);
m_StatusBar.GetStatusBarCtrl().SetIcon(0,m_hIconOpened);
}
else
{
m_StatusBar.GetStatusBarCtrl().SetIcon(0,NULL);
m_StatusBar.GetStatusBarCtrl().SetIcon(0,m_hIconClosed);
}
}
//更新状态栏的信息
void CSerialAsDlg::UpdateStatusBarInfo(CStatusBar &statusBar,int nIndex,LPCTSTR lpszNewText)
{
char text[256];
sprintf(text,"%s",lpszNewText);
m_StatusBar.SetPaneText(nIndex,text);
/* CFont font,*pOldFont;
font.CreateFont(-15,0,0,0,500,FALSE,FALSE,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,
DEFAULT_PITCH|FF_SWISS,"宋体");
CDC *pDC = m_StatusBar.GetDC();
COLORREF color = RGB_BTNFACE;
CBrush brush,pOldBrush;
brush.CreateSolidBrush(color);
CRect rect;
rect = m_StatusBar.GetBorders();
// pOldBrush = pDC->SelectObject(&brush);
pDC->FillRect(&rect,&brush);
pOldFont = pDC->SelectObject(&font);
pDC->SetTextColor(RGB(255,0,0));
pDC->SetBkMode(1);
pDC->TextOut(0,4,lpszNewText);
pDC->SelectObject(pOldFont);
ReleaseDC(pDC);*/
}
void CSerialAsDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==TIME_ID_TIME)
{
CString str;
SYSTEMTIME st;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -