现在的位置: 首页 > 综合 > 正文

S 串口编程 详解6 串口调试助手整个程序代码

2013年02月15日 ⁄ 综合 ⁄ 共 21892字 ⁄ 字号 评论关闭

S  串口编程 详解6 串口调试助手整个程序代码

CSerialPort类的代码见   串口编程 详解2   CSerialPort类   (SerialPort.h头文件和SerialPort.ccp实现文件)http://blog.csdn.net/gdliweibing/article/details/13629129

SCOMMDlg.h : header file

// SCOMMDlg.h : header file
//

#if !defined(AFX_SCOMMDLG_H__B37E2B99_040C_4C9E_827B_240E2F02C66E__INCLUDED_)
#define AFX_SCOMMDLG_H__B37E2B99_040C_4C9E_827B_240E2F02C66E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "SerialPort.h"
#include "PushPin.h"
/////////////////////////////////////////////////////////////////////////////
// CSCOMMDlg dialog

class CSCOMMDlg : public CDialog
{
// Construction
public:
	char HexChar(char c);
	int Str2Hex(CString str,char* data);
	CSCOMMDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	//{{AFX_DATA(CSCOMMDlg)
	enum { IDD = IDD_SCOMM_DIALOG };
	CButton	m_ctrlNewLine;
	CComboBox	m_ctrlPartity;
	CComboBox	m_ctrlStopbits;
	CComboBox	m_ctrlDatabits;
	CComboBox	m_ctrlPort;
	CComboBox	m_ctrlBaud;
	CEdit	m_ctrlEditSendFile;
	CButton	m_ctrlSendFile;
	CButton	m_ctrlManualSend;
	CEdit	m_ctrlSavePath;
	CButton	m_ctrlAutoClear;
	CButton	m_ctrlHexReceieve;
	CButton	m_ctrlStopDisp;
	CStatic	m_ctrlRXCOUNT;
	CStatic	m_ctrlTXCount;
	CButton	m_ctrlHexSend;
	CEdit	m_ctrlReciveData;
	CButton	m_ctrlAutoSend;
	CComboBox	m_ctrlDataBits;
	CComboBox	m_ctrlSpeed;
	CComboBox	m_ctrlCom;
	CStatic	m_ctrlIconOpenoff;
	CStatic	m_ctrlPortStatus;
	CButton	m_ctrlOpenPort;
	CString	m_strCom;
	CString	m_strSpeed;
	CString	m_strDataBits;
	CString	m_strReceiveData;
	CString	m_strSendData;
	int		m_nCycleTime;
	CString	m_StrCurPath;
	CString	m_strSendFilePathName;
	CString	m_strEditSendFile;
	CString	m_strBaud;
	CString	m_strPort;
	CString	m_strPartity;
	CString	m_strStopbits;
	CString	m_strDatabits;
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CSCOMMDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
	private:
		BOOL m_bOpenPort;
		CSerialPort m_Port;

		UINT m_nCom;
		UINT m_nBaud;
		CHAR m_cParity;
		UINT m_nDatabits;
		UINT m_nStopbits;
		DWORD m_dwCommEvents;

		HICON m_hIconRed;
		HICON m_hIconOff;

		BOOL m_bAutoSend;
		BOOL m_bStopDispRXData;

		//下面是关于文件发送的一些变量
		BOOL m_bSendFile;
		UINT m_nFileLength;
		CString m_strTempSendFilePathName;

		BOOL m_bVisible;



protected:
	HICON m_hIcon;

	// Generated message map functions
	//{{AFX_MSG(CSCOMMDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg LONG OnCommunication(WPARAM ch,LPARAM port);  
	afx_msg void OnButtonOpenport();
	afx_msg void OnDestroy();
	afx_msg void OnButtonManualsend();
	afx_msg void OnTimer(UINT nIDEvent);
	afx_msg void OnCheckAutosend();
	afx_msg void OnChangeEditCycletime();
	afx_msg void OnChangeEditSend();
	afx_msg void OnButtonStopdisprxdata();
	afx_msg void OnButtonClearreciarea();
	afx_msg void OnButtonSavedata();
	afx_msg void OnButtonDirbrowser();
	afx_msg void OnButtonFilebrowser();
	afx_msg void OnButtonSendfile();
    afx_msg LONG OnFileSendingEnded(WPARAM wParam,LPARAM port);
	afx_msg void OnSelendokComboComselect();
	afx_msg void OnSelendokComboDatabits();
	afx_msg void OnSelendokComboParity();
	afx_msg void OnSelendokComboStopbits();
	afx_msg void OnButtonCountreset();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};



//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SCOMMDLG_H__B37E2B99_040C_4C9E_827B_240E2F02C66E__INCLUDED_)

SCOMMDlg.cpp : implementation file

// SCOMMDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SCOMM.h"
#include "SCOMMDlg.h"

#include <io.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()



/////////////////////////////////////////////////////////////////////////////
// CSCOMMDlg dialog

CSCOMMDlg::CSCOMMDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSCOMMDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSCOMMDlg)
	m_strReceiveData = _T("");
	m_strSendData = _T("");
	m_StrCurPath = _T("");
	m_strEditSendFile = _T("");
	m_strBaud = _T("");
	m_strPort = _T("");
	m_strPartity = _T("");
	m_strStopbits = _T("");
	m_strDatabits = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	m_bOpenPort=FALSE;
	m_nCom=1;
	m_nBaud=115200;
	m_cParity='N';
	m_nDatabits=8;
	m_nStopbits=1;
	m_dwCommEvents=EV_RXCHAR;
	m_hIconOff=AfxGetApp()->LoadIcon(IDI_ICON_OFF);
	m_hIconRed=AfxGetApp()->LoadIcon(IDI_ICON_RED);

	m_bAutoSend=FALSE;
	m_nCycleTime=1000;

	m_bStopDispRXData=FALSE;
	m_bSendFile=FALSE;
//	m_ctrlStopDisp.SetWindowText("停止显示");//这句是不能放在这里的。因为对话框还没有建立起来,当然对话框中的按钮等也没有建立

	m_StrCurPath="C:\\DataCom";

	m_bVisible=FALSE;
}

void CSCOMMDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//数据映射(按钮、编辑框 与 变量的映射)
	//{{AFX_DATA_MAP(CSCOMMDlg)
	DDX_Control(pDX, IDC_CHECK_NEWLINE, m_ctrlNewLine);
	DDX_Control(pDX, IDC_COMBO_PARITY, m_ctrlPartity);
	DDX_Control(pDX, IDC_COMBO_STOPBITS, m_ctrlStopbits);
	DDX_Control(pDX, IDC_COMBO_DATABITS, m_ctrlDatabits);
	DDX_Control(pDX, IDC_COMBO_COMSELECT, m_ctrlPort);
	DDX_Control(pDX, IDC_COMBO_SPEED, m_ctrlBaud);
	DDX_Control(pDX, IDC_EDIT_SENDFILE, m_ctrlEditSendFile);
	DDX_Control(pDX, IDC_BUTTON_SENDFILE, m_ctrlSendFile);
	DDX_Control(pDX, IDC_BUTTON_MANUALSEND, m_ctrlManualSend);
	DDX_Control(pDX, IDC_EDIT_SEND, m_ctrlSavePath);
	DDX_Control(pDX, IDC_CHECK_AUTOCLEAR, m_ctrlAutoClear);
	DDX_Control(pDX, IDC_CHECK_HEXRECIEVE, m_ctrlHexReceieve);
	DDX_Control(pDX, IDC_BUTTON_STOPDISPRXDATA, m_ctrlStopDisp);
	DDX_Control(pDX, IDC_STATIC_RXCOUNT, m_ctrlRXCOUNT);
	DDX_Control(pDX, IDC_STATIC_TXCOUNT, m_ctrlTXCount);
	DDX_Control(pDX, IDC_CHECK_HEXSEND, m_ctrlHexSend);
	DDX_Control(pDX, IDC_EDIT_RECIEVE, m_ctrlReciveData);
	DDX_Control(pDX, IDC_CHECK_AUTOSEND, m_ctrlAutoSend);
	DDX_Control(pDX, IDC_STATIC_OPENOFF, m_ctrlIconOpenoff);
	DDX_Control(pDX, IDC_STATIC_STATUS, m_ctrlPortStatus);
	DDX_Control(pDX, IDC_BUTTON_OPENPORT, m_ctrlOpenPort);
	DDX_Text(pDX, IDC_EDIT_RECIEVE, m_strReceiveData);
	DDX_Text(pDX, IDC_EDIT_SEND, m_strSendData);
	DDX_Text(pDX, IDC_EDIT_CYCLETIME, m_nCycleTime);
	DDX_Text(pDX, IDC_EDIT_SAVE_PATH, m_StrCurPath);
	DDX_Text(pDX, IDC_EDIT_SENDFILE, m_strEditSendFile);
	DDX_CBString(pDX, IDC_COMBO_SPEED, m_strBaud);
	DDX_CBString(pDX, IDC_COMBO_COMSELECT, m_strPort);
	DDX_CBString(pDX, IDC_COMBO_PARITY, m_strPartity);
	DDX_CBString(pDX, IDC_COMBO_STOPBITS, m_strStopbits);
	DDX_CBString(pDX, IDC_COMBO_DATABITS, m_strDatabits);
	//}}AFX_DATA_MAP
}

//消息映射
BEGIN_MESSAGE_MAP(CSCOMMDlg, CDialog)
	//{{AFX_MSG_MAP(CSCOMMDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_MESSAGE(WM_COMM_RXCHAR,OnCommunication)
	ON_BN_CLICKED(IDC_BUTTON_OPENPORT, OnButtonOpenport)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTON_MANUALSEND, OnButtonManualsend)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_CHECK_AUTOSEND, OnCheckAutosend)
	ON_EN_CHANGE(IDC_EDIT_CYCLETIME, OnChangeEditCycletime)
	ON_EN_CHANGE(IDC_EDIT_SEND, OnChangeEditSend)
	ON_BN_CLICKED(IDC_BUTTON_STOPDISPRXDATA, OnButtonStopdisprxdata)
	ON_BN_CLICKED(IDC_BUTTON_CLEARRECIAREA, OnButtonClearreciarea)
	ON_BN_CLICKED(IDC_BUTTON_SAVEDATA, OnButtonSavedata)
	ON_BN_CLICKED(IDC_BUTTON_DIRBROWSER, OnButtonDirbrowser)
	ON_BN_CLICKED(IDC_BUTTON_FILEBROWSER, OnButtonFilebrowser)
	ON_BN_CLICKED(IDC_BUTTON_SENDFILE, OnButtonSendfile)
	ON_CBN_SELENDOK(IDC_COMBO_COMSELECT, OnSelendokComboComselect)
	ON_CBN_SELENDOK(IDC_COMBO_DATABITS, OnSelendokComboDatabits)
	ON_CBN_SELENDOK(IDC_COMBO_PARITY, OnSelendokComboParity)
	ON_CBN_SELENDOK(IDC_COMBO_STOPBITS, OnSelendokComboStopbits)
	ON_BN_CLICKED(IDC_BUTTON_COUNTRESET, OnButtonCountreset)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//ON_MESSAGE(WM_COMM_TXEMPTY_DETECTED,OnFileSendingEnded)
static long count=0;
static long rxdatacount=0;
//注意这个 afx_msg LONG OnCommunication(WPARAM ch,LPARAM port); 和ON_MESSAGE(WM_COMM_RXCHAR,OnCommunication)映射的产生
LONG CSCOMMDlg::OnCommunication(WPARAM ch,LPARAM port)
{
	if(port<=0||port>=10)
		return -1;
	rxdatacount++;//接收字节计数

	CString strTemp;
	strTemp.Format("%ld",rxdatacount);
	strTemp="RX:"+strTemp;
	m_ctrlRXCOUNT.SetWindowText(strTemp);//显示计数

	if(m_bStopDispRXData)//如果选择了 停止显示 接收数据,则返回
		return -1;

	//若设置了 自动清空 则达到50行后,自动清空接收编辑框中显示的数据
	if((m_ctrlAutoClear.GetCheck())&&(m_ctrlReciveData.GetLineCount()>=50))
	{
		m_strReceiveData.Empty();//??????????????
		UpdateData(FALSE);
		if(count==0)
		{
			count++;
		}
	}


	//若没设置了 自动清空 则达到400行后,也自动清空接收编辑框中显示的数据
	if(m_ctrlReciveData.GetLineCount()>=400)
	{
		m_strReceiveData.Empty();//??????????????
		m_strReceiveData="***The Length of the text is too long ,Emptied Automaticly!!!***\r\n";
		UpdateData(FALSE);

	}

	//如果选择了“十六进制显示”,则显示十六进制值
	CString str;

	if(m_ctrlHexReceieve.GetCheck())
		str.Format("%2X",ch);
	else
		str.Format("%c",ch);

	//以下是将接收的字符加在字符串的最后,这里费时多
	//但考虑到数据需要保存成文件,所以没有用List Control();
	int nLen=m_ctrlReciveData.GetWindowTextLength();
	m_ctrlReciveData.SetSel(nLen,nLen);//?????????
	m_ctrlReciveData.ReplaceSel(str);//??????????
	nLen+=str.GetLength();

	m_strReceiveData+=str;
	if(m_ctrlNewLine.GetCheck())
	{
		m_strReceiveData=m_strReceiveData+"\r\n";//自动换行
	}
	UpdateData(FALSE);
	return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CSCOMMDlg message handlers

BOOL CSCOMMDlg::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_bOpenPort=FALSE;
	m_nCom=1;
	m_nBaud=115200;
	m_cParity='N';
	m_nDatabits=8;
	m_nStopbits=1;
	m_dwCommEvents=EV_RXCHAR||EV_RXFLAG;//串口事件

	CString strStatus;
	if(m_Port.InitPort(this,m_nCom,m_nBaud,m_cParity,m_nDatabits,m_nStopbits,m_dwCommEvents,512))
	{
		m_Port.StartMonitoring();  //启动检测辅助线程
		m_ctrlIconOpenoff.SetIcon(m_hIconRed);
		strStatus.Format("STATUS: COM %d OPENED, %d, %c, %d, %d",m_nCom,m_nBaud,m_cParity,m_nDatabits,m_nStopbits);
		//当前的状态                  端口号     奇偶 数据位  停止位
		m_ctrlOpenPort.SetWindowText("关闭串口");
			m_bOpenPort=TRUE;
	}
	else
	{
		AfxMessageBox("没有发现该串口或 已被占用");
		m_ctrlIconOpenoff.SetIcon(m_hIconOff);
			m_bOpenPort=FALSE;
	}
		m_ctrlPortStatus.SetWindowText(strStatus);

		m_ctrlStopDisp.SetWindowText("停止显示");
		
		//端口的初始化
		m_ctrlPort.SetCurSel(0);
		m_ctrlPort.GetWindowText(m_strPort);
		//波特率的初始化
		m_ctrlBaud.InsertString(0,_T("4800"));
		m_ctrlBaud.InsertString(1,_T("14400"));
		m_ctrlBaud.InsertString(2,_T("19200"));
		m_ctrlBaud.InsertString(3,_T("38400"));
		m_ctrlBaud.InsertString(4,_T("56000"));
		m_ctrlBaud.InsertString(5,_T("57600"));
		m_ctrlBaud.InsertString(6,_T("115200"));
	//	m_ctrlBaud.InsertString(7,_T("128000"));
	//	m_ctrlBaud.InsertString(8,_T("256000"));
		m_ctrlBaud.SetCurSel(6);
		m_ctrlBaud.GetWindowText(m_strBaud);
		//校验初始化
		m_ctrlPartity.SetCurSel(0);
		m_ctrlPartity.GetWindowText(m_strPartity);
		//数据位初始化
		m_ctrlDatabits.SetCurSel(0);
		m_ctrlDatabits.GetWindowText(m_strDatabits);
		//停止位
		m_ctrlStopbits.SetCurSel(0);
		m_ctrlStopbits.GetWindowText(m_strStopbits);
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSCOMMDlg::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 CSCOMMDlg::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 CSCOMMDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


//打开/关闭串口
void CSCOMMDlg::OnButtonOpenport() 
{
	if(m_bOpenPort)//串口先是打开的,现在点击按钮进行关闭
	{
		if(m_ctrlAutoSend.GetCheck())
		{
			m_bOpenPort=!m_bOpenPort;
			AfxMessageBox("请先关掉自动发送");
			return;
		}
		m_ctrlOpenPort.SetWindowText("打开串口");
		m_Port.ClosePort();//关闭串口
		m_ctrlPortStatus.SetWindowText("STATUS: COM Port Close");
		m_ctrlIconOpenoff.SetIcon(m_hIconOff);
		m_bOpenPort=FALSE;
	}
	else//打开串口
	{
		m_ctrlOpenPort.SetWindowText("关闭串口");
		CString strStatus;
		//	BOOL  InitPort(CWnd* pPortOwner, UINT portnr = 1, UINT baud = 19200, \
		char parity = 'N', UINT databits = 8, UINT stopbits = 1, DWORD dwCommEvents = EV_RXCHAR, UINT writebuffersize = 1024);
		if(m_Port.InitPort(this,m_nCom,m_nBaud,m_cParity,m_nDatabits,m_nStopbits,m_dwCommEvents,512))
		{
			m_Port.StartMonitoring();
			m_ctrlIconOpenoff.SetIcon(m_hIconRed);
			strStatus.Format("STATUS: COM %d OPENED, %d, %c, %d, %d",m_nCom,m_nBaud,m_cParity,m_nDatabits,m_nStopbits);
			//当前的状态                 端口号     奇偶 数据位  停止位
				m_bOpenPort=TRUE;
		}
		else
		{
			AfxMessageBox("没有发现该串口或 已被占用");
			m_ctrlIconOpenoff.SetIcon(m_hIconOff);
				m_bOpenPort=FALSE;
		}
		m_ctrlPortStatus.SetWindowText(strStatus);
	}	
}


void CSCOMMDlg::OnDestroy() 
{
	CDialog::OnDestroy();
		m_ctrlAutoSend.SetCheck(0);//强行关闭自动发送
		KillTimer(1);
		KillTimer(4);
		m_Port.ClosePort();//关闭串口
		m_strReceiveData.Empty();//清空接收数据字符串
}


//将一个字符串作为十六进制串转化为一个字节数组,字节间可用空格分隔
//返回转换后的字节数组长度,同时字节数组长度自动设置
//将 一串十六进制数转换为字符串(原理:两个十六进制数转化为一个字符  )
int CSCOMMDlg::Str2Hex(CString str, char *data)
{
	int t,t1;
	int rlen=0,len=str.GetLength();

	for (int i=0;i<len;)
	{
		char l,h=str[i];//高位

		if(h==' ')
		{
			i++;
			continue;
		}

		i++;
		if(i>=len)
			break;

		l=str[i];//低位
		t=HexChar(h);
		t1=HexChar(l);

		if((t==16)||(t1==16))
			break;
		else
			t=t*16+t1;
		i++;
		data[rlen]=(char)t;
		rlen++;
	}
	return rlen;
}

char CSCOMMDlg::HexChar(char c)
{
	if((c>='0')&&(c<='9'))
		return c-0x30;
	else if((c>='A')&&(c<='F'))
		return c-'A'+10;
	else if((c>'a')&&(c<'f'))
		return c-'a'+10;
	else 
		return 0x10;
}



void CSCOMMDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	switch (nIDEvent)
	{
	case 1: //定时器ID==1为自动发送时间
		OnButtonManualsend();   //周期到后自动发送
		break;
	case 2:
		m_ctrlSavePath.SetWindowText(m_StrCurPath);//重新显示路径
		KillTimer(2);//关闭定时器
		break;
	case 3:
		m_ctrlManualSend.EnableWindow(TRUE);
		m_ctrlAutoSend.EnableWindow(TRUE);
		m_ctrlSendFile.EnableWindow(TRUE);
		m_strSendFilePathName=m_strTempSendFilePathName;
		
		KillTimer(3);
		if(!(m_ctrlAutoSend.GetCheck()))
		{
			CString strStatus;
			if(m_Port.InitPort(this,m_nCom,m_nBaud,m_cParity,m_nDatabits,m_nStopbits,m_dwCommEvents,512))
			{
				m_Port.StartMonitoring();
				strStatus.Format("STATUS: COM %d OPENED, %d, %c, %d, %d",m_nCom,m_nBaud,m_cParity,m_nDatabits,m_nStopbits);
				m_ctrlIconOpenoff.SetIcon(m_hIconRed );

			}
			else
			{
				AfxMessageBox("Failed to reset send buffer size!");
				m_ctrlIconOpenoff.SetIcon(m_hIconOff);
			}
			m_ctrlPortStatus.SetWindowText(strStatus);
		}
		break;
	default:
		break;
	}
	CDialog::OnTimer(nIDEvent);
}

void CSCOMMDlg::OnCheckAutosend() 
{
	m_bAutoSend=!m_bAutoSend;
	if(m_bAutoSend)
	{
		if(m_Port.m_hComm==NULL)
		{
			m_bAutoSend=!m_bAutoSend;
			m_ctrlAutoSend.SetCheck(0);
			AfxMessageBox("串口没打开,请打开串口");
			return ;
		}
		else
			SetTimer(1,m_nCycleTime,NULL);
	}
	else
	{
		KillTimer(1);//杀掉定时器1
	}
}



void CSCOMMDlg::OnChangeEditCycletime() 
{
	CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT_CYCLETIME);
	CString strText;
	pEdit->GetWindowText(strText);
	m_nCycleTime=atoi(strText);
}

void CSCOMMDlg::OnChangeEditSend() 
{
	UpdateData(TRUE);
}

//停止/继续显示
void CSCOMMDlg::OnButtonStopdisprxdata() 
{
	// TODO: Add your control notification handler code here
	m_bStopDispRXData=!m_bStopDispRXData;
	if(m_bStopDispRXData)
		m_ctrlStopDisp.SetWindowText("继续显示");
	else
		m_ctrlStopDisp.SetWindowText("停止显示");
}

//清空接收区
void CSCOMMDlg::OnButtonClearreciarea() 
{
	// TODO: Add your control notification handler code fere
	m_strReceiveData.Empty();
	UpdateData(FALSE);        
}

//接收到的数据在文件中进行保存
void CSCOMMDlg::OnButtonSavedata() 
{
	UpdateData(TRUE);//由屏幕到 内存的
	int nLength;
    nLength=m_StrCurPath.GetLength();
	for(int nCount=0;nCount<nLength;nCount++)
	{
		if(m_StrCurPath.GetAt(nCount)=='\\')
		{		
			CreateDirectory(m_StrCurPath.Left(nCount+1),NULL);
		}
	}
	CreateDirectory(m_StrCurPath,NULL);
	CFile m_rFile;
	//LPCSTR是Win32和VC++所使用的一种字符串数据类型。LPCSTR被定义成是一个指向以NULL(‘\0’)结尾的常量字符的指针。
	LPCSTR lpszPath=m_StrCurPath;// "C:\\comdata"
	SetCurrentDirectory(lpszPath);
	
	//文件为Rec**.txt,一下的代码自动检测文件名是否存在,若存在,则后面序号自动增加
	char buf[200];
	for(int j=0;j<100;j++)
	{
		sprintf(buf,"Rec%02d.txt",j);
		if((access(buf,0))==-1)
			break;
	}

	if(!m_rFile.Open(buf,CFile::modeCreate|CFile::modeWrite))//我的天呀:这里写成这样的CFile::modeCreate||File::modeWrite
	{
	AfxMessageBox("创建文件记录文件失败");
		return ;
	}

	if((access(buf,0))==-1)
	{
		AfxMessageBox("failed");
		return ;
	}

	//在文件开始处写上保存日期
	CTime t=CTime::GetCurrentTime();
	CString str=t.Format("%Y年 %m月 %d日 %H时 %M 分 %S秒\r\n");
	m_rFile.Write((LPCTSTR)str,str.GetLength());

	//保存显示数据
	m_rFile.Write((LPCTSTR)m_strReceiveData,m_strReceiveData.GetLength());
	m_rFile.Flush();//????????
	m_rFile.Close();//关闭文件

	str="OK";
	for(int i=0;i<5;i++)
		str+=buf[i];
	str+=".txt saved";
	m_ctrlSavePath.SetWindowText(str);	
	SetTimer(2,5000,NULL);//在定时器中显示保存文件状态	
}

void CSCOMMDlg::OnButtonDirbrowser() 
{
	
	static char displayname[MAX_PATH];
	static char path[MAX_PATH];

/*	typedef LPITEMIDLIST *ITEMIDLIST;
	
	typedef struct _ITEMIDLIST {
		SHITEMID mkid;
	} ITEMIDLIST;
	
	typedef struct _SHITEMID {
		USHORT cb;
		BYTE abID[1];
} SHITEMID;*/
	LPITEMIDLIST pidlBrowse; //PIDL selected by user

	BROWSEINFO bi;//????
	bi.hwndOwner=this->m_hWnd;//获得窗口自己的句柄
	bi.pidlRoot=NULL;  
	bi.pszDisplayName= displayname;
	bi.lpszTitle ="请选择保存接收数据的文件夹";
	bi.ulFlags=BIF_EDITBOX;
	bi.lpfn=NULL;
	pidlBrowse=SHBrowseForFolder(&bi);
	
	if(pidlBrowse!=NULL)
	{

		SHGetPathFromIDList(pidlBrowse,path);
	}
	AfxMessageBox("2");
	CString str=path;//得到路径
	if(str.IsEmpty())   //没选择则返回
		return ;        
	m_StrCurPath=str; //接收路径编辑框对应的变量
	UpdateData(FALSE);
}

//下面代码是实现文件的小发送
//选择要发送的文件
void CSCOMMDlg::OnButtonFilebrowser() 
{
	// TODO: Add your control notification handler code here
	LPCTSTR lpszPath="c:\\comdata";
	SetCurrentDirectory(lpszPath);

	static char BASED_CODE szFilter[]="文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||";
	
	CFileDialog FileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);
	FileDlg.m_ofn.lpstrInitialDir=lpszPath;

	if(FileDlg.DoModal()==IDOK)
	{
		CString strFileName =FileDlg.GetFileName();
		CString strFileExt =FileDlg.GetFileExt();
		CString lpstrName  =FileDlg.GetPathName();
		m_strSendFilePathName=lpstrName;
		UpdateData(FALSE);
	}
}


//发送文件
void CSCOMMDlg::OnButtonSendfile() 
{
	// TODO: Add your control notification handler code here
	CFile fp;
	if(!(fp.Open((LPCSTR)m_strSendFilePathName,CFile::modeRead)))
	{
		AfxMessageBox("Open file failed!");
		return ;
	}
	fp.SeekToEnd();
	unsigned long fplength=fp.GetLength();
	m_nFileLength=fplength;
	char* fpBuff;
	fpBuff =new char[fplength];
	fp.SeekToBegin();
	if(fp.Read(fpBuff,fplength)<1)
	{
		fp.Close();
		return ;
	}
	fp.Close();
	
	CString strStatus;
	
	if(m_Port.InitPort(this,m_nCom,m_nBaud,m_cParity,m_nDatabits,m_nStopbits,m_dwCommEvents,fplength))
	{
		
		m_Port.StartMonitoring();
		strStatus.Format("STATUS: COM%d OPENED, %d, %c, %d, %d",m_nCom,m_nBaud,m_cParity,m_nDatabits,m_nStopbits);
		m_ctrlIconOpenoff.SetIcon(m_hIconRed);
		m_bSendFile=TRUE;
		//	m_strTempSendFilePathName=m_strSendFilePathName;
		m_ctrlEditSendFile.SetWindowText("正在发送......");
		
		//发送文件时,一下功能不能使用
		m_ctrlManualSend.EnableWindow(FALSE);
		m_ctrlAutoSend.EnableWindow(FALSE);
		m_ctrlSendFile.EnableWindow(FALSE);
		m_Port.WriteToPort((LPCSTR)fpBuff,fplength);
	}
	else
	{
		AfxMessageBox("Failed to send file!");
		m_ctrlIconOpenoff.SetIcon(m_hIconOff);
	}
	delete fpBuff;
}

//手动发送
long TX_count=0;
void CSCOMMDlg::OnButtonManualsend() 
{
	if(m_Port.m_hComm==NULL)//发送数据时要检查串口是否被打开
	{
		m_ctrlAutoSend.SetCheck(0);
		AfxMessageBox("串口没有打开,请打开串口");
		return ;
	}
	else
	{
		UpdateData(TRUE);
		if(m_ctrlHexSend.GetCheck())//发送十六进制数
		{		
			char data[512];		
			int len=Str2Hex(m_strSendData,data);//将一个字符串转换为十六进制数 发送
			m_Port.WriteToPort(data,len);
			CString str;
			str.Format("%d",len);
			AfxMessageBox(str);
			for(int i=0;i<len;i++)
				OnCommunication(data[i],1);
			TX_count+=(long)((m_strSendData.GetLength()+1)/3);//?????????????
		}
		else//发送ASCII文本
		{
			m_Port.WriteToPort((LPCTSTR)m_strSendData);//发送数据
				char data[512];
	
			strcpy(data,m_strSendData);
			int len=m_strSendData.GetLength();
			for(int i=0;i<len;i++)
				OnCommunication(data[i],1);
			TX_count+=m_strSendData.GetLength();
		}
		CString strTemp;
		strTemp.Format("TX: %d",TX_count);
		m_ctrlTXCount.SetWindowText(strTemp);//显示计数		
	//	WPARAM ch='a';
	//	OnCommunication(ch,1);	
	}	
		  CFile m_rFile;
		  //LPCSTR是Win32和VC++所使用的一种字符串数据类型。LPCSTR被定义成是一个指向以NULL(‘\0’)结尾的常量字符的指针。
		  LPCSTR lpszPath=m_StrCurPath;// "C:\\comdata"
		  SetCurrentDirectory(lpszPath);		  
}

LONG CSCOMMDlg::OnFileSendingEnded(WPARAM wParam,LPARAM port)
{
	if(m_bSendFile)
	{
		m_ctrlEditSendFile.SetWindowText("发送完毕!");//
		TX_count+=m_nFileLength;
		SetTimer(3,3000,NULL);
		CString strTemp;
		strTemp.Format("TX: %d ",TX_count);
		m_ctrlTXCount.SetWindowText(strTemp);

	}
	return 0;
}

/*void CSCOMMDlg::OnButtonPushpin() 
{
	// TODO: Add your control notification handler code here
//	m_ctrlPushPin.ProcessClick();
	m_bVisible=!m_bVisible;

	if(m_bVisible)
	{
		SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
	}
	else
	{
		SetWindowPos(&wndBottom,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOREDRAW);
		BringWindowToTop();
	}
}*/





void CSCOMMDlg::OnSelendokComboComselect() 
{
	int index=m_ctrlPort.GetCurSel();
	m_ctrlPort.SetCurSel(index);
	m_nCom=index+1;
/*	if(m_nCom>4)
	{
		m_nCom=1;
		m_ctrlPort.SetCurSel(0);
	}*/
	if(	m_bOpenPort==TRUE)
	{
		m_bOpenPort=FALSE;
		OnButtonOpenport();
	}
}




void CSCOMMDlg::OnSelendokComboDatabits() 
{
	int index=m_ctrlDatabits.GetCurSel();
	m_ctrlDatabits.SetCurSel(index);
	m_nDatabits=index+5;	
	if(	m_bOpenPort==TRUE)
	{
		m_bOpenPort=FALSE;
		OnButtonOpenport();
	}
}

//
void CSCOMMDlg::OnSelendokComboParity() 
{
	int index=m_ctrlPartity.GetCurSel();
	m_ctrlPartity.SetCurSel(index);
	switch(index)
	{
	/*	NONE
			ODD
			EVEN
			MARK
			SPACE*/
	case 0:
		m_cParity='N';
		break;
	case 1:
		m_cParity='O';
		break;
	case 2:
		m_cParity='E';
		break;
	case 3:
		m_cParity='M';
		break;
	case 4:
		m_cParity='S';
		break;
	default:
		m_cParity='N';
		break;
	}
	if(	m_bOpenPort==TRUE)
	{
		m_bOpenPort=FALSE;
		OnButtonOpenport();
	}	
}

//停止位 
void CSCOMMDlg::OnSelendokComboStopbits() 
{
	int index=m_ctrlStopbits.GetCurSel();
    m_ctrlStopbits.SetCurSel(index);
	m_ctrlStopbits.GetWindowText(m_strStopbits);
	m_nStopbits=atoi(m_strStopbits);
	if(	m_bOpenPort==TRUE)
	{
		m_bOpenPort=FALSE;
		OnButtonOpenport();
	}	
}

void CSCOMMDlg::OnButtonCountreset() 
{
	// TODO: Add your control notification handler code here
	TX_count=0;
	rxdatacount=0;
}

抱歉!评论已关闭.