# Saturday, January 28, 2006

OpenNETCF.IO in SDF 2.0

As well as the revolutionary changes in the SDF v2.0, some of which are simply only made possible by improvements in .NETCF v2.0, we have used this opportunity to make a number of evolutionary changes too. For example I'm going to take a quick trip through the file functionality in the OpenNETCF.IO namespace:-

DriveInfo - This is a new class which mimics functionality new in the desktop framework v2.0 and replaces previous separate classes for StorageCard and ObjectStore information. You can use it in two ways, use the constructor which takes a path and pass in the path of your storage device e.g. "\" or "\Storage Card" or you can use the static GetDrives() method which will return an array of all devices. A pleasant side-effect of this is that you can data-bind to this array of DriveInfo objects.

OpenNETCF.IO.DriveInfo[] di = OpenNETCF.IO.DriveInfo.GetDrives();
dataGrid1.DataSource = di;

File2 - To follow accepted naming behaviour we have stopped using Ex as a name suffix and so instead our classes which overlap existing classes in .NETCF have the 2 suffix. I have added some additional helper methods which are found on the desktop to quickly read/write whole files - ReadAllText / ReadAllLines and WriteAllText / WriteAllLines.

File2.WriteAllText(filename, textBox1.Text);

FileSystemWatcher - We've made some improvements here so that all the various event combinations are correctly raised. Also we have built in designer support for VS2005 so you can drop a FileSystemWatcher onto your form and hook up the events in the designer.

#    Comments [0] |
# Thursday, January 19, 2006

GetDeviceUniqueID For VB

To complement the C# version posted Here,  here is a working VB translation:-

<System.Runtime.InteropServices.DllImport("coredll.dll")> _
Private Shared Function GetDeviceUniqueID(ByVal appdata As Byte(), ByVal cbApplictionData As Integer, ByVal dwDeviceIDVersion As Integer, ByVal deviceIDOuput As Byte(), ByRef pcbDeviceIDOutput As Integer) As Integer
End Function

Private Function GetDeviceId(ByVal appData As String) As Byte()

Dim appDataBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(appData)
Dim outputSize As Integer = 20
Dim output(19) As Byte

Dim result As Integer = GetDeviceUniqueID(appDataBytes, appDataBytes.Length, 1, output, outputSize)

Return output

End Function

#    Comments [0] |

Indigo Reaches Beta 2 And Gets Go-Live License

Indigo (Yeah I know I'm supposed to call it Windows Communication Foundation), has reached the Beta 2 milestone. With this release you can apply for a Go-Live license to deploy the technology in live environments*

Read all about it here:-

http://msdn.microsoft.com/winfx/getthebeta/golive/

*Terms and conditions apply. Your small print may go down as well as up.

#    Comments [0] |
# Sunday, January 15, 2006

Any Port in a Storm

A user posted an important observation on the Bluetooth COM support in Windows Mobile 5 here on the microsoft.public.pocketpc.developer newsgroup. The problem is that while the system allows you to create virtual COM ports for all your paired devices which support Serial Port Profile, most of the time this will fail because the COM port you pick is already in use, on many devices you can have just 2 virtual COM ports. I've posted a few of my thoughts in the thread linked above, but while there are things that Microsoft can work to improve there are also a few things that developers can do to avoid the problem:-

  • Don't rely on the control panel for setting up ports, use the RegisterDevice route (or BluetoothSerialPort in 32Feet.net) to just register a port for the duration you need it (and possibly reuse the same port name). This also allows you to use a different port prefix since few COMx: ports are available out of the box.
  • Don't use serial ports. Unless you need your device to be accessible by a legacy app then you can avoid using virtual COM ports altogether and work directly with Sockets (again 32Feet.net will allow you to setup these connections easily). The downside with this approach is it applies only to the Microsoft Bluetooth Stack, as the programming model for the main alternative from Broadcom is essentially based around ports. However based on the first batch of devices released with Windows Mobile 5.0 the Broadcom stack is a lot less common.
#    Comments [0] |
# Tuesday, January 10, 2006

MEDC 2006 Europe

[via Jason Langridge]

MEDC will be returning to a dedicated conference for Europe this year, last year saw a number of one day events and in 2004 MDC was a thread within Tech Ed Europe.

 

Details are fairly basic at this early stage but if you are interested I suggest signing the "guestbook" so that you will be notified as more information becomes available.

#    Comments [0] |
# Sunday, January 08, 2006

Determine WM5.0 AKU Version Programmatically

The full build and AKU version of a device is shown on the Start > Settings > System > About screen, however what if you want to determine the version from your code. Well starting with Windows Mobile 5.0 there is now a registry key which holds the AKU version e.g.

RegistryKey kAku = Registry.LocalMachine.OpenSubKey("System\\Versions");

string akuVersion = kAku.GetValue("Aku", "");

kAku.Close();

This version will include a leading period so for example if the string is ".0.1.1" as on the current JasJar ROM the device has AKU 0.1, if it reads ".1.1.0" as on the current K-Jam ROM you have AKU 1.1. As far as I'm aware all shipping devices will have at least 0.1 as some fixes were implemented between RTM in May 2005 and the first shipping devices released later in the year. If your version is ".2.x.x" then you are a very lucky bunny indeed!

Whilst Windows Mobile 2003 had a similar concept of periodic AKU updates throughout it's lifetime this registry key is not available, nor is the AKU version displayed on the About dialog, only the Build number is displayed.

#    Comments [0] |
# Thursday, January 05, 2006

KeyboardPresent always returns false

This bug affects both managed and native developers working with the Windows Mobile 5.0 SDK.

Native

Due to an error in snapi.h the location of the registry key used to indicate if a hardware keyboard is present is incorrect:-

////////////////////////////////////////////////////////////////////////////////
// KeyboardPresent
// Gets a value indicating whether a keyboard is attached and enabled.
#define SN_KEYBOARDPRESENT_ROOT HKEY_LOCAL_MACHINE
#define SN_KEYBOARDPRESENT_PATH TEXT("Software\\Microsoft\\Shell")
#define SN_KEYBOARDPRESENT_VALUE TEXT("HasKeyboard")

The root key for this value should instead be HKEY_CURRENT_USER. Once you use this location you can correctly determine if there is a hardware keyboard (this is the same location as used on WM2003 Second Edition devices such as the HTC Blue Angel).

Managed

The SystemState class also uses the incorrect location to read this value so the property will always return false. The workaround here is to access the registry directly using either the Microsoft.Win32.RegistryKey in .NETCF v2.0 e.g.

RegistryKey keyboardKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Shell");

int dwHasKeyboard = keyboardKey.GetValue("HasKeyboard", 0);

keyboardKey.Close();

bool hasKeyboard = (dwHasKeyboard != 0);

#    Comments [0] |
# Wednesday, January 04, 2006

Bug in Microsoft.WindowsMobile.Telephone.Phone.Talk

Luis Cabrera has posted the details of a bug identified in the Talk method to the Windows Mobile Team blog. The workaround (see the original post) is to append a null character to the end of your dial string.

Note: this bug doesn't affect InTheHand.WindowsMobile.Telephony.Phone.Talk.

#    Comments [0] |
# Friday, December 23, 2005

The ItemId in Managed PocketOutlook

The ItemId type is introduced to the managed APIs to represent either a POOM Oid (int) or MAPI ENTRYID (16/14 bytes). It doesn’t directly expose the underlying data but there are a couple of useful behaviours:-

  • ItemId constructor accepts an int to create an ItemId from an existing known Oid value
  • For POOM items (Appointment, Contact, Task) calling GetHashCode() on the ItemId returns the underlying Oid. However since this behaviour is not specifically documented it cannot be relied upon to stay this way in a future version.
  • Oids on Windows Mobile 5.0 are created differently to previous versions. On older platforms the Oid is the identifier of the CEDB database record containing the item. On Windows Mobile 5.0 the databases are housed in an EDB database. Here the POOM Oid is a separate field containing a unique id and the item type, therefore it's possible to infer the type from an Oid unlike previous versions - 0x4000001 would be an Appointment, 0x80000001 a Contact and 0xC0000001 a Task.
#    Comments [0] |
# Thursday, December 22, 2005

PocketOutlook Native <-> Managed Map

Windows Mobile 5.0 introduces a managed API which wraps both POOM and a subset of CEMAPI (enough to send an Email / Sms). The table below is designed to show how the managed objects map to the interfaces which will be familiar to seasoned POOM developers. It also shows those parts of POOM which are not available through the managed APIs:-

Native

Managed

IPOutlookApp

OutlookSession

· Logon

Automatically handled

· Logoff

Automatic – call Dispose on your OutlookSession when finished

· get_Version

Not Supported – Get OS version with System.Environment.OSVersion.Version

· GetDefaultFolder

Use strongly typed folder properties - Appointments, Contacts & Tasks

Infrared not supported

· CreateItem

Use default constructor for specific item type

· GetItemFromOid

Use constructor for item which accepts an ItemId e.g.

new Contact(new ItemId(oid)

· City Methods (Removed in Pocket PC 2002)

Obsolete

· ReceiveFromInfrared (Obsolete from Pocket PC 2002)

Obsolete

· get_OutlookCompatible

Obsolete

· GetTimeZoneFromIndex

Not Supported

IFolder

Folder – AppointmentFolder, ContactFolder, TaskFolder

Infrared not supported

· get_Items

Items

· get_DefaultItemType

N/A inferred from the Folder type

· get_Application

N/A

· AddItemToInfraredFolder

Not Supported

· SendToInfrared

Not Supported

· ReceiveFromInfrared

Not Supported

IPOutlookItemCollection

PimItemCollection – AppointmentCollection, ContactCollection, TaskCollection

· Add

Add

· get_Count

Count

· Find

Find (Requires a PropertyDescriptor)

· FindNext

Not Supported

· Item

· 1-based index

Default indexer – () VB or [] C#

0-based index

· Remove

RemoveAt - also implements Remove(PimItem)

· Restrict

Restrict

· Sort

Sort

· get_IncludeRecurrences

Not Supported

· put_IncludeRecurrences

Not Supported

IAppointment

Appointment

· ClearRecurrencePattern

Call Clear on the AppointmentRecurrence

· GetRecurrencePattern

RecurrencePattern

· get_* / put_*

Accessible by named properties or via Ids through the Properties collection

· Save

Update

· Send

Send

· Delete

Delete

· Cancel

Cancel

· Copy

Copy

· Display

ShowDialog

· get_Oid

ItemId

· get_BodyInk / put_BodyInk

BodyInk no longer supported on WM5.0

IContact

Contact

· get_* / put_*

Accessible by named properties or via Ids through the Properties collection

· Save

Update

· Delete

Delete

· Copy

Copy

· Display

ShowDialog

· get_Oid

ItemId

· get_BodyInk / put_BodyInk

BodyInk no longer supported on WM5.0

ITask

Task

· ClearRecurrencePattern

Call Clear on the TaskRecurrence

· GetRecurrencePattern

RecurrencePattern

· get_* / put_*

Accessible by named properties or via Ids through the Properties collection

· Save

Update

· Delete

Delete

· SkipRecurrence

Call Skip on the TaskRecurrence

· Copy

Copy

· Display

ShowDialog

· get_Oid

ItemId

· get_BodyInk / put_BodyInk

BodyInk no longer supported on WM5.0

IItem

New in WM5.0 supports access to custom properties etc Functionality is available via Appointment, Contact and Task types

IRecipients

RecipientCollection

Shared with the Email (MAPI) support

IRecipient

Recipient

Shared with the Email (MAPI) support

IRecurrencePattern

Recurrence – AppointmentRecurrence, TaskRecurrence

Properties follow same names as native equivalent. Managed types such as TimeSpan and DateTime are used as appropriate. Enums defined for Months, WeekOfMonth, DaysOfWeek

IExceptions

Not supported

IException

Not supported

ITimeZone

Not supported

#    Comments [0] |
# Monday, December 19, 2005

XmlSerialization of DateTime in .NETCF 2.0

Changes have been made to the DateTime type in v2.0 to help indicate whether a specific value represents a local time or universal time. What this can mean is that the behaviour of web services using DateTimes will change. This article has full details of the issue:-

http://blogs.msdn.com/mattavis/archive/2005/10/11/479782.aspx

The same approach is available under .NETCF v2.0 to request the old v1 behaviour - add a configuration file for your exe with the following content:-

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

   <system.xml.serialization>

      <dateTimeSerialization mode="Local" />

   </system.xml.serialization>

</configuration>

#    Comments [0] |
# Saturday, December 17, 2005

XBox Live and Messenger convergence

Jason Langridge has recently given an interview to the BBC about an upcoming enhancement to XBox Live which will allow you to send messages from within XBox Live to MSN Messenger users, this is a very interesting feature and it makes a lot of sense to help tie the two systems together.

#    Comments [0] |

Reading E-Mail Through MAPI on Windows Mobile 5

Here is another issue I've been banging my head against a brick wall with and the workaround - although it's not a pleasant workaround by any measure.

To read the body text of an email message under WM2003 you open the PR_BODY property of the message and this gets you the plain text body of the message, no headers, no fancy encoding - just the facts! However in Windows Mobile 5 this now returns an empty stream. So how do we get at the body of the message, the Messaging application certainly knows how to. Well the answer from Microsoft is that although this change in behaviour is not documented you must now change your approach. Instead you need to access the PR_CE_MIME_TEXT property (defined in cemapi.h). This contains the entire message, header and all, and may require you to deal with mime encoded body. My first impression of this is that it's a backwards step which unnecessarily breaks existing code, you'd expect the API to deal with the underlying implementation and decoding and have the properties such as PR_BODY exposed to the outside world. Ah well, progress I guess...

#    Comments [0] |
# Thursday, December 15, 2005

Issue with Microsoft.WindowsMobile.PocketOutlook.RecipientCollection.Add()

When you want to create a meeting request with managed POOM on WM5.0 you start by creating an Appointment and then add Recipient objects to it's Recipients collection. However what the documentation doesn't tell you is that you have to ensure that your Recipient has both the Name and Address properties. For example:-

Microsoft.WindowsMobile.PocketOutlook.Appointment ma = new Microsoft.WindowsMobile.PocketOutlook.Appointment();
ma.Subject = "Test 5";
ma.Recipients.Add(new Microsoft.WindowsMobile.PocketOutlook.Recipient("user@yourdomain.com"));

Will throw a Win32Exception with the text "Native method call failed". This isn't very descriptive but the reason it fails is due to how native POOM works - the IRecipients.Add method takes a name argument and since your Name property is empty this call fails. If you specify the name e.g.

ma.Recipients.Add(new Microsoft.WindowsMobile.PocketOutlook.Recipient("User","user@yourdomain.com"));

or even this if you only have an address:-

ma.Recipients.Add(new Microsoft.WindowsMobile.PocketOutlook.Recipient("user@yourdomain.com","user@yourdomain.com"));

Then you'll be okay.

#    Comments [0] |
# Thursday, December 08, 2005

Windows Live Local goes live

As the name suggests, Windows Live Local (the new name for MSN Virtual Earth) is now live. It has a fresh new look, mapping data for Europe (woohoo!), supports driving directions, custom pushpins and for a selection of US cities it has high quality "birds-eye" images. There have been some changes to the API in this version, full details of which are due to hit MSDN today.

#    Comments [0] |
# Thursday, November 24, 2005

VS2005 and File Alignment

One of the transparent benefits of building your projects with VS2005 is that the default File Alignment is now set at 512 bytes, rather than the 4096 bytes which was the default for device projects in VS2003. This means if you create a new project in both versions and add exactly the same code you should notice the output dll created by VS2005 is noticably smaller.

One thing you may not realise is that the default value used in a VS2003 project is stored within the C# project file, which means if you import a VS2003 C# Smart Device project to VS2005 it will still use the value 4096. You can change this from the project properties > Build tab > Advanced button and set it to 512.

#    Comments [0] |