⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialasdlg.cpp

📁 这是我仿照串口助手(龚建伟)作的一个例子并修正了其中的一些bug
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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 + -