Monday, February 25, 2008

Windows Mobile Development: Tips 'n' Tricks

[Been meaning to post this a long time back but finally got to it, so here's an initial dump]
  • Sometimes changing a registry key manually via CE Remote Tools doesn't seem to persist, especially noticeable if you soft reset right after changing a registry value. This is a known behavior due to disk buffering/writing optimizations and clarified in this blog post. If you write a registry key programmatically and you want to be absolutely certain its written out to disk, you can either use native RegFlushKey() call or, in .Net CF, the Flush() method of RegistryKey class (Note that RegistryState does not offer a flush mechanism). Use this flushing sparingly and after a group of registry writing activities rather than after each call.
  • Smartphone/PocketPC Detection:
    • This article highlights the deprecated features in Windows Mobile 6. Note that it mentions SPI_GETPLATFORMTYPE has been deprecated to be replaced by SPI_GETPROJECTNAME . That's important, as that is usually used to do intelligent behavior to handle Smartphone / PocketPC in the same code. Interestingly, even on WM6, SPI_GETPLATFORMTYPE still seems to work. So it is yet to get phased out in the early WM6 AKUs I guess.
    • Another way is, if you use same code but shared in separate projects for PocketPC/Smartphone via Visual Studio you get two pre-defined constants 'PocketPC' or 'Smartphone'. You can use these via '#if' directives.
      • In case you are wondering how to add a source file as a link in Visual Studio [From MSDN]: "To add a source file as a link, right-click on a project in Solution Explorer, and then click Add Existing Item. In the Add Existing Item dialog box, select the file that you want to add. Instead of clicking the Add button, click the arrow to the right of it (as shown in the following figure), and then click Add As Link.".
  • Doing processing in form Load call: If you have a form Load event handler where you wish to do processing after the form has loaded but wish to display form first while you process information Do a DoEverts() call after this.Show(). The form gets rendered first while you do further processsing in the Load call.
private void Form1_Load(object sender, EventArgs e)
{
this.Show();
Application.DoEvents();
DoStuff();
}
  • Use SHGetSpecialFolderLocation to get the standard folders path on PocketPC/Smartphone: Not only is it safe in internationalization, but also you skip some systemic differences. For example, if you want to programmatically create a shortcut (via SHCreateShortcutEx) to your application to show in the the Programs folder then on Smartphone the folder is "\Windows\Windows\Start Menu\ " or on PocketPC it is "\Windows\Start Menu\Programs".
  • Connectivity Detection in WM6
    • Some very interesting properties can be found in the SystemState class in Microsoft.WindowsMobile.Status namespace (and dll).
    • Some interesting properties are
      • Number of network connections: SystemState.ConnectionsNetworkCount
      • Get the phone GPRS coverage : SystemState.PhoneGprsCoverage
      • SystemState.PhoneBlockedSim
      • SystemState.PhoneInvalidSim
      • SystemState.PhoneNoService
      • SystemState.PhoneNoSim
      • SystemState.PhoneRadioOff
      • SystemState.PhoneRadioPresent
  • Assembly Strong Naming, Type Loading and Plugins
    • Trying to load types dynamically using the AssemblyQualifiedName, say via Type.GetType() (format: [assembly], [version], [Culture], PublicKeyToken=)
    • The assembly has to be strong named to load a type by version. If its not strong named, then the version you specify is ignored, and the type would get loaded from an assembly irrespective of version.
    • Also, the assembly name is the name of assembly during the creation (i.e. during strong naming process). I.e. if you rename the assembly, and try to use the new name to load a Type from it, it will not work. GetType looks into the assembly metadata to get the original name of assembly.
    • If attempting to use this in say a dynamic plug-in manger/plug-in model you may come across InvalidCastException problem since the interface/shared elements are being used from the specific plug-in. To load different types in different plugins/assemblies, but which use the same interface, you can move the interface into its own little project so that the interface type is referenced by the plugins and the plugin manager/loader. Here is a nice post about the plugin model: http://www.yoda.arachsys.com/csharp/plugin.html
  • Wireless data connections such as WiFi on device get turned off when device is connected to computer via Activesync:
    • If you wish to have it enabled while device is connected to computer via ActiveSync it automatically turns off the Wireless connections. If you wish to enable this goto ActiveSync properties and check the last option.

0 comments: