Инициирование телефонного звонка

Всё о КПК (PPC)

Модератор: чипега

Аватара пользователя
Blaze
Информатик-аналитик
Информатик-аналитик
Сообщения: 8933
Зарегистрирован: 24.05.2007 17:23
Модель телефона: POCO X3 Pro 6/128
Прошивка: crDroid v7.7
Sat-ресивер: Tiviar Mini HD
Откуда: Данков
Контактная информация:

Инициирование телефонного звонка

Непрочитанное сообщение#1 » Blaze » 26.06.2009 17:18

Не самый сложный пример на C# совершения важного телефонного звонка

Инициирование телефонного звонка.

Для устройств с Windows Mobile 5.0 и выше самый простой способ осуществить телефонный звонок это воспользоваться классом Microsoft.WindowsMobile.Telephony.Phone из сборки microsoft.windowsmobile.telephony.dll. Использование этого класса просто до непреличия. У класса Phone есть перегруженный метод Talk:

public void Talk(string number);
и
public void Talk(string number, bool showPrompt);

Параметр number принимает номер по которому необходимо осуществить звонок, а showPrompt позволяет вывести пользователю окно с подтверждением телефонного звонка. По умолчанию первый метод не выводит этого подтверждения.

Рассмотрим более сложную ситуацию. Что если у нас используется устройство Windows Mobile 2003 SE, скажем. Вы ведь не можете гарантировать, что ваши пользователи обладают только новейшими устройствами? В свете этого соображения, наличие класс Phone в WM 5.0 несколько меркнет. По крайней мере до той поры пока большиство устройств WM 2003 не окажется на помойке. Бережливые западные корпорации вряд ли планируют сделать это в ближайшее время. Дешевле (для наших западных партнеров это самое важное!), быстрее и проще воспользоваться приведенным ниже классом, чем менять сотни и тысячи девайсов:

Код: Выделить всё

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

namespace Vestace.WindowsMobile.Telephony
{
 public class Phone
 {
  private static long PMCF_DEFAULT = 0x00000001;
  private static long PMCF_PROMPTBEFORECALLING = 0x00000002;

  private const long LMEM_FIXED = 0;
  private const long LMEM_MOVEABLE = 2;
  private const long LMEM_ZEROINIT = 0x40;
  private const long LPTR = LMEM_FIXED | LMEM_ZEROINIT;

  private struct PhoneMakeCallInfo
  {
   public IntPtr cbSize;
   public IntPtr dwFlags;
   public IntPtr pszDestAddress;
   public IntPtr pszAppName;
   public IntPtr pszCalledParty;
   public IntPtr pszComment;
  }

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

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

  [DllImport("phone.dll")]
  private static extern IntPtr PhoneMakeCall(ref PhoneMakeCallInfo ppmci);

  private static IntPtr AllocHLocal(int uBytes)
  {
   IntPtr result = LocalAlloc((int)LPTR, uBytes);
   if(result == IntPtr.Zero)
   {
    throw new Win32Exception(Marshal.GetLastWin32Error());
   }
   return result;
  }

  private static void FreeHLocal(IntPtr hLocal)
  {
   if(hLocal != IntPtr.Zero)
   {
    if(LocalFree(hLocal) != IntPtr.Zero)
    {
     throw new Win32Exception(Marshal.GetLastWin32Error());
    }
    hLocal = IntPtr.Zero;
   }
  }

  private static void MakeCall(ref PhoneMakeCallInfo ppmci)
  {
   if(PhoneMakeCall(ref ppmci) != IntPtr.Zero)
   {
    throw new Win32Exception(Marshal.GetLastWin32Error());
   }
  }

  /// <summary>
  /// Dials the specified phone number.
  /// </summary>
  /// <param name="PhoneNumber">Phone number </param>
  /// <param name="PromptBeforeCall">sets whether Prompts the user before the call is placed</param>
  /// <exception cref="System.MissingMethodException">MissingMethodException</exception>
  /// <exception cref="System.ComponentModel.Win32Exception">Win32Exception</exception>
  public static void Talk(string PhoneNumber, bool PromptBeforeCall)
  {
   IntPtr iPhoneNumber = IntPtr.Zero;
   try
   {
    PhoneNumber += '\0';
    char[] cPhoneNumber = PhoneNumber.ToCharArray();
    PhoneMakeCallInfo info = new PhoneMakeCallInfo();
    info.cbSize = (IntPtr)Marshal.SizeOf(info);
    iPhoneNumber = AllocHLocal(cPhoneNumber.Length * Marshal.SizeOf(cPhoneNumber[0]));
    Marshal.Copy(cPhoneNumber, 0, iPhoneNumber, cPhoneNumber.Length);
    info.pszDestAddress = iPhoneNumber;

    if (PromptBeforeCall)
    {
     info.dwFlags = (IntPtr)PMCF_PROMPTBEFORECALLING;
    }
    else
    {
     info.dwFlags = (IntPtr)PMCF_DEFAULT;
    }
    MakeCall(ref info);
   }
   finally
   {
    FreeHLocal(iPhoneNumber);
   }
  }

  public static string ProcessPhoneNumber(string phoneNumber)
  {
   if(phoneNumber == null || phoneNumber.Length == 0)
   {
    throw new AppException("Incorrect Phone number");
   }

   StringBuilder result = new StringBuilder();
   if(Char.IsDigit(phoneNumber[0]) || phoneNumber[0] == '+')
   {
    result.Append(phoneNumber[0]);
   }

   for(int i = 1; i < phoneNumber.Length; i++)
   {
    if(Char.IsDigit(phoneNumber[i]) || phoneNumber[i] == '.')
    {
     result.Append(phoneNumber[i]);
    }
   }

   if(result.Length == 0)
   {
    throw new AppException("Incorrect Phone number");
   }

   return result.ToString();
  }
 }

}
Для использования этого метода вам достаточно написать вызов вроде
Vestace.WindowsMobile.Telephony.Phone("+74959142222");
(Дорогие граждане-шпионы! Убедительно прошу вас позвонить по этому номеру. И сотрудники ФСБ высочайшего класса пояснят вам как вы заблуждаетесь.)
Другой полезный метод просто удаляет из телефонного номера всякий ненужный мусор. Чтобы, значит, девайсина не ругалась благим матом.

Александр Игнатьев,
_http://www.vestace.ru_

Ответить