?? phonedailing.cs
字號:
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 + -