How to use unmanaged code (native API code)?

  • Thread starter Thread starter Mpoy
  • Start date Start date
M

Mpoy

I need to use the Phone API of the compact framework. I have tried
using the Marshall class and tried to wrap it in C# code so I can use
it as a managed code but it doesn't work. I also don't have any idea on
how can I use the 'PhoneGetCallLogEntry' function. Can anyone help me
pls. This is my wrapped code:

(in reference to phone.h)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace ProjectObjects
{
public class W_Phone
{
public W_Phone()
{
}

private enum CALLERIDTYPE
{
CALLERIDTYPE_UNAVAILABLE,
CALLERIDTYPE_BLOCKED,
CALLERIDTYPE_AVAILABLE
}

private enum IOM
{
IOM_MISSED,
IOM_INCOMING,
IOM_OUTGOING
}

private enum CALLLOGSEEK
{
CALLLOGSEEK_BEGINNING = 2,
CALLLOGSEEK_END = 4
}

[StructLayout(LayoutKind.Sequential)]
private struct CALLLOGENTRY
{
public UInt32 cbSize; // sizeof CALLLOGENTRY
public DateTime ftStartTime;
public DateTime ftEndTime;
public IOM iom;
public bool fOutgoing; // direction of call.
(Missed calls are incoming.)
public bool fConnected1; // Did the call connect? (as
opposed to busy, no answer)
public bool fEnded; // Was the call ended? (as
opposed to dropped)
public bool fRoam; // Roaming (vs. local)
public CALLERIDTYPE cidt;
public string pszNumber;
public string pszName;
public string pszNameType; // "w" for work tel, "h" for
home tel, for example
public string pszNote; // filename of associated Notes
file
}

// Open the call log and set the seek pointer to the beginning.
[DllImport("Phone.dll")]
private static extern long PhoneOpenCallLog(out IntPtr ph);


// PhoneGetCallLogEntry returns one call log entry and advances
the seek
// pointer.
// pentry->cbSize must be set to "sizeof CALLLOGENTRY" before
this function is
// called.
// The entries are returned in order of start time, the most
recent call first.
// It is the responsibility of the caller to LocalFree any
strings
// which are returned.
// A return value of S_FALSE indicates there are no more
entries.
[DllImport("Phone.dll")]
private static extern long PhoneGetCallLogEntry(IntPtr h,
string pentry);

// PhoneSeekCallLog seeks to a record in the call log.
// iRecord is the zero-based index of the record, starting at
the beginning
// if seek == CALLLOGSEEK_BEGINNING, at the end if
CALLLOGSEEK_END.
// piRecord returns the zero-based index (from the beginning)
of the seek
// pointer after the seek is performed.
// PhoneSeekCallLog(h, CALLLOGSEEK_END, 0, &count) will return
the number of
// records.
[DllImport("Phone.dll")]
private static extern long PhoneSeekCallLog(IntPtr hdb,
CALLLOGSEEK seek, UInt32 iRecord, ref UInt32 piRecord);

// Close the call log
[DllImport("Phone.dll")]
private static extern long PhoneCloseCallLog(IntPtr h);

// The Call Log application supports the context menu
extensibility mechanism.
// The Context name is "Phone" and the Class name is "Log".
// The IUnknown pointer passed to the context menu handler
supports IPropertyBag,
// and the set of properties supported is as follows:
//
// property name: type: value:
// -------------- ----- ------
// PropSet BSTR "CallLog"
// Number BSTR the phone number of the other
person on the call
// NumberType BSTR the type of phone number (e.g. "h"
for home)
// Name BSTR person's name
// Year I2 the year of the beginning time of
the call
// Month I2 the month of the beginning time of
the call
// Day I2 the day of the beginning time of
the call
// Hour I2 the hour of the beginning time of
the call
// Minute I2 the minute of the beginning time of
the call
// Second I2 the second of the beginning time of
the call
// DayOfWeek I2 the day of the week of the
beginning time of the call
// Duration UI4 the duration of the call in seconds
// CallerIDType UI4 a CALLERIDTYPE value (see above)
// Connected BOOL Did the call connect? (as opposed
to busy, no answer)
// Ended BOOL Was the call ended? (as opposed to
dropped)
// Outgoing BOOL Was the call outgoing? (Missed
calls are incoming.)
// Roaming BOOL Roaming?
// IOM UI4 an IOM value (see above)



// PhoneShowCallLog
//
// Show the Call Log, and filter it

private enum CALLLOGFILTER
{
CALLLOGFILTER_ALL_CALLS,
CALLLOGFILTER_MISSED,
CALLLOGFILTER_INCOMING,
CALLLOGFILTER_OUTGOING
}

[DllImport("Phone.dll")]
private static extern long PhoneShowCallLog(CALLLOGFILTER
iCallLogFilter);

}
}
 
Firstly all your return types are wrong, you should use int not long (which
is an Int64).
Next your definition of CALLLOGENTRY is wrong - a filetime is a 64bit value
and you'll need to convert it to a DateTime using DateTime.FromFileTimeUTC
to get the DateTime value.
BOOL type is 4bytes (Int32) so precede them with
[MarshalAs(UnmanagedType.Bool)]

Strings are marshalled as pointers so precede each with
[MarshalAs(UnmanagedType.LPWStr)]

All of the above assumes .NETCF v2.0, v1.0 doesn't have the MarshalAs
attribute so you need to declare the bools as ints and the strings as IntPtr
and marshal them manually yourself.

Peter

--
Peter Foot
Device Application Development MVP
www.peterfoot.net | www.inthehand.com

Mpoy said:
I need to use the Phone API of the compact framework. I have tried
using the Marshall class and tried to wrap it in C# code so I can use
it as a managed code but it doesn't work. I also don't have any idea on
how can I use the 'PhoneGetCallLogEntry' function. Can anyone help me
pls. This is my wrapped code:

(in reference to phone.h)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace ProjectObjects
{
public class W_Phone
{
public W_Phone()
{
}

private enum CALLERIDTYPE
{
CALLERIDTYPE_UNAVAILABLE,
CALLERIDTYPE_BLOCKED,
CALLERIDTYPE_AVAILABLE
}

private enum IOM
{
IOM_MISSED,
IOM_INCOMING,
IOM_OUTGOING
}

private enum CALLLOGSEEK
{
CALLLOGSEEK_BEGINNING = 2,
CALLLOGSEEK_END = 4
}

[StructLayout(LayoutKind.Sequential)]
private struct CALLLOGENTRY
{
public UInt32 cbSize; // sizeof CALLLOGENTRY
public DateTime ftStartTime;
public DateTime ftEndTime;
public IOM iom;
public bool fOutgoing; // direction of call.
(Missed calls are incoming.)
public bool fConnected1; // Did the call connect? (as
opposed to busy, no answer)
public bool fEnded; // Was the call ended? (as
opposed to dropped)
public bool fRoam; // Roaming (vs. local)
public CALLERIDTYPE cidt;
public string pszNumber;
public string pszName;
public string pszNameType; // "w" for work tel, "h" for
home tel, for example
public string pszNote; // filename of associated Notes
file
}

// Open the call log and set the seek pointer to the beginning.
[DllImport("Phone.dll")]
private static extern long PhoneOpenCallLog(out IntPtr ph);


// PhoneGetCallLogEntry returns one call log entry and advances
the seek
// pointer.
// pentry->cbSize must be set to "sizeof CALLLOGENTRY" before
this function is
// called.
// The entries are returned in order of start time, the most
recent call first.
// It is the responsibility of the caller to LocalFree any
strings
// which are returned.
// A return value of S_FALSE indicates there are no more
entries.
[DllImport("Phone.dll")]
private static extern long PhoneGetCallLogEntry(IntPtr h,
string pentry);

// PhoneSeekCallLog seeks to a record in the call log.
// iRecord is the zero-based index of the record, starting at
the beginning
// if seek == CALLLOGSEEK_BEGINNING, at the end if
CALLLOGSEEK_END.
// piRecord returns the zero-based index (from the beginning)
of the seek
// pointer after the seek is performed.
// PhoneSeekCallLog(h, CALLLOGSEEK_END, 0, &count) will return
the number of
// records.
[DllImport("Phone.dll")]
private static extern long PhoneSeekCallLog(IntPtr hdb,
CALLLOGSEEK seek, UInt32 iRecord, ref UInt32 piRecord);

// Close the call log
[DllImport("Phone.dll")]
private static extern long PhoneCloseCallLog(IntPtr h);

// The Call Log application supports the context menu
extensibility mechanism.
// The Context name is "Phone" and the Class name is "Log".
// The IUnknown pointer passed to the context menu handler
supports IPropertyBag,
// and the set of properties supported is as follows:
//
// property name: type: value:
// -------------- ----- ------
// PropSet BSTR "CallLog"
// Number BSTR the phone number of the other
person on the call
// NumberType BSTR the type of phone number (e.g. "h"
for home)
// Name BSTR person's name
// Year I2 the year of the beginning time of
the call
// Month I2 the month of the beginning time of
the call
// Day I2 the day of the beginning time of
the call
// Hour I2 the hour of the beginning time of
the call
// Minute I2 the minute of the beginning time of
the call
// Second I2 the second of the beginning time of
the call
// DayOfWeek I2 the day of the week of the
beginning time of the call
// Duration UI4 the duration of the call in seconds
// CallerIDType UI4 a CALLERIDTYPE value (see above)
// Connected BOOL Did the call connect? (as opposed
to busy, no answer)
// Ended BOOL Was the call ended? (as opposed to
dropped)
// Outgoing BOOL Was the call outgoing? (Missed
calls are incoming.)
// Roaming BOOL Roaming?
// IOM UI4 an IOM value (see above)



// PhoneShowCallLog
//
// Show the Call Log, and filter it

private enum CALLLOGFILTER
{
CALLLOGFILTER_ALL_CALLS,
CALLLOGFILTER_MISSED,
CALLLOGFILTER_INCOMING,
CALLLOGFILTER_OUTGOING
}

[DllImport("Phone.dll")]
private static extern long PhoneShowCallLog(CALLLOGFILTER
iCallLogFilter);

}
}
 
Thank you Peter for your great help. I badly need help on this, this is
very hard for me to understand.

By the way I have already changed the code and I tried to make a method
so that I could use the API functions, but I get a
'System.NotSupportedException' when I use my method.

Here's my code: (GetInfo() is the method that i created and called in
the main program)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;

namespace ProjectObjects
{
public class W_Phone
{
public W_Phone()
{
}

public string GetInfo()
{
CALLLOGENTRY log = new CALLLOGENTRY();
log.cbSize = Marshal.SizeOf(log);
PhoneGetCallLogEntry(IntPtr.Zero, ref log);
return log.ftStartTime.ToString();
}

private enum CALLERIDTYPE
{
CALLERIDTYPE_UNAVAILABLE,
CALLERIDTYPE_BLOCKED,
CALLERIDTYPE_AVAILABLE
}

private enum IOM
{
IOM_MISSED,
IOM_INCOMING,
IOM_OUTGOING
}

private enum CALLLOGSEEK
{
CALLLOGSEEK_BEGINNING = 2,
CALLLOGSEEK_END = 4
}

[StructLayout(LayoutKind.Sequential)]
private struct CALLLOGENTRY
{
public int cbSize; // sizeof CALLLOGENTRY

public long ftStartTime;
public long ftEndTime;
public IOM iom;
[MarshalAs(UnmanagedType.Bool)]
public int fOutgoing; // direction of call.
(Missed calls are incoming.)
[MarshalAs(UnmanagedType.Bool)]
public int fConnected1; // Did the call connect? (as
opposed to busy, no answer)
[MarshalAs(UnmanagedType.Bool)]
public int fEnded; // Was the call ended? (as
opposed to dropped)
[MarshalAs(UnmanagedType.Bool)]
public int fRoam; // Roaming (vs. local)
public CALLERIDTYPE cidt;
[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pszNumber;
[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pszName;
[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pszNameType; // "w" for work tel, "h" for
home tel, for example
[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pszNote; // filename of associated Notes
file
}

// Open the call log and set the seek pointer to the beginning.
[DllImport("Phone.dll")]
private static extern int PhoneOpenCallLog(out IntPtr ph);


// PhoneGetCallLogEntry returns one call log entry and advances
the seek
// pointer.
// pentry->cbSize must be set to "sizeof CALLLOGENTRY" before
this function is
// called.
// The entries are returned in order of start time, the most
recent call first.
// It is the responsibility of the caller to LocalFree any
strings
// which are returned.
// A return value of S_FALSE indicates there are no more
entries.
[DllImport("Phone.dll")]
private static extern int PhoneGetCallLogEntry(IntPtr h, ref
CALLLOGENTRY pentry);

// PhoneSeekCallLog seeks to a record in the call log.
// iRecord is the zero-based index of the record, starting at
the beginning
// if seek == CALLLOGSEEK_BEGINNING, at the end if
CALLLOGSEEK_END.
// piRecord returns the zero-based index (from the beginning)
of the seek
// pointer after the seek is performed.
// PhoneSeekCallLog(h, CALLLOGSEEK_END, 0, &count) will return
the number of
// records.
[DllImport("Phone.dll")]
private static extern int PhoneSeekCallLog(IntPtr hdb,
CALLLOGSEEK seek, UInt32 iRecord, ref UInt32 piRecord);

// Close the call log
[DllImport("Phone.dll")]
private static extern int PhoneCloseCallLog(IntPtr h);

// The Call Log application supports the context menu
extensibility mechanism.
// The Context name is "Phone" and the Class name is "Log".
// The IUnknown pointer passed to the context menu handler
supports IPropertyBag,
// and the set of properties supported is as follows:
//
// property name: type: value:
// -------------- ----- ------
// PropSet BSTR "CallLog"
// Number BSTR the phone number of the other
person on the call
// NumberType BSTR the type of phone number (e.g. "h"
for home)
// Name BSTR person's name
// Year I2 the year of the beginning time of
the call
// Month I2 the month of the beginning time of
the call
// Day I2 the day of the beginning time of
the call
// Hour I2 the hour of the beginning time of
the call
// Minute I2 the minute of the beginning time of
the call
// Second I2 the second of the beginning time of
the call
// DayOfWeek I2 the day of the week of the
beginning time of the call
// Duration UI4 the duration of the call in seconds
// CallerIDType UI4 a CALLERIDTYPE value (see above)
// Connected BOOL Did the call connect? (as opposed
to busy, no answer)
// Ended BOOL Was the call ended? (as opposed to
dropped)
// Outgoing BOOL Was the call outgoing? (Missed
calls are incoming.)
// Roaming BOOL Roaming?
// IOM UI4 an IOM value (see above)



// PhoneShowCallLog
//
// Show the Call Log, and filter it

private enum CALLLOGFILTER
{
CALLLOGFILTER_ALL_CALLS,
CALLLOGFILTER_MISSED,
CALLLOGFILTER_INCOMING,
CALLLOGFILTER_OUTGOING
}

[DllImport("Phone.dll")]
private static extern int PhoneShowCallLog(CALLLOGFILTER
iCallLogFilter);

}
}

Firstly all your return types are wrong, you should use int not long (which
is an Int64).
Next your definition of CALLLOGENTRY is wrong - a filetime is a 64bit value
and you'll need to convert it to a DateTime using DateTime.FromFileTimeUTC
to get the DateTime value.
BOOL type is 4bytes (Int32) so precede them with
[MarshalAs(UnmanagedType.Bool)]

Strings are marshalled as pointers so precede each with
[MarshalAs(UnmanagedType.LPWStr)]

All of the above assumes .NETCF v2.0, v1.0 doesn't have the MarshalAs
attribute so you need to declare the bools as ints and the strings as IntPtr
and marshal them manually yourself.

Peter

--
Peter Foot
Device Application Development MVP
www.peterfoot.net | www.inthehand.com

Mpoy said:
I need to use the Phone API of the compact framework. I have tried
using the Marshall class and tried to wrap it in C# code so I can use
it as a managed code but it doesn't work. I also don't have any idea on
how can I use the 'PhoneGetCallLogEntry' function. Can anyone help me
pls. This is my wrapped code:

(in reference to phone.h)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace ProjectObjects
{
public class W_Phone
{
public W_Phone()
{
}

private enum CALLERIDTYPE
{
CALLERIDTYPE_UNAVAILABLE,
CALLERIDTYPE_BLOCKED,
CALLERIDTYPE_AVAILABLE
}

private enum IOM
{
IOM_MISSED,
IOM_INCOMING,
IOM_OUTGOING
}

private enum CALLLOGSEEK
{
CALLLOGSEEK_BEGINNING = 2,
CALLLOGSEEK_END = 4
}

[StructLayout(LayoutKind.Sequential)]
private struct CALLLOGENTRY
{
public UInt32 cbSize; // sizeof CALLLOGENTRY
public DateTime ftStartTime;
public DateTime ftEndTime;
public IOM iom;
public bool fOutgoing; // direction of call.
(Missed calls are incoming.)
public bool fConnected1; // Did the call connect? (as
opposed to busy, no answer)
public bool fEnded; // Was the call ended? (as
opposed to dropped)
public bool fRoam; // Roaming (vs. local)
public CALLERIDTYPE cidt;
public string pszNumber;
public string pszName;
public string pszNameType; // "w" for work tel, "h" for
home tel, for example
public string pszNote; // filename of associated Notes
file
}

// Open the call log and set the seek pointer to the beginning.
[DllImport("Phone.dll")]
private static extern long PhoneOpenCallLog(out IntPtr ph);


// PhoneGetCallLogEntry returns one call log entry and advances
the seek
// pointer.
// pentry->cbSize must be set to "sizeof CALLLOGENTRY" before
this function is
// called.
// The entries are returned in order of start time, the most
recent call first.
// It is the responsibility of the caller to LocalFree any
strings
// which are returned.
// A return value of S_FALSE indicates there are no more
entries.
[DllImport("Phone.dll")]
private static extern long PhoneGetCallLogEntry(IntPtr h,
string pentry);

// PhoneSeekCallLog seeks to a record in the call log.
// iRecord is the zero-based index of the record, starting at
the beginning
// if seek == CALLLOGSEEK_BEGINNING, at the end if
CALLLOGSEEK_END.
// piRecord returns the zero-based index (from the beginning)
of the seek
// pointer after the seek is performed.
// PhoneSeekCallLog(h, CALLLOGSEEK_END, 0, &count) will return
the number of
// records.
[DllImport("Phone.dll")]
private static extern long PhoneSeekCallLog(IntPtr hdb,
CALLLOGSEEK seek, UInt32 iRecord, ref UInt32 piRecord);

// Close the call log
[DllImport("Phone.dll")]
private static extern long PhoneCloseCallLog(IntPtr h);

// The Call Log application supports the context menu
extensibility mechanism.
// The Context name is "Phone" and the Class name is "Log".
// The IUnknown pointer passed to the context menu handler
supports IPropertyBag,
// and the set of properties supported is as follows:
//
// property name: type: value:
// -------------- ----- ------
// PropSet BSTR "CallLog"
// Number BSTR the phone number of the other
person on the call
// NumberType BSTR the type of phone number (e.g. "h"
for home)
// Name BSTR person's name
// Year I2 the year of the beginning time of
the call
// Month I2 the month of the beginning time of
the call
// Day I2 the day of the beginning time of
the call
// Hour I2 the hour of the beginning time of
the call
// Minute I2 the minute of the beginning time of
the call
// Second I2 the second of the beginning time of
the call
// DayOfWeek I2 the day of the week of the
beginning time of the call
// Duration UI4 the duration of the call in seconds
// CallerIDType UI4 a CALLERIDTYPE value (see above)
// Connected BOOL Did the call connect? (as opposed
to busy, no answer)
// Ended BOOL Was the call ended? (as opposed to
dropped)
// Outgoing BOOL Was the call outgoing? (Missed
calls are incoming.)
// Roaming BOOL Roaming?
// IOM UI4 an IOM value (see above)



// PhoneShowCallLog
//
// Show the Call Log, and filter it

private enum CALLLOGFILTER
{
CALLLOGFILTER_ALL_CALLS,
CALLLOGFILTER_MISSED,
CALLLOGFILTER_INCOMING,
CALLLOGFILTER_OUTGOING
}

[DllImport("Phone.dll")]
private static extern long PhoneShowCallLog(CALLLOGFILTER
iCallLogFilter);

}
}
 
Did you narrow down the line number that the exception is coming from? That
might give you a clue on what it is that is wrong with your code. Also, you
can try using the Interop log. You can read this for more info:

http://blogs.msdn.com/stevenpr/archive/2005/06/22/431612.aspx

Mpoy said:
Thank you Peter for your great help. I badly need help on this, this is
very hard for me to understand.

By the way I have already changed the code and I tried to make a method
so that I could use the API functions, but I get a
'System.NotSupportedException' when I use my method.

Here's my code: (GetInfo() is the method that i created and called in
the main program)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;

namespace ProjectObjects
{
public class W_Phone
{
public W_Phone()
{
}

public string GetInfo()
{
CALLLOGENTRY log = new CALLLOGENTRY();
log.cbSize = Marshal.SizeOf(log);
PhoneGetCallLogEntry(IntPtr.Zero, ref log);
return log.ftStartTime.ToString();
}

private enum CALLERIDTYPE
{
CALLERIDTYPE_UNAVAILABLE,
CALLERIDTYPE_BLOCKED,
CALLERIDTYPE_AVAILABLE
}

private enum IOM
{
IOM_MISSED,
IOM_INCOMING,
IOM_OUTGOING
}

private enum CALLLOGSEEK
{
CALLLOGSEEK_BEGINNING = 2,
CALLLOGSEEK_END = 4
}

[StructLayout(LayoutKind.Sequential)]
private struct CALLLOGENTRY
{
public int cbSize; // sizeof CALLLOGENTRY

public long ftStartTime;
public long ftEndTime;
public IOM iom;
[MarshalAs(UnmanagedType.Bool)]
public int fOutgoing; // direction of call.
(Missed calls are incoming.)
[MarshalAs(UnmanagedType.Bool)]
public int fConnected1; // Did the call connect? (as
opposed to busy, no answer)
[MarshalAs(UnmanagedType.Bool)]
public int fEnded; // Was the call ended? (as
opposed to dropped)
[MarshalAs(UnmanagedType.Bool)]
public int fRoam; // Roaming (vs. local)
public CALLERIDTYPE cidt;
[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pszNumber;
[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pszName;
[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pszNameType; // "w" for work tel, "h" for
home tel, for example
[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pszNote; // filename of associated Notes
file
}

// Open the call log and set the seek pointer to the beginning.
[DllImport("Phone.dll")]
private static extern int PhoneOpenCallLog(out IntPtr ph);


// PhoneGetCallLogEntry returns one call log entry and advances
the seek
// pointer.
// pentry->cbSize must be set to "sizeof CALLLOGENTRY" before
this function is
// called.
// The entries are returned in order of start time, the most
recent call first.
// It is the responsibility of the caller to LocalFree any
strings
// which are returned.
// A return value of S_FALSE indicates there are no more
entries.
[DllImport("Phone.dll")]
private static extern int PhoneGetCallLogEntry(IntPtr h, ref
CALLLOGENTRY pentry);

// PhoneSeekCallLog seeks to a record in the call log.
// iRecord is the zero-based index of the record, starting at
the beginning
// if seek == CALLLOGSEEK_BEGINNING, at the end if
CALLLOGSEEK_END.
// piRecord returns the zero-based index (from the beginning)
of the seek
// pointer after the seek is performed.
// PhoneSeekCallLog(h, CALLLOGSEEK_END, 0, &count) will return
the number of
// records.
[DllImport("Phone.dll")]
private static extern int PhoneSeekCallLog(IntPtr hdb,
CALLLOGSEEK seek, UInt32 iRecord, ref UInt32 piRecord);

// Close the call log
[DllImport("Phone.dll")]
private static extern int PhoneCloseCallLog(IntPtr h);

// The Call Log application supports the context menu
extensibility mechanism.
// The Context name is "Phone" and the Class name is "Log".
// The IUnknown pointer passed to the context menu handler
supports IPropertyBag,
// and the set of properties supported is as follows:
//
// property name: type: value:
// -------------- ----- ------
// PropSet BSTR "CallLog"
// Number BSTR the phone number of the other
person on the call
// NumberType BSTR the type of phone number (e.g. "h"
for home)
// Name BSTR person's name
// Year I2 the year of the beginning time of
the call
// Month I2 the month of the beginning time of
the call
// Day I2 the day of the beginning time of
the call
// Hour I2 the hour of the beginning time of
the call
// Minute I2 the minute of the beginning time of
the call
// Second I2 the second of the beginning time of
the call
// DayOfWeek I2 the day of the week of the
beginning time of the call
// Duration UI4 the duration of the call in seconds
// CallerIDType UI4 a CALLERIDTYPE value (see above)
// Connected BOOL Did the call connect? (as opposed
to busy, no answer)
// Ended BOOL Was the call ended? (as opposed to
dropped)
// Outgoing BOOL Was the call outgoing? (Missed
calls are incoming.)
// Roaming BOOL Roaming?
// IOM UI4 an IOM value (see above)



// PhoneShowCallLog
//
// Show the Call Log, and filter it

private enum CALLLOGFILTER
{
CALLLOGFILTER_ALL_CALLS,
CALLLOGFILTER_MISSED,
CALLLOGFILTER_INCOMING,
CALLLOGFILTER_OUTGOING
}

[DllImport("Phone.dll")]
private static extern int PhoneShowCallLog(CALLLOGFILTER
iCallLogFilter);

}
}

Firstly all your return types are wrong, you should use int not long (which
is an Int64).
Next your definition of CALLLOGENTRY is wrong - a filetime is a 64bit value
and you'll need to convert it to a DateTime using DateTime.FromFileTimeUTC
to get the DateTime value.
BOOL type is 4bytes (Int32) so precede them with
[MarshalAs(UnmanagedType.Bool)]

Strings are marshalled as pointers so precede each with
[MarshalAs(UnmanagedType.LPWStr)]

All of the above assumes .NETCF v2.0, v1.0 doesn't have the MarshalAs
attribute so you need to declare the bools as ints and the strings as IntPtr
and marshal them manually yourself.

Peter

--
Peter Foot
Device Application Development MVP
www.peterfoot.net | www.inthehand.com

Mpoy said:
I need to use the Phone API of the compact framework. I have tried
using the Marshall class and tried to wrap it in C# code so I can use
it as a managed code but it doesn't work. I also don't have any idea on
how can I use the 'PhoneGetCallLogEntry' function. Can anyone help me
pls. This is my wrapped code:

(in reference to phone.h)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace ProjectObjects
{
public class W_Phone
{
public W_Phone()
{
}

private enum CALLERIDTYPE
{
CALLERIDTYPE_UNAVAILABLE,
CALLERIDTYPE_BLOCKED,
CALLERIDTYPE_AVAILABLE
}

private enum IOM
{
IOM_MISSED,
IOM_INCOMING,
IOM_OUTGOING
}

private enum CALLLOGSEEK
{
CALLLOGSEEK_BEGINNING = 2,
CALLLOGSEEK_END = 4
}

[StructLayout(LayoutKind.Sequential)]
private struct CALLLOGENTRY
{
public UInt32 cbSize; // sizeof CALLLOGENTRY
public DateTime ftStartTime;
public DateTime ftEndTime;
public IOM iom;
public bool fOutgoing; // direction of call.
(Missed calls are incoming.)
public bool fConnected1; // Did the call connect? (as
opposed to busy, no answer)
public bool fEnded; // Was the call ended? (as
opposed to dropped)
public bool fRoam; // Roaming (vs. local)
public CALLERIDTYPE cidt;
public string pszNumber;
public string pszName;
public string pszNameType; // "w" for work tel, "h" for
home tel, for example
public string pszNote; // filename of associated Notes
file
}

// Open the call log and set the seek pointer to the beginning.
[DllImport("Phone.dll")]
private static extern long PhoneOpenCallLog(out IntPtr ph);


// PhoneGetCallLogEntry returns one call log entry and advances
the seek
// pointer.
// pentry->cbSize must be set to "sizeof CALLLOGENTRY" before
this function is
// called.
// The entries are returned in order of start time, the most
recent call first.
// It is the responsibility of the caller to LocalFree any
strings
// which are returned.
// A return value of S_FALSE indicates there are no more
entries.
[DllImport("Phone.dll")]
private static extern long PhoneGetCallLogEntry(IntPtr h,
string pentry);

// PhoneSeekCallLog seeks to a record in the call log.
// iRecord is the zero-based index of the record, starting at
 
Back
Top