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

📄 sendmessagedlg.cpp

📁 短消息代码~! 短消息代码~! PC发送sms
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// sendmessageDlg.cpp : implementation file
//

#include "stdafx.h"
#include "sendmessage.h"
#include "sendmessageDlg.h"

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

SM_PARAM sm;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength);
int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength);
int gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength);
int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength);
int gsmString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength);
int gsmBytes2String(const unsigned char* pSrc, char* pDst, int nSrcLength);
int gsmInvertNumbers(const char* pSrc, char* pDst, int nSrcLength);
int gsmSerializeNumbers(const char* pSrc, char* pDst, int nSrcLength);
int gsmEncodePdu(const SM_PARAM* pSrc, char* pDst);
int gsmDecodePdu(const char* pSrc, SM_PARAM* pDst);
	
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()

/////////////////////////////////////////////////////////////////////////////
// CSendmessageDlg dialog

CSendmessageDlg::CSendmessageDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSendmessageDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSendmessageDlg)
	m_strPhone = _T("");
	m_strContent = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSendmessageDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSendmessageDlg)
	DDX_Text(pDX, IDC_EDIT_PHONE, m_strPhone);
	DDX_Text(pDX, IDC_EDIT_CONTENT, m_strContent);
	DDX_Control(pDX, IDC_MSCOMM1, m_Com);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSendmessageDlg, CDialog)
	//{{AFX_MSG_MAP(CSendmessageDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSendmessageDlg message handlers

BOOL CSendmessageDlg::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
	
	//初始化串口
	InitialComm();
	SetTimer(1,2000,NULL);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

BOOL CSendmessageDlg::InitialComm()
{
	m_Com.SetCommPort(1);
	int ret = m_Com.GetPortOpen();
	if (!ret) 
	{
		m_Com.SetSettings("9600,N,8,1");
		m_Com.SetPortOpen(true);
		m_Com.SetInBufferCount(0);
		ret = m_Com.GetInBufferCount();
		m_Com.SetRTSEnable(true);
	   // SetTimer(1,1000,NULL);//set sm timer for receiving sm
	}
	else
	{
		return FALSE;
	}

	CString at;
	at.Format("AT+CMGF=0\r");//pdu mode
	m_Com.SetOutput(COleVariant(at));
	Sleep(500);

	CString atcomand("AT+CLIP=1\r");//显示来电号码
	m_Com.SetOutput(COleVariant(atcomand)); 
	Sleep(500);

	at.Format("AT+SPEAKER=1\r");
	m_Com.SetOutput(COleVariant(at)); 

    
	Sleep(500);

	m_Com.SetInBufferCount(0);

	return TRUE;
}

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

void CSendmessageDlg::receiveMessage()
{
	VARIANT MyInBuffer = m_Com.GetInput();
				
	CString str(MyInBuffer.bstrVal);
	str.TrimLeft();
	if (str.IsEmpty())
	{
		return;
	}
    else
	{                
		int i =str.Find("RING");
		if (i == -1)
		{
		
			int k = str.ReverseFind(':');
			//if (k < 5)
					//	break;
			CString strCmd = str.Mid(k-5, 5) ;
			if (strCmd.CompareNoCase("+CMTI") == 0)	//"+CMTI: "SM", 6"	
			{
				k = str.ReverseFind(',');
				CString strNum = str.Mid(k + 1); // "6"
				int num = atoi(strNum); // 6
				CString at;  //at = "at+CMGR=10\0";
				at.Format("AT+CMGR = %d \r", num); //"AT+CMGR = 6"
				m_Com.SetOutput(COleVariant(at));         
				
				Sleep(500);
				
				MyInBuffer = m_Com.GetInput();
						
				CString strPacket(MyInBuffer.bstrVal);
				int pos = strPacket.Find("0891");
				strPacket = strPacket.Mid(pos);
						
				char* pstr = (LPSTR)(LPCSTR)strPacket;
				
				gsmDecodePdu(pstr, &sm);

				CString temp;
			
				for(int ii=0;ii<161;ii++)
				{
					temp+=sm.TP_UD[ii];
				}//注意先后顺序,因为中英文的编码方式不同,故而可能产生无法显示的现象
				m_strContent=m_strContent+temp;
				temp.Empty();
				for(int jj=0;jj<16;jj++)
				{
					temp+=sm.TPA[jj];					
				}//电话号码
				m_strPhone=temp;

				UpdateData(FALSE);
				
				MessageBox("收到信短信,请注意查看!");
//				UpdateData(TRUE);
				
		//		m_lstSMContent.SetItemText(iIndex, 0, sm.TPA);
		//		m_lstSMContent.SetItemText(iIndex, 1, sm.TP_SCTS);
		//		m_lstSMContent.SetItemText(iIndex, 2, sm.TP_UD);

			}
		}	
	}

}
// PDU解码,用于接收、阅读短消息
// pSrc: 源PDU串指针
// pDst: 目标PDU参数指针
// 返回: 用户信息串长度
int gsmDecodePdu(const char* pSrc, SM_PARAM* pDst)
{
    int nDstLength;          // 目标PDU串长度
    unsigned char tmp;       // 内部用的临时字节变量
    unsigned char buf[256];  // 内部用的缓冲区

    // SMSC地址信息段
    gsmString2Bytes(pSrc, &tmp, 2);    // 取长度
    tmp = (tmp - 1) * 2;    // SMSC号码串长度
    pSrc += 4;              // 指针后移
    gsmSerializeNumbers(pSrc, pDst->SCA, tmp);    // 转换SMSC号码到目标PDU串
    pSrc += tmp;        // 指针后移

    // TPDU段基本参数、回复地址等
    gsmString2Bytes(pSrc, &tmp, 2);    // 取基本参数
    pSrc += 2;        // 指针后移
    if(tmp & 0x04/*0x80*/)
    {
        // 包含回复地址,取回复地址信息
        gsmString2Bytes(pSrc, &tmp, 2);    // 取长度
        if(tmp & 1) tmp += 1;    // 调整奇偶性
        pSrc += 4;          // 指针后移
        gsmSerializeNumbers(pSrc, pDst->TPA, tmp);    // 取TP-RA号码
        pSrc += tmp;        // 指针后移
    }

    // TPDU段协议标识、编码方式、用户信息等
    gsmString2Bytes(pSrc, (unsigned char*)&pDst->TP_PID, 2);    // 取协议标识(TP-PID)
    pSrc += 2;        // 指针后移
    gsmString2Bytes(pSrc, (unsigned char*)&pDst->TP_DCS, 2);    // 取编码方式(TP-DCS)
    pSrc += 2;        // 指针后移
    gsmSerializeNumbers(pSrc, pDst->TP_SCTS, 14);        // 服务时间戳字符串(TP_SCTS)
    pSrc += 14;       // 指针后移
    gsmString2Bytes(pSrc, &tmp, 2);    // 用户信息长度(TP-UDL)
    pSrc += 2;        // 指针后移
    if(pDst->TP_DCS == GSM_7BIT)
    {
        // 7-bit解码
        nDstLength = gsmString2Bytes(pSrc, buf, tmp & 7 ? (int)tmp * 7 / 4 + 2 : (int)tmp * 7 / 4);  // 格式转换
        gsmDecode7bit(buf, pDst->TP_UD, nDstLength);    // 转换到TP-DU
        nDstLength = tmp;
    }
    else if(pDst->TP_DCS == GSM_UCS2)
    {
        // UCS2解码
        nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2);        // 格式转换
        nDstLength = gsmDecodeUcs2(buf, pDst->TP_UD, nDstLength);    // 转换到TP-DU
    }
    else
    {
        // 8-bit解码
       // nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2);        // 格式转换
       // nDstLength = gsmDecode8bit(buf, pDst->TP_UD, nDstLength);    // 转换到TP-DU
    }

    // 返回目标字符串长度
    return nDstLength;
}

int gsmString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
    for(int i=0; i<nSrcLength; i+=2)
    {
        // 输出高4位
        if(*pSrc>='0' && *pSrc<='9')
        {
            *pDst = (*pSrc - '0') << 4;
        }
        else
        {
            *pDst = (*pSrc - 'A' + 10) << 4;
        }
    
        pSrc++;
    
        // 输出低4位
        if(*pSrc>='0' && *pSrc<='9')
        {
            *pDst |= *pSrc - '0';
        }
        else
        {
            *pDst |= *pSrc - 'A' + 10;
        }
        pSrc++;
        pDst++;
    }
    
    // 返回目标数据长度
    return nSrcLength / 2;
}

    
// 字节数据转换为可打印字符串
// 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01" 
// pSrc: 源数据指针
// pDst: 目标字符串指针
// nSrcLength: 源数据长度
// 返回: 目标字符串长度
int gsmBytes2String(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
    const char tab[]="0123456789ABCDEF";    // 0x0-0xf的字符查找表
    
    for(int i=0; i<nSrcLength; i++)
    {
        // 输出低4位
        *pDst++ = tab[*pSrc >> 4];
    
        // 输出高4位
        *pDst++ = tab[*pSrc & 0x0f];
    
        pSrc++;
    }
    
    // 输出字符串加个结束符
    *pDst = '\0';
    
    // 返回目标字符串长度
    return nSrcLength * 2;
}

// 两两颠倒的字符串转换为正常顺序的字符串
// 如:"683158812764F8" --> "8613851872468"
// pSrc: 源字符串指针
// pDst: 目标字符串指针
// nSrcLength: 源字符串长度
// 返回: 目标字符串长度
int gsmSerializeNumbers(const char* pSrc, char* pDst, int nSrcLength)
{
    int nDstLength;   // 目标字符串长度
    char ch;          // 用于保存一个字符

    // 复制串长度
    nDstLength = nSrcLength;

    // 两两颠倒
    for(int i=0; i<nSrcLength;i+=2)
    {
        ch = *pSrc++;        // 保存先出现的字符
        *pDst++ = *pSrc++;   // 复制后出现的字符
        *pDst++ = ch;        // 复制先出现的字符
    }

    // 最后的字符是'F'吗?
    if(*(pDst-1) == 'F')
    {
        pDst--;
        nDstLength--;        // 目标字符串长度减1
    }

    // 输出字符串加个结束符
    *pDst = '\0';

    // 返回目标字符串长度
    return nDstLength;
}


// 7-bit编码
// pSrc: 源字符串指针
// pDst: 目标编码串指针
// nSrcLength: 源字符串长度
// 返回: 目标编码串长度
int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
    int nSrc;        // 源字符串的计数值
    int nDst;        // 目标编码串的计数值
    int nChar;       // 当前正在处理的组内字符字节的序号,范围是0-7
    unsigned char nLeft;    // 上一字节残余的数据
    
    // 计数值初始化
    nSrc = 0;
    nDst = 0;
    
    // 将源串每8个字节分为一组,压缩成7个字节
    // 循环该处理过程,直至源串被处理完
    // 如果分组不到8字节,也能正确处理
    while(nSrc<nSrcLength)
    {
        // 取源字符串的计数值的最低3位
        nChar = nSrc & 7;
    
        // 处理源串的每个字节
        if(nChar == 0)
        {
            // 组内第一个字节,只是保存起来,待处理下一个字节时使用
            nLeft = *pSrc;
        }
        else

⌨️ 快捷键说明

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