在ppc2003的开发过程中,对于电话的呼叫和短信收发需要通过。net的委托调用外部函数。
短信操作,需要委托调用sms.dll,电话呼出需要委托调用phone.dll的函数。
下面就是我的一个例子
using System;
using System.Text;
using System.Runtime.InteropServices;
#endregion
namespace Aibang.Util
{
/// <summary>
/// Phone 的摘要说明。
/// </summary>
///
public enum AddressType
{
/// <summary>Unknown phone number type.</summary>
Unknown,
/// <summary>International phone number.</summary>
International,
/// <summary>National phone number.</summary>
National,
/// <summary>Network-specific phone number.</summary>
NetworkSpecific,
/// <summary>Subscriber phone number.</summary>
Subscriber,
/// <summary>Alphanumeric phone number.</summary>
Alphanumeric,
/// <summary>Abbreviated phone number.</summary>
Abbreviated
}
/// <summary>
/// Information about the phone number.
/// </summary>
public struct PhoneAddress
{
/// <summary>The address type.</summary>
public AddressType AddressType;
/// <summary>The phone number in string format.</summary>
public String Address;
}
public class Phone
{
public Phone()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
private static long PMCF_DEFAULT = 0x00000001;
private static long PMCF_PROMPTBEFORECALLING = 0x00000002;
private struct PhoneMakeCallInfo
{
public IntPtr cbSize;
public IntPtr dwFlags;
public IntPtr pszDestAddress;
public IntPtr pszAppName;
public IntPtr pszCalledParty;
public IntPtr pszComment;
}
[DllImport("phone.dll")]
private static extern IntPtr PhoneMakeCall(ref PhoneMakeCallInfo ppmci);
/// <summary>
/// Dials the specified phone number.
/// </summary>
/// <param name="PhoneNumber">Phone number to dial.</param>
public static void MakeCall(string PhoneNumber)
{
MakeCall(PhoneNumber, false);
}
/// <summary>
/// Dials the specified phone number.
/// </summary>
/// <param name="PhoneNumber">Phone number to dial.</param>
/// <param name="PromptBeforeCall">Prompts the user before the call is placed.</param>
unsafe public static void MakeCall(string PhoneNumber, bool PromptBeforeCall)
{
IntPtr res;
PhoneNumber += '/0';
char[] cPhoneNumber = PhoneNumber.ToCharArray();
fixed (char* pAddr = cPhoneNumber)
{
PhoneMakeCallInfo info = new PhoneMakeCallInfo();
info.cbSize = (IntPtr)Marshal.SizeOf(info);
info.pszDestAddress = (IntPtr)pAddr;
if (PromptBeforeCall)
{
info.dwFlags = (IntPtr)PMCF_PROMPTBEFORECALLING;
}
else
{
info.dwFlags = (IntPtr)PMCF_DEFAULT;
}
res = PhoneMakeCall(ref info);
}
}
}
//
//短信类
//
public class 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;
}
}
}