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

📄 testsms.c

📁 短信发送软件
💻 C
字号:
/*-------------------------------------------------------------
发送手机短信程序
江振健
http://www.my66.com
litth@yeah.net
---------------------------------------------------------------*/
#include <stdio.h>
#include <windows.h>
#include "testsmsres.h"

HWND hMain;
HINSTANCE hInst;

static BOOL CALLBACK DialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);

/*-------------------------------------------------------------
函数名 :ShowMsg
功能   :在状窗显示字符串
参数   :msg--内容
返回值 :void
---------------------------------------------------------------*/
void ShowMsg(char *msg)
{
	HWND hEdit=GetDlgItem(hMain,IDE_MSG);
	int len=GetWindowTextLength(hEdit);
    char *buf=malloc(len+strlen(msg)+100);
	if(buf)
	{
		GetWindowText(hEdit,buf,len+10);
		strcat(buf,msg);
		SetWindowText(hEdit,buf);
		SendMessage(hEdit,EM_LINESCROLL,0,
			SendMessage(hEdit,EM_GETLINECOUNT,0,0));
		free(buf);
	}
}

/*-------------------------------------------------------------
函数名 :PduCode
功能   :生成短信的PDU编码字符串.
参数   :cnt --短信服务中心号码,sdt--接收号码(对方手机号),msg--短信内容.
返回值 :经PDU编码的字符串指针,如有错,其内容为空.
---------------------------------------------------------------*/
char *PduCode(char *cnt,char *sdt,char *msg)
{
  static unsigned char pdu[1024]="",tmp1[1024],tmp2[20];
  int i,k,len_cnt=strlen(cnt),len_sdt=strlen(sdt),len_msg=strlen(msg);

  memset(pdu,0,sizeof(pdu));//把存放PDU编码的内存清零.
  if(len_cnt>18||len_sdt>18||len_msg>100)return pdu;//判断参数是否有效.
  strcpy(tmp1,cnt);//把服务中心号复制到tmp1
  if(len_cnt%2==1){strcat(tmp1,"F");len_cnt++;}//若服务中心号长度为奇数则追加"F".
  sprintf(pdu,"%02X",(len_cnt/2)+1);//服务中心号码长度.
  if(!strncmp(cnt,"00",2))//判断服务中心号类型.
    {
       strcat(pdu,"81");
    }
  else
    {//默认短信服务中心号前有"+",如+86130200500.
       strcat(pdu,"91");
    }
  for(k=strlen(pdu),i=0;i<len_cnt;i++,k++)
    {//每两个字节进行位置交换.
       pdu[k]=i%2==0?tmp1[i+1]:tmp1[i-1];
    }
  //处理接收方手机号码.
  sprintf(tmp2,"1100%02X81",len_sdt);
  strcat(pdu,tmp2);
  strcpy(tmp1,sdt);
  if(len_sdt%2==1)
   {//若接收方手机号长度为奇数则追加"F".
     strcat(tmp1,"F");
     len_sdt++;
   }
  for(i=0,k=strlen(pdu);i<len_sdt;i++,k++)
   {//每两个字节进行位置交换.
     pdu[k]=i%2==0?tmp1[i+1]:tmp1[i-1];
   }
  //处理被发送的短信的内容.
  k=2*MultiByteToWideChar(CP_ACP,//转换成UNICODE.
       MB_PRECOMPOSED,msg,len_msg,(unsigned short *)tmp1,sizeof(tmp1));
  sprintf(tmp2,"0008FF%02X",k);
  strcat(pdu,tmp2);
  for(i=0;i<k;i++)
    {//将短信内容每两个字节进行位置交换转成十六进制的字符串.
      sprintf(tmp2,"%02X",i%2==0?tmp1[i+1]:tmp1[i-1]);
      strcat(pdu,tmp2);
    }
   return pdu;
}

/*-------------------------------------------------------------
函数名 :ATCommand
功能   :发送AT命令到指定的串口
参数   :hComm--串口的句柄,cmd--AT命令
返回值 :发送AT命令后收到的字符指针
---------------------------------------------------------------*/
char *ATCommand(HANDLE hComm,char *cmd)
{
   DWORD readwrite=0;
   static char  buf[1024];

   ZeroMemory(buf,sizeof(buf));
   WriteFile(hComm,cmd,strlen(cmd),&readwrite,NULL);
   Sleep(1000);//等待调制解调器处理AT命令.
   ReadFile(hComm,buf,sizeof(buf)-1,&readwrite,NULL);
   ShowMsg(buf);
   return buf;
}

/*-------------------------------------------------------------
函数名 :sms
功能   :发送短信
参数   :com--串口号, sendto--接收方手机号, msg--短信内容
返回值 :0
---------------------------------------------------------------*/
int sms(int com,char *sendto,char *msg)
{
    char buf[1024],*p,*sms,*center=NULL;
    HANDLE hComm;
    DCB dcb;
    int len,len_center;
    COMMTIMEOUTS cto = { 20, 10, 10, 10, 10 };
    sprintf(buf,"COM%d",com);
    hComm=CreateFile(buf,
		GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);
    if(hComm==INVALID_HANDLE_VALUE)
       {
         ShowMsg("通信串口打开错误.\r\n");
         goto Quit;
       }
    GetCommState(hComm,&dcb);
    dcb.BaudRate = CBR_9600; // 设置波特率为9600.
    dcb.ByteSize = 8;        // 字节为 8位.
    dcb.Parity = NOPARITY;   // Parity 为 None.
    dcb.StopBits = ONESTOPBIT; // 1 个停止位.
    if (!SetCommState(hComm, &dcb)) {// 设置通信端口状态.
    ShowMsg("通信串口设置错误.");
	goto Quit;
    }
   SetCommTimeouts(hComm,&cto);//设置超时时间.
   if(!strstr(ATCommand(hComm,"AT\r"),"OK"))//判断手机是否支持AT命令.
       {  
          ShowMsg("通信串口未连接手机或手机不支持AT命令.\r\n");
		  goto Quit;
       }
   //取短信服务中心号码.
   for(p=ATCommand(hComm,"AT+CSCA?\r");*p!='\0';p++)
       {//从引号间找出服务中心号,如:+CSCA: "8613010200500",145.
          if(*p=='"' && center!=NULL)
             {
                *p='\0';break;
             }
          if(*p=='"' && center==NULL)
             {
                center=p+1;
             }
        }
   if(center==NULL)
     {
         ShowMsg("找不到服务中心号码.\r\n");
		 goto Quit;
      }    
    sms=PduCode(center,sendto,msg);//进行PDU编码.
    if((len=strlen(sms)/2)<=0)
	{
		ShowMsg("PDU编码失败.\r\n");
		goto Quit;
	}
    len_center=strlen(center);
    if(len_center%2==1)
       {
           len_center++;
       }
    len-=(len_center/2)+2;//计算短信内容长度.
    ATCommand(hComm,"AT+CMGF=0\r");//发送AT+CMGF=0<CR>.
    sprintf(buf,"AT+CMGS=%d\r",len);
    ATCommand(hComm,buf);//发送AT+CMGS=n<CR>.
    ATCommand(hComm,sms);//发送经PDU编码的字符串.
    ATCommand(hComm,"\32\r");//发送(CTRL+Z+<CR>)结束.
Quit:
	CloseHandle(hComm);//关闭句柄.
    return 0;
}

/*-------------------------------------------------------------
函数名 :InitializeIni
功能   :初始化变量
参数   :void
返回值 :void
---------------------------------------------------------------*/
void InitializeIni(void)
{
	char INIFile[600];
	char tmp[512];

	GetCurrentDirectory(600,INIFile);
	lstrcat(INIFile,"\\testsms.ini");

	GetPrivateProfileString("Opt","COM","1",tmp,512,INIFile);

	SetDlgItemText(hMain,IDE_COM,tmp);

	GetPrivateProfileString("Opt","TO","13026889xyz",tmp,512,INIFile);

	SetDlgItemText(hMain,IDE_SENDTO,tmp);

}
/*-------------------------------------------------------------
函数名 :SaveIni
功能   :保存Ini
参数   :void
返回值 :void
---------------------------------------------------------------*/
void SaveIni(void)
{
	char INIFile[600];
	char tmp[512];

	GetCurrentDirectory(600,INIFile);
	lstrcat(INIFile,"\\testsms.ini");


	GetDlgItemText(hMain,IDE_COM,tmp,512);

	WritePrivateProfileString("Opt","COM",tmp,INIFile);

	GetDlgItemText(hMain,IDE_SENDTO,tmp,512);

	WritePrivateProfileString("Opt","TO",tmp,INIFile);

}
/*-------------------------------------------------------------
函数名 :WinMain
功能   :主函数
参数   :
返回值 :
---------------------------------------------------------------*/
int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpCmdLine, int nCmdShow)
{
	hInst=hinst;
	return DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, (DLGPROC) DialogFunc);
}


/*-------------------------------------------------------------
函数名 :SendSMS
功能   :发送短信的线程
参数   :void
返回值 :void
---------------------------------------------------------------*/
void SendSMS(void)
{
	char com[20];
	char sendto[30];
	char msg[200];
	HWND hwnd;

	hwnd=hMain;
	EnableWindow(GetDlgItem(hwnd,IDOK),FALSE);
    EnableWindow(GetDlgItem(hwnd,IDE_SENDTO),FALSE);
	EnableWindow(GetDlgItem(hwnd,IDE_COM),FALSE);
	EnableWindow(GetDlgItem(hwnd,IDE_TEXT),FALSE);

	GetDlgItemText(hwnd,IDE_COM,com,2);
	GetDlgItemText(hwnd,IDE_SENDTO,sendto,30);
	GetDlgItemText(hwnd,IDE_TEXT,msg,54);
	SetDlgItemText(hwnd,IDE_MSG,"");
	if(strlen(msg)>0 && strlen(sendto)>0)
	{
        sms(atoi(com),sendto,msg);
	}
	else
	{
		ShowMsg("短信内容和和号码不能为空.\r\n");
	}
	EnableWindow(GetDlgItem(hwnd,IDOK),TRUE);
	EnableWindow(GetDlgItem(hwnd,IDE_SENDTO),TRUE);
	EnableWindow(GetDlgItem(hwnd,IDE_COM),TRUE);
	EnableWindow(GetDlgItem(hwnd,IDE_TEXT),TRUE);

}
/*-------------------------------------------------------------
函数名 :HandleCommand
功能   :处理WM_COMMAND消息
参数   :hwnd,wParam,lParam
返回值 :void
---------------------------------------------------------------*/
void HandleCommand(HWND hwnd,WPARAM wParam,LPARAM lParam)
{

	char msg[200];
	DWORD Id;
	switch (LOWORD(wParam)) {
			case IDOK:
                 CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE )SendSMS,NULL,0,&Id));
				return ;

			case IDE_TEXT:
				if(EN_CHANGE==HIWORD(wParam))
					{   int len =GetWindowTextLength((HWND)lParam);
				        if(len<100)
						{
						wsprintf(msg,"字节数:%d",len);
						SetDlgItemText(hwnd,IDC_STATUS,msg);
					    }
					    else
							{
								SetDlgItemText(hwnd,IDC_STATUS,"超过短信规定的字节数");
								MessageBeep(0);
							}
					}
				return ;
		}

}
/*-------------------------------------------------------------
函数名 :DialogFunc
功能   :处理Window消息
参数   :hwndDlg,msg,wParam,lParam
返回值 :TRUE or FALSE
---------------------------------------------------------------*/
static BOOL CALLBACK DialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_INITDIALOG:
	hMain=hwndDlg;
	InitializeIni();
	return TRUE;
	case WM_COMMAND:
		HandleCommand(hwndDlg,wParam,lParam);
		return 1;
	case WM_CLOSE:
		SaveIni();
		EndDialog(hwndDlg,0);
		return TRUE;

	}
	return FALSE;
}

⌨️ 快捷键说明

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