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

📄 phonedailing.cs

📁 程序中利用了一个API来拨打电话
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using OpenNETCF.Tapi;

namespace PhoneTest
{
    public struct GeneralInfo
    {
        public string Manufacturer;
        public string Model;
        public string Revision;
        public string SerialNumber;
        public string SubscriberNumber;
    }

    /// <summary>
    /// Tapi控制类
    /// </summary>
    public class ControlTapi
    {

        [DllImport("cellcore.dll")]
        private static extern int lineGetGeneralInfo(IntPtr hLigne, byte[] lpLineGeneralInfo);

        /// <summary>
        /// 调用cellcore.dll获取sim卡的综合信息
        /// </summary>
        /// <param name="l"></param>
        /// <returns></returns>
        private GeneralInfo GetGeneralInfo(Line l)
        {
            GeneralInfo lgi = new GeneralInfo();
            byte[] buffer = new byte[512];
            BitConverter.GetBytes(512).CopyTo(buffer, 0);

            if (lineGetGeneralInfo(l.hLine, buffer) != 0)
            {
                throw new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error(), "TAPI Error: " + System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString("X"));
            }

            int subscsize = BitConverter.ToInt32(buffer, 44);
            int subscoffset = BitConverter.ToInt32(buffer, 48);
            lgi.SubscriberNumber = System.Text.Encoding.Unicode.GetString(buffer, subscoffset, subscsize).ToString();
            lgi.SubscriberNumber = lgi.SubscriberNumber.Replace("\0", "");
            return lgi;

        }



        /// <summary>
        /// 获取sim卡的IMSI
        /// </summary>
        /// <returns></returns>
        public static string GetIMSINumber()
        {
            string result = "";
            try
            {
                Tapi t = new Tapi();
                t.Initialize();
                Line l = t.CreateLine(0, LINEMEDIAMODE.INTERACTIVEVOICE, OpenNETCF.Tapi.LINECALLPRIVILEGE.MONITOR);
                ControlTapi ctapi = new ControlTapi();
                GeneralInfo gi = ctapi.GetGeneralInfo(l);

                result = gi.SubscriberNumber;
                l.Dispose();
                t.Shutdown();

            }
            catch// (Exception ex)
            {
                result = "";
            }

            return result;

        }

        /// <summary>
        /// 获取IMEI的号码
        /// </summary>
        /// <returns></returns>
        public static string GetIMEINumber()
        {
            string result = "";
            try
            {
                Tapi t = new Tapi();
                t.Initialize();
                Line l = t.CreateLine(0, LINEMEDIAMODE.INTERACTIVEVOICE, OpenNETCF.Tapi.LINECALLPRIVILEGE.MONITOR);
                ControlTapi ctapi = new ControlTapi();
                GeneralInfo gi = ctapi.GetGeneralInfo(l);
                result = gi.SerialNumber;
                l.Dispose();
                t.Shutdown();

            }
            catch// (Exception ex)
            {
                result = "";
            }

            return result;
        }

    }
    class PhoneDailing
    {
        
        //        简介
        //本文旨在通过另外一个示例,说明在用 C# 和 VB.NET 编写的托管代码中调用本机 Microsoft? Win32? API 是大有裨益的。下面,我们看看 Pocket PC Phone Edition 支持的通用电话 API。

        //使用 C# 创建电话呼叫
        //本文下面所引用的所有代码都可以从此处下载(英文)。创建呼叫是一个基本操作;我们传递 PhoneMakeCall (Win32 API),它是一个字符串,指示目标地址以及是否需要在呼叫前确认等操作。我们需要进行多项声明。

        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;
        }

        //cbSize 表明 PhoneMakeCallInfo 结构的大小。dwFlags 是一个选项位,用于指定呼叫前是否提示用户。pszDestAddress 是一个指针,指向要拨打的电话号码。当前不支持 pszAppName。pszCalledParty 为可选项,表示被叫方的姓名,大小有限。当前不支持 pszComment。现在,我们激活 PInvoke 并调用 DLLImport,以便访问 API 函数 PhoneMakeCall。

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

        //为了方便起见,我们包含了一个辅助函数,以便省略拨号前确认 Boolean。

        /// <summary>
        /// 拨打指定的电话号码。
        /// </summary>
        /// <param name="PhoneNumber">要拨打的电话号码。</param>
        public static void MakeCall(string PhoneNumber)
        {
            MakeCall(PhoneNumber, false);
        }
        //下面介绍一下 MakeCall 的功能。简而言之,我们将 PhoneNumber 参数(作为字符串传递)分割成一个字符数组。

        private static void MakeCall(string PhoneNumber, bool PromptBeforeCall)
        {
            PhoneNumber += '\0';
            char[] cPhoneNumber = PhoneNumber.ToCharArray();
            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;
            }
            IntPtr iPhoneNumber = Marshal.AllocHGlobal(cPhoneNumber.Length);
            Marshal.Copy(cPhoneNumber, 0, iPhoneNumber, cPhoneNumber.Length);
            info.pszDestAddress = iPhoneNumber;

            PhoneMakeCall(ref info);

            //   res = PhoneMakeCall(info)
        }

        //指向字符数组在内存中的内存地址,并为此变量加上 fixed 关键字,表示不希望内存回收器移动固定括号内的内容。


    //     HRIL g_hRil = NULL;
    //HRESULT hr = RIL_Initialize(1, RILResultProc, RILNotifyProc, RIL_NCLASS_ALL, NULL, &g_hRil);
    //RILCALLFORWARDINGSETTINGS Settings = {...}{0};
    //memset(&Settings,0,sizeof(RILCALLFORWARDINGSETTINGS));
    //Settings.cbSize = sizeof(RILCALLFORWARDINGSETTINGS);
    //Settings.dwParams  = RIL_PARAM_CFS_STATUS|RIL_PARAM_CFS_INFOCLASSES|RIL_PARAM_CFS_ADDRESS;//|RIL_PARAM_CFS_DELAYTIME;
    //Settings.dwStatus = RIL_CALLSTAT_ACTIVE;
    //Settings.dwInfoClasses = RIL_INFOCLASS_VOICE;

    //Settings.raAddress.cbSize = sizeof(RILADDRESS);
    //Settings.raAddress.dwParams = RIL_PARAM_A_ALL;
    //Settings.raAddress.dwType = RIL_ADDRTYPE_UNKNOWN;
    //Settings.raAddress.dwNumPlan = RIL_NUMPLAN_TELEPHONE; 

    //memcpy(Settings.raAddress.wszAddress,L"01068731199",256);

    //hr = RIL_RemoveCallForwarding(g_hRil,RIL_FWDREASON_ALLFORWARDING,RIL_INFOCLASS_VOICE);
    //if(hr <= 0)
    //{...}{
    //    SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
    //    MessageBox(_T("设置失败"),_T("错误"),MB_OK);
    //}
    //hr = RIL_AddCallForwarding(g_hRil,RIL_FWDREASON_MOBILEBUSY,&Settings);
    //if(hr <= 0)
    //{...}{
    //    SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
    //    MessageBox(_T("设置失败"),_T("错误"),MB_OK);
    //}
    //empty_hr = hr;



        //创建一个新的 PhoneMakeCallInfo 结构实例,指示是否希望在拨号之前进行确认以及是否将电话号码插入 pszDestAddress 字段。最后,我们将该结构实例作为引用传入 PhoneMakeCall。此函数使用 unsafe 关键字进行了修饰,因为它使用指针和直接内存访问。

        //使用 VB.NET 创建电话呼叫
        //用 VB.NET 编写的 MakeCall 代码与使用 C# 编写的代码相似(详细代码如上文所示),几乎不需要太大的改动。我们使用 IntPtr 变量保存多数函数的值。两者的不同之处在于,在 MakeCall 的前向声明中,我们指定 PhoneMakeCallInfo 结构实例将作为引用传递。

        //    <System.Runtime.InteropServices.DllImport("phone.dll")> _
        //    Private Shared Function PhoneMakeCall(ByRef ppmci As 
        //      PhoneMakeCallInfo) As IntPtr
        //    End Function

        //我们基本上按照前面的方法处理 PhoneMakeCallInfo 结构。将 PhoneNumber 字符串分割为一个字符数组,然后将 iPhoneNumber 用作内存调整指针写入内存。

        //PhoneNumber.Insert(PhoneNumber.Length, " ")
        //Dim cPhoneNumber() As Char = PhoneNumber.ToCharArray()
        //Dim pAddr() As Char = cPhoneNumber

        //Dim info As PhoneMakeCallInfo = New PhoneMakeCallInfo
        //info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info)
        //Dim iPhoneNumber As IntPtr = Marshal.AllocHLocal(cPhoneNumber.Length)
        //        System.Runtime.InteropServices.Marshal.Copy(cPhoneNumber, 0, 
        //          iPhoneNumber, cPhoneNumber.Length)
        //info.pszDestAddress = iPhoneNumber

        //将 pszDestAddress 成员指向此内存空间并设置拨号前确认选项后,将此结构实例传入 PhoneMakeCall。

        //If PromptBeforeCall Then
        //   info.dwFlags = PMCF_PROMPTBEFORECALLING
        //Else
        //   info.dwFlags = PMCF_DEFAULT
        //End If
        //   res = PhoneMakeCall(info)

        //使用 C# 访问 SIM 信息
        //虽然称不上是对 Pocket PC Phone Edition 平台上的可用 SIM 访问函数的详细介绍,但我们将通过介绍如何检索 SIM 所有者的主要电话号码和服务提供程序的名称,进一步说明 P/Invoke 的用途。我们首先定义一个结构,用以存放 ping SIM 卡时获得的值,如下所示。

        [StructLayout(LayoutKind.Sequential)]
        private struct SimRecord
        {
            public IntPtr cbSize;
            public IntPtr dwParams;
            public IntPtr dwRecordType;
            public IntPtr dwItemCount;
            public IntPtr dwSize;
        }

        //因为在本机代码和托管代码之间只能自动封送顺序布局结构,所以我们用顺序布局标记修饰我们的结构。cbSize 是所传递结构的大小。dwParams 是参数值,这里我们并不用担心。dwRecordType 表示记录的格式。选项包括:

        //值 说明 
        //SIM_RECORDTYPE_UNKNOWN 未知的文件类型。 
        //SIM_RECORDTYPE_TRANSPARENT 单个变长记录。 

⌨️ 快捷键说明

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