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

📄 serialportdlg.cpp

📁 利用VC++实现PC通过串口收发手机短消息
💻 CPP
字号:
// SerialPortDlg.cpp : implementation file
/*
 * 本程序模仿 秦林勇的rcc_kit 编写了串口通讯程序。
 *
 * created by chenyong 2006.10.25
 * 2007.04.25 调试sms 程序。
 */

#include "stdafx.h"
#include "SerialPort.h"
#include "SerialPortDlg.h"

#include "sms.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

HANDLE hCommEventArrive;
char smsResponseBuf[500];
unsigned int smsResponseBuf_length;

CListCtrl * lstCtrl;

void DisplayMessage(char * msg)
{
	_SYSTEMTIME st;

	GetLocalTime(&st);

	CString str;
	str.Format("%d-%d-%d %d:%d:%d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

	int nCurSel = lstCtrl->InsertItem(0xffff,"");
	lstCtrl->SetItem(nCurSel,0,LVIF_TEXT,str,NULL,0,0,0);
    lstCtrl->SetItem(nCurSel,1,LVIF_TEXT,msg,NULL,0,0,0);
}

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_BaudRate = 0;
	m_ByteSize = 0;
	m_Port = _T("");
	m_SendItems = _T("");
	m_Parity = _T("");
	m_StopBit = _T("");
	m_smsc = _T("");
	m_DestCellularNo = _T("");
	m_smsno = _T("");
	m_nCodeScheming = -1;
	//}}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_Control(pDX, IDC_comboStopBit, m_comboStopBit);
	DDX_Control(pDX, IDC_comboPort, m_comboPort);
	DDX_Control(pDX, IDC_comboParity, m_comboParity);
	DDX_Control(pDX, IDC_comboByteSize, m_comboByteSize);
	DDX_Control(pDX, IDC_comboBaudRate, m_comboBaudRate);
	DDX_Control(pDX, IDC_btnStopComm, m_btnStopComm);
	DDX_Control(pDX, IDC_btnStartComm, m_btnStartComm);
	DDX_Control(pDX, IDC_lstSentDatus, m_lstSentDatus);
	DDX_Control(pDX, IDC_lstReceivedDatus, m_lstReceivedDatus);
	DDX_Text(pDX, IDC_edtBaudRate, m_BaudRate);
	DDX_Text(pDX, IDC_edtByteSize, m_ByteSize);
	DDX_Text(pDX, IDC_edtPort, m_Port);
	DDX_Text(pDX, IDC_edtSendItems, m_SendItems);
	DDX_Text(pDX, IDC_edtParity, m_Parity);
	DDX_Text(pDX, IDC_edtStopBit, m_StopBit);
	DDX_Text(pDX, IDC_edtSMSC, m_smsc);
	DDX_Text(pDX, IDC_edtDestCellularNo, m_DestCellularNo);
	DDX_Text(pDX, IDC_edtSmsNo, m_smsno);
	DDX_Radio(pDX, IDC_radioCodeScheming_7bit, m_nCodeScheming);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSerialPortDlg, CDialog)
	//{{AFX_MSG_MAP(CSerialPortDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_btnUpdateCommStatus, OnbtnUpdateCommStatus)
	ON_BN_CLICKED(IDC_btnSend, OnbtnSend)
	ON_BN_CLICKED(IDC_btnStartComm, OnbtnStartComm)
	ON_BN_CLICKED(IDC_btnStopComm, OnbtnStopComm)
	ON_BN_CLICKED(IDC_btnListen, OnbtnListen)
	ON_BN_CLICKED(IDC_btnGsmInit, OnbtnGsmInit)
	ON_BN_CLICKED(IDC_btnCMGL, OnbtnCMGL)
	ON_BN_CLICKED(IDC_btnCMGR, OnbtnCMGR)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSerialPortDlg message handlers

BOOL CSerialPortDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	m_btnStopComm.EnableWindow(FALSE);
	::SendMessage(m_lstReceivedDatus.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
    ::SendMessage(m_lstSentDatus.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);

	//////////为列表控件添加列标题//////////
	m_lstReceivedDatus.InsertColumn(0,"time",LVCFMT_LEFT,120);
	m_lstReceivedDatus.InsertColumn(1,"content",LVCFMT_LEFT,560);
	
    m_lstSentDatus.InsertColumn(0,"time",LVCFMT_LEFT,120);
	m_lstSentDatus.InsertColumn(1,"content",LVCFMT_LEFT,350);

	m_comboBaudRate.SetCurSel(0);
	m_comboByteSize.SetCurSel(0);
	m_comboPort.SetCurSel(0);
	m_comboStopBit.SetCurSel(0);
	m_comboParity.SetCurSel(0);

	lstCtrl = & m_lstReceivedDatus;

	//assign initial values...
	m_hComm = NULL;

	m_smsc = "13800871500";
    
    m_nCodeScheming = 0;

	m_BaudRate = 57600;
	m_ByteSize = 8;
	m_Port = "com1";
	m_StopBit = "1";
	m_Parity = "None";
	UpdateData(FALSE);

	hCommEventArrive = INVALID_HANDLE;
	smsResponseBuf_length = 0;

	// 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
	
	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::OnbtnUpdateCommStatus() 
{
	// TODO: Add your control notification handler code here
	CString str;

	m_comboPort.GetWindowText(str);
	m_Port = str;
	m_comboBaudRate.GetWindowText(str);
	m_BaudRate = atoi(str);
    m_comboByteSize.GetWindowText(str);
    m_ByteSize = atoi(str);

	switch (m_comboStopBit.GetCurSel())
	{
	case 0:
		m_StopBit = "1";
		break;
	case 1:
		m_StopBit = "1.5";
		break;
	case 2:
		m_StopBit = "2";
		break;
	default:
		AfxMessageBox("Error StopBit.........");
	}

	switch (m_comboParity.GetCurSel())
	{
	case 0:
		m_Parity = "None";
		break;
	case 1:
		m_Parity = "Odd";
		break;
	case 2:
		m_Parity = "Even";
		break;
	default:
		AfxMessageBox("Error Parity.........");
	}
    UpdateData(FALSE);
}

void CSerialPortDlg::OnbtnSend() 
{
    SM_PARAM SmParam;

	int nPduLength;		// PDU串长度
	unsigned char nSmscLength;	// SMSC串长度
	char cmd[16];		// 命令串
	char pdu[512];		// PDU串

	if ( UpdateData() )
	{
		if (m_DestCellularNo.GetLength() == 0)
        {
			AfxMessageBox("请输入目标手机号。");
			return;
		}

		if (m_SendItems.GetLength() > 0)
		{
			if (m_SendItems.GetLength() > 70)
			{
				AfxMessageBox("超出最大字符数(70),请重新发送.");
				return;
			}

			if (m_hComm != NULL)
			{		
				memset(&SmParam, 0, sizeof(SM_PARAM));
				
				// 去掉号码前的"+"
	            if (m_smsc[0] == '+')
		            m_smsc = m_smsc.Mid(1);
	            if (m_DestCellularNo[0] == '+')
		            m_DestCellularNo = m_DestCellularNo.Mid(1);

	            // 在号码前加"86"
	            if (m_smsc.Left(2) != "86")  
		            m_smsc = "86" + m_smsc;
	            if (m_DestCellularNo.Left(2) != "86")  
		            m_DestCellularNo = "86" + m_DestCellularNo;

	            // 填充短消息结构
	            strcpy(SmParam.SCA, m_smsc);
	            strcpy(SmParam.TPA, m_DestCellularNo);
	            strcpy(SmParam.TP_UD, m_SendItems);
	            SmParam.TP_PID = 0;
				if (m_nCodeScheming == 0)
			        SmParam.TP_DCS = GSM_7BIT;
		        else if (m_nCodeScheming == 1)
			        SmParam.TP_DCS = GSM_UCS2;
				else
					SmParam.TP_DCS = GSM_8BIT;
				
	            nPduLength = gsmEncodePdu(&SmParam, pdu);	// 根据PDU参数,编码PDU串
	            pdu[nPduLength] = 0;
	            strcat(pdu, "\x01a");		// 以Ctrl-Z结束

	            gsmString2Bytes(pdu, &nSmscLength, 2);	// 取PDU串中的SMSC信息长度
	            nSmscLength++;		// 加上长度字节本身

	            // 命令中的长度,不包括SMSC信息长度,以数据字节计
	            sprintf(cmd, "AT+CMGS=%d\r", nPduLength / 2 - nSmscLength);	// 生成命令
                m_hComm->Send(cmd, strlen(cmd));

                Sleep(100);

				m_hComm->Send(pdu, strlen(pdu));
			}
		}
		else
			AfxMessageBox("请输入待发送数据。");
	}
}

void CSerialPortDlg::OnbtnStartComm() 
{
	m_btnStartComm.EnableWindow(FALSE);
	m_btnStopComm.EnableWindow(TRUE);

	BYTE byStopBit = 0;
	BYTE byParity  = 0;
	
	if ( !m_StopBit.Compare("1") )
		byStopBit = 0;
	else if ( !m_StopBit.Compare("1.5") )
		byStopBit = 1;
	else if ( !m_StopBit.Compare("2") )
		byStopBit = 2;

	if ( !m_Parity.Compare("None") )
		byParity = 0;
	else if ( !m_Parity.Compare("Odd") )
		byParity = 1;
	else if ( !m_Parity.Compare("Even") )
		byParity = 2;

	if (m_hComm != NULL)
		delete m_hComm;

	if (hCommEventArrive != INVALID_HANDLE)
	{
		CloseHandle(hCommEventArrive);
		hCommEventArrive = INVALID_HANDLE;
	}
	hCommEventArrive = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (hCommEventArrive == INVALID_HANDLE)
	{
		CloseHandle( hCommEventArrive );
        hCommEventArrive = INVALID_HANDLE;
		AfxMessageBox("hCommEventArrive created fail.");
		return;
	}

	m_hComm = new CRCCComm();
	RECT rect;
	rect.left=rect.top=0;
	rect.bottom=rect.right=20;
	if ( !m_hComm->Create(NULL,"COMM",WS_CHILD,rect,this,3000) )
	{
		delete m_hComm;
		m_hComm = NULL;

		AfxMessageBox("comm create failed.");
	}
    if ( !m_hComm->StartComm(m_Port.GetBuffer(0), m_BaudRate, m_ByteSize, byParity, byStopBit) )
	{
		int LastError = m_hComm->GetLastError();
		CString str;
		str.Format("error no: %d", LastError);
	
		delete m_hComm;
		m_hComm = NULL;

		AfxMessageBox(str);
	}
}

void CSerialPortDlg::OnbtnStopComm() 
{
	m_btnStartComm.EnableWindow(TRUE);
	m_btnStopComm.EnableWindow(FALSE);
	if (m_hComm != NULL)
	{
		m_hComm->StopComm();

		delete m_hComm;
		m_hComm = NULL;
	}

	if (hCommEventArrive != INVALID_HANDLE)
	{
		CloseHandle(hCommEventArrive);
		hCommEventArrive = INVALID_HANDLE;
	}
}

void CSerialPortDlg::OnbtnListen() 
{
	char strInstr[50];

	if ( UpdateData() )
	{
		if (m_SendItems.GetLength()>0)
		{
			if (m_hComm != NULL)
			{	
			    sprintf(strInstr, "%s\r", m_SendItems);
                m_hComm->Send(strInstr, strlen(strInstr));
			}
			
		}
		else
			AfxMessageBox("请输入待发送instruction。");
	}

}

void CSerialPortDlg::OnbtnGsmInit() 
{
	char strInstr[50];
	
	// TODO: Add your control notification handler code here
	if (m_hComm != NULL)
	{	
		//发送AT命令.
	    sprintf(strInstr, "%s\r", "AT"); 
        m_hComm->Send(strInstr, strlen(strInstr));
		Sleep(100);

		//发送ATE0
	    sprintf(strInstr, "%s\r", "ATE0"); 
        m_hComm->Send(strInstr, strlen(strInstr));
		Sleep(100);

		//发送AT+CMGF=0
	    sprintf(strInstr, "%s\r", "AT+CMGF=0"); 
        m_hComm->Send(strInstr, strlen(strInstr));
		Sleep(100);
	}
}

void CSerialPortDlg::OnbtnCMGL() 
{
	char strCMGL[50];

	if ( UpdateData() )
	{
		if (m_smsno.GetLength() > 0)
		{
			if (m_hComm != NULL)
			{	
			    sprintf(strCMGL, "AT+CMGL=%s\r", m_smsno);
                m_hComm->Send(strCMGL, strlen(strCMGL));
				Sleep(100); 
			}
		}
		else
			AfxMessageBox("请输入list no。");
	}
}

void CSerialPortDlg::OnbtnCMGR() 
{
	char strCMGR[50];

	if ( UpdateData() )
	{
		if (m_smsno.GetLength() > 0)
		{
			if (m_hComm != NULL)
			{	
			    sprintf(strCMGR, "AT+CMGR=%s\r", m_smsno);
                m_hComm->Send(strCMGR, strlen(strCMGR));
			}
		}
		else
			AfxMessageBox("请输入短信息号。");
	}

/*
	char* ptr;			// 内部用的数据指针
    SM_PARAM SmParam;

    char DbgMsg[200];

    char * a = "0891683108801705F0040D91683156887116F60000705080310320230AB2190A2C08B7C96A00";

	ptr = a;

	memset(&SmParam, 0, sizeof(SM_PARAM));

	gsmDecodePdu(ptr, &SmParam);	// PDU串解码

	sprintf(DbgMsg, "index=%d,SCA=%s,TPA=%s,SCTS=%s,TP_UD=%s", 
		 SmParam.index, SmParam.SCA, SmParam.TPA, SmParam.TP_SCTS, SmParam.TP_UD);
	DisplayMessage(DbgMsg);
*/
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -