📄 serialportdlg.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 + -