📄 phone.cs
字号:
using System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
namespace PInvokeLibrary
{
/// <summary>
/// Wraps the Pocket PC Phone API
/// </summary>
public class Phone
{
/// <summary>
/// Private constructor to prevent instantiation
/// </summary>
private Phone(){}
/// <summary>
/// This structure contains the information required to make a phone call.
/// typedef struct tagPHONEMAKECALLINFO
/// {
/// DWORD cbSize;
/// DWORD dwFlags;
/// PCWSTR pszDestAddress;
/// PCWSTR pszAppName;
/// PCWSTR pszCalledParty;
/// PCWSTR pszComment;
/// } PHONEMAKECALLINFO, * PHONEMAKECALLINFO;
/// </summary>
private class PHONEMAKECALLINFO : IDisposable
{
private const uint PMCF_DEFAULT = 0x00000001;
private const uint PMCF_PROMPTBEFORECALLING = 0x00000002;
uint cbSize = (uint)Marshal.SizeOf(typeof(PHONEMAKECALLINFO));
public uint dwFlags = PMCF_DEFAULT;
IntPtr pszDestAddress = IntPtr.Zero;
IntPtr pszAppName = IntPtr.Zero;
IntPtr pszCalledParty = IntPtr.Zero;
IntPtr pszComment = IntPtr.Zero;
/// <summary>
/// Create an instance.
/// </summary>
/// <param name="phoneNumber">Destination phone number</param>
public PHONEMAKECALLINFO(string phoneNumber)
{
this.pszDestAddress =
Utilities.StringToHLocalUni(phoneNumber);
}
/// <summary>
/// Create an instance.
/// </summary>
/// <param name="phoneNumber">Destination phone number</param>
/// <param name="calledParty">Desitnation party</param>
public PHONEMAKECALLINFO(string phoneNumber, string calledParty)
{
this.pszDestAddress =
Utilities.StringToHLocalUni(phoneNumber);
this.pszCalledParty =
Utilities.StringToHLocalUni(calledParty);
}
/// <summary>
/// Create an instance.
/// </summary>
/// <param name="phoneNumber">Destination phone number</param>
/// <param name="calledParty">Desitnation party</param>
/// <param name="prompt">Specifies if the user should be prompted
/// before making the actual call</param>
public PHONEMAKECALLINFO(string phoneNumber, string calledParty, bool prompt)
{
this.pszDestAddress = Utilities.StringToHLocalUni(phoneNumber);
this.pszCalledParty = Utilities.StringToHLocalUni(calledParty);
if (prompt)
this.dwFlags = PMCF_PROMPTBEFORECALLING;
}
/// <summary>
/// Clean up string allocations.
/// </summary>
public void Dispose()
{
if (pszDestAddress != IntPtr.Zero)
Memory.LocalFree(pszDestAddress);
if (pszCalledParty != IntPtr.Zero)
Memory.LocalFree(pszCalledParty);
}
}
/// <summary>
/// typedef struct
/// {
/// DWORD cbSize;
/// FILETIME ftStartTime;
/// FILETIME ftEndTime;
/// IOM iom;
/// BOOL fOutgoing:1;
/// BOOL fConnected:1;
/// BOOL fEnded:1;
/// BOOL fRoam:1;
/// CALLERIDTYPE cidt;
/// PTSTR pszNumber;
/// PTSTR pszName;
/// PTSTR pszNameType;
/// PTSTR pszNote;
/// } CALLLOGENTRY, *PCALLLOGENTRY;
/// </summary>
public class CALLLOGENTRY : IDisposable
{
public uint cbSize = (uint)Marshal.SizeOf(typeof(CALLLOGENTRY));
public long ftStartTime = 0;
public long ftEndTime = 0;
public IOM iom = 0;
public Flags flags = 0;
public CALLERIDTYPE cidt = 0;
public IntPtr pszNumber = IntPtr.Zero;
public IntPtr pszName = IntPtr.Zero;
public IntPtr pszNameType = IntPtr.Zero;
public IntPtr pszNote = IntPtr.Zero;
public enum CALLERIDTYPE
{
UNAVAILABLE,
BLOCKED,
AVAILABLE
}
public enum IOM
{
MISSED,
INCOMING,
OUTGOING
}
public enum Flags : byte
{
Outgoing = 0x1,
Connected = 0x2,
Ended = 0x4,
Roam = 0x8
}
public enum CallerIDType
{
Unavailable,
Blocked,
Available
}
public enum CallType
{
Missed,
Incoming,
Outgoing
}
// Accessors
public DateTime StartTime { get { return DateTime.FromFileTime(this.ftStartTime); } }
public DateTime EndTime { get { return DateTime.FromFileTime(this.ftEndTime); } }
public CallType CallTyp { get { return (CallType)this.iom; } }
public bool Outgoing { get { return (this.flags & Flags.Outgoing) != 0; } }
public bool Connected { get { return (this.flags & Flags.Connected) != 0; } }
public bool Ended { get { return (this.flags & Flags.Ended) != 0; } }
public bool Roam { get { return (this.flags & Flags.Roam) != 0; } }
public CallerIDType CallerIDTyp { get { return (CallerIDType)this.cidt; } }
public string Number { get { return Marshal.PtrToStringUni(this.pszNumber); } }
public string Name { get{ return Marshal.PtrToStringUni(this.pszName); } }
public string NameType { get { return Marshal.PtrToStringUni(this.pszNameType); } }
public string NoteFile { get { return Marshal.PtrToStringUni(this.pszNote); } }
/// <summary>
/// Clean up string allocations.
/// </summary>
public void Dispose()
{
if (pszNumber != IntPtr.Zero)
Memory.LocalFree(pszNumber);
if (pszName != IntPtr.Zero)
Memory.LocalFree(pszName);
if (pszNameType != IntPtr.Zero)
Memory.LocalFree(pszNameType);
if (pszNote != IntPtr.Zero)
Memory.LocalFree(pszNote);
}
}
/// <summary>
/// This method dials the specified phone number.
/// </summary>
/// <param name="phoneNumber">The phone number to be dialed.</param>
/// <param name="calledParty">The name of the party to be called.</param>
/// <param name="prompt">Prompt the user before the call is placed.</param>
/// <returns>True if the placing the call was successful.</returns>
public static bool MakeCall(string phoneNumber, string calledParty, bool prompt)
{
PHONEMAKECALLINFO phoneMakeCallInfo = null;
try
{
phoneMakeCallInfo = new PHONEMAKECALLINFO
(
phoneNumber,
calledParty,
prompt
);
return (0 == PhoneMakeCall(phoneMakeCallInfo));
}
finally
{
if (phoneMakeCallInfo != null)
phoneMakeCallInfo.Dispose();
}
}
/// <summary>
/// This method dials the specified phone number.
/// </summary>
/// <param name="phoneNumber">The phone number to be dialed.</param>
/// <param name="calledParty">The name of the party to be called.</param>
/// <returns>True if the placing the call was successful.</returns>
public static bool MakeCall(string phoneNumber, string calledParty)
{
return MakeCall(phoneNumber, calledParty, false);
}
/// <summary>
/// This method dials the specified phone number.
/// </summary>
/// <param name="phoneNumber">The phone number to be dialed.</param>
/// <returns>True if the placing the call was successful.</returns>
public static bool MakeCall(string phoneNumber)
{
return MakeCall(phoneNumber, "", false);
}
/// <summary>
/// Access the phones callog.
/// </summary>
/// <returns>Array of CALLOGENTRY</returns>
public static CALLLOGENTRY[] GetCallLog()
{
IntPtr h = IntPtr.Zero;
try
{
uint lastRecordIndex = 0;
uint position = 0;
CALLLOGENTRY[] entries = null;
PhoneOpenCallLog(out h);
if (h == IntPtr.Zero)
return null;
PhoneSeekCallLog(h, CALLLOGSEEK.END, 0, ref lastRecordIndex);
entries = new CALLLOGENTRY[lastRecordIndex+1];
for (uint i = 0; i <= lastRecordIndex; i++)
{
entries[i] = new CALLLOGENTRY();
PhoneSeekCallLog(h, CALLLOGSEEK.BEGINNING, i, ref position);
PhoneGetCallLogEntry(h, entries[i]);
}
return entries;
}
finally
{
if (h != IntPtr.Zero)
PhoneCloseCallLog(h);
}
}
/// <summary>
/// Make a phone call.
/// </summary>
/// <param name="ppmci">Filled in instance of PHONEMAKECALLINFO</param>
/// <returns>0 if successful</returns>
[DllImport("Phone.dll")]
private static extern int PhoneMakeCall(PHONEMAKECALLINFO ppmci);
/// <summary>
/// Open the phone calllog.
/// </summary>
/// <param name="ph">Handle to the log</param>
[DllImport("Phone.dll")]
private static extern void PhoneOpenCallLog(out IntPtr ph);
/// <summary>
/// Close the phone callog.
/// </summary>
/// <param name="h">Open handle to the log</param>
[DllImport("Phone.dll")]
private static extern void PhoneCloseCallLog(IntPtr h);
/// <summary>
/// Get the current calllog entry.
/// </summary>
/// <param name="h">Handle to an open log</param>
/// <param name="pentry">CALLLOGENTRY data</param>
[DllImport("Phone.dll")]
private static extern void PhoneGetCallLogEntry(IntPtr h, CALLLOGENTRY pentry);
/// <summary>
/// Seek start position used by PhoneSeekCallLog seek parameter.
/// </summary>
private enum CALLLOGSEEK
{
BEGINNING = 2,
END = 4
}
/// <summary>
/// Seek to a specific calllog entry.
/// </summary>
/// <param name="hdb">Handle to an open log</param>
/// <param name="seek">Seek starting position</param>
/// <param name="iRecord">Record index from seek start location</param>
/// <param name="piRecord">Index of the record sought</param>
[DllImport("Phone.dll")]
private static extern void PhoneSeekCallLog(IntPtr hdb, CALLLOGSEEK seek, uint iRecord, ref uint piRecord);
/// <summary>
/// Run a test of the Phone class.
/// </summary>
/// <param name="showLine">Delegate called to show debug information</param>
public static void TestProc(MainTest.DisplayLineDelegate showLine)
{
showLine("Reading calllog...");
CALLLOGENTRY[] ee = Phone.GetCallLog();
if (ee == null)
{
showLine("FAILURE: Reading calllog");
}
else
{
foreach( Phone.CALLLOGENTRY cle in ee )
{
showLine(cle.StartTime.ToString());
cle.Dispose();
}
}
showLine("Calling 555-5555");
if (!Phone.MakeCall("5555555"))
{
showLine("FAILURE: Making call");
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -