[智能设备]SmartPhone开发常用类(一) 手机短信发送

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace SmartPhone
{
 /// <summary>
 /// SMS helper class.
 /// </summary>
 public class SMS
 {
  public SMS()
  {
  }
  private const string SMS_MSGTYPE_TEXT = "Microsoft Text SMS Protocol";//消息协议模式
  
  private const int SMS_MAX_ADDRESS_LENGTH = 256;  // Max length of address
  //短消息模式
  private const int SMS_MODE_RECEIVE = 1;       //以接收模式打开
  private const int SMS_MODE_SEND = 2;          // 以发送模式打开
  private const int SMSAT_INTERNATIONAL = 1;    // 国际格式
  private const int PS_MESSAGE_OPTION_NONE = 0; // 没有消息选项
   //提供商指定消息类型
  private const int PS_MESSAGE_CLASS0 = 0;      //立即显示但不存储
  private const int PS_MESSAGE_CLASS1 = 1;      //存储,并在存储后发送一个确认回服务中心
  private const int PS_MESSAGE_CLASS2 = 2;      //在向服务中心发送确认之前,先把消息转移到SIM卡上的短信区域,如果不能存储但还有空间时发送一个未指明的协议错误到服务中心
  private const int PS_MESSAGE_CLASS3 = 3;      //消息到达并可以存储时发送一个确认回服务中心

  private const int PSRO_NONE = 0;              // 没有替换项

  //短信发送选项
  private const int SMS_OPTION_DELIVERY_NONE = 0; // 没有发送选项
  private const int SMS_OPTION_DELIVERY_NO_RETRY=1; //如果设置了该选项,则不再尝试重发,否则会按预定的时间表重发
  //短信编码格式
  private enum SMS_DATA_ENCODING
  {
   SMSDE_OPTIMAL=0, //最佳模式
   SMSDE_GSM,       //使用默认的GSM 7位编码
   SMSDE_UCS2,      //使用Unicode UCS2编码
  }
  [DllImport("sms.dll")]
  private static extern int SmsOpen(
   string ptsMessageProtocol,
   int dwMessageModes,
   ref IntPtr psmshHandle,
   int phMessageAvailableEvent);


  /// <summary>
  ///
  /// </summary>
  /// <param name="短信句柄"></param>
  /// <param name="短消息服务中心地址,推荐为NULL"></param>
  /// <param name="短消息目的地址"></param>
  /// <param name="短信的有效期,可以为NULL"></param>
  /// <param name="短信的数据部分,可以为NULL"></param>
  /// <param name="短信的数据部分大小,可以为0"></param>
  /// <param name="短信提供者指定数据"></param>
  /// <param name="短信提供者指定数据大小"></param>
  /// <param name="短信编码格式"></param>
  /// <param name="短信发送选项"></param>
  /// <param name="短信标识,如果不为空,则为短信发送成功后返回的ID,可以用于SmsGetMessageStatus"></param>
  /// <returns></returns>
  [DllImport("sms.dll")]
  private static extern int SmsSendMessage(
   IntPtr smshHandle,
   int psmsaSMSCAddress,
            IntPtr psmsaDestinationAddress,
   int pstValidityPeriod,
   IntPtr pbData,
            int dwDataSize,
   IntPtr pbProviderSpecificData,
   int dwProviderSpecificDataSize,
   SMS_DATA_ENCODING smsdeDataEncoding,
   int dwOptions,
   int psmsmidMessageID);

  [DllImport("sms.dll")]
  private static extern int SmsClose(IntPtr smshHandle);

  [DllImport("coredll.dll")]
  private static extern IntPtr LocalAlloc(uint uFlags, uint uBytes);

  [DllImport("coredll.dll")]
  internal static extern IntPtr LocalFree(IntPtr hMem);

  private static IntPtr AllocHGlobal(IntPtr cb)
  {
   IntPtr hmem;

   hmem = LocalAlloc(0x40, (uint) cb);
   return hmem;
  }

  private static void FreeHGlobal(IntPtr hglobal)
  {
   LocalFree(hglobal);
  }

  public static int SendSMS(string Number, string Message)
  {
   int returnValue = 0;
   IntPtr smsHandle = IntPtr.Zero;
   try
   {
    if(Number.Substring(0,3)!="+86") //国内手机必须在手机号码前加上+86
     Number ="+86"+Number;
    // Set address structure
    byte[] smsatAddressType = BitConverter.GetBytes(SMSAT_INTERNATIONAL);
    byte[] ptsAddress = Encoding.Unicode.GetBytes(Number);
    byte[] smsAddressTag = new byte[smsatAddressType.Length + ptsAddress.Length];
    Array.Copy(smsatAddressType, 0, smsAddressTag, 0, smsatAddressType.Length);
    Array.Copy(ptsAddress, 0, smsAddressTag, smsatAddressType.Length, ptsAddress.Length);
    IntPtr smsAddress = AllocHGlobal((IntPtr)smsAddressTag.Length);
    Marshal.Copy(smsAddressTag, 0, smsAddress, smsAddressTag.Length);

    // Set provider data structure
    byte[] dwMessageOptions = BitConverter.GetBytes(PS_MESSAGE_OPTION_NONE);
    byte[] psMessageClass = BitConverter.GetBytes(PS_MESSAGE_CLASS1);
    byte[] psReplaceOption = BitConverter.GetBytes(PSRO_NONE);
    byte[] smsProviderDataTag = new byte[dwMessageOptions.Length +
     psMessageClass.Length + psReplaceOption.Length];
    Array.Copy(dwMessageOptions, 0, smsProviderDataTag, 0, dwMessageOptions.Length);
    Array.Copy(psMessageClass, 0, smsProviderDataTag, dwMessageOptions.Length,
     psMessageClass.Length);
    Array.Copy(psReplaceOption, 0, smsProviderDataTag, dwMessageOptions.Length +
     psMessageClass.Length, psReplaceOption.Length);
    IntPtr smsProviderData = AllocHGlobal((IntPtr) smsProviderDataTag.Length);
    Marshal.Copy(smsProviderDataTag, 0, smsProviderData, smsProviderDataTag.Length);

    // Set message
    byte[] smsMessageTag = Encoding.Unicode.GetBytes(Message);
    IntPtr smsMessage = AllocHGlobal((IntPtr)smsMessageTag.Length);
    Marshal.Copy(smsMessageTag, 0, smsMessage, smsMessageTag.Length);

    // Get handle
    if (0 != SmsOpen(SMS_MSGTYPE_TEXT, SMS_MODE_SEND, ref smsHandle, 0))
     returnValue = -1; // Could not open

    // Send message
    if (0 != SmsSendMessage(smsHandle, 0, smsAddress, 0,
     smsMessage, smsMessageTag.Length,
     smsProviderData, smsProviderDataTag.Length,
     SMS_DATA_ENCODING.SMSDE_OPTIMAL, SMS_OPTION_DELIVERY_NONE, 0))
     returnValue = -2;

    FreeHGlobal(smsMessage);
    FreeHGlobal(smsProviderData);
    FreeHGlobal(smsAddress);
   }
   finally
   {
    // Release handle
    if (smsHandle != IntPtr.Zero)
    {
     if (0 != SmsClose(smsHandle))
      returnValue = -3; // Could not close
    }
   }

   return returnValue;
  }
 }
}

除了使用自定义类外,还可以使用OpenNetCF这个工具包 可以到这里下载 http://www.opennetcf.org ,目前版本1.4
安装后,引用OpenNETCF.Phone
然后代码如下:
....
using OpenNETCF.Phone;
using OpenNETCF.Phone.Sms;

private void menuItem2_Click(object sender, System.EventArgs e)
  {
   if((textBox1.Text.Trim().Length>0) &&(textBox1.Text.Trim().Length>0))
   {
    Sms mySMS=new Sms(SmsMode.Send);
    SmsAddress myAddr=new SmsAddress();
    myAddr.Address="+86"+textBox1.Text;
    myAddr.Type=AddressType.International;
    int smsHandle=mySMS.SendMessage(myAddr,textBox2.Text);
   }
  }
要特别注意的是,当你的系统中有Framework 1.1以及FrameWork 2.0时,加载dll会有问题,解决方法如下

将/Program Files/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE/中的OpenNETCF.Phone.dll拷贝到项目目录中,并在项目中包含此dll文件即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值