Tuesday, December 16, 2008

Property Header Control for Windows Mobile



I wrote an article a long time ago regarding developing a common property header control that is highly customizable for Windows Mobile. Now I finally got around to publishing it on the codeproject here: http://www.codeproject.com/KB/mobile/PropertyHeaderWM.aspx

Saturday, December 13, 2008

So what does a Silverlight app look like on a small device

Check this out: http://sl.weatherbug.com/. It's a Silverlight desktop application but been designed for a 320x240 screen. When you get the Silverlight bits in 2009 Q1 give this a try. You'll need a WM 6.1 device.

Monday, December 01, 2008

Silverlight 2 for Windows Mobile at PDC

As you have probably heard by now, Silverlight 2 for Windows Mobile has been announced by Microsoft and will be available as a CTP (community technology preview) build sometime Q1 2009.

One of Microsofts main goals with Silverlight 2 for Windows Mobile was to get the compatibility between desktop and device. So you can essentially write a Silverlight application for the desktop and run it within the browser on the device (with the Silverlight device plugin of course). So you can use Expression to build a Silverlight UI for devices. There is no "mobile" version for doing this.

Throughout the mobile community many LOB (line of business) developers are worried that you lose the smart client "occasionally connected" architecture that you get with embedded Compact Framework based development when you use Silverlight for mobile devices. There is some worry with this although Silverlight for mobile once downloaded, does stay in memory and allows you to continue using the application. Of course during this downtime you can't communicate back to the server as per a smart client app. You can with Silverlight make use of isolated storage, as remember, Silverlight runs in a sandbox this is great news for Silverlight mobile devs.
Even so, this is still not a smart client application. So precaution needs to be taken and architecture reviews need to be extensive when choosing either Silverlight over an embedded alternative.

This also leads to the question: "when would I choose to use Silverlight over the Compact Framework?". Good question! And the answer is probably similar to that of why you would use ASP.NET over Winforms/WPF, although alittle bit more complex for devices.

Check out the following video from PDC where fellow MVP Maarten Struys, Microsoft Mobile Community Manager Constanze and Program Manager Amit Chopra with Microsoft Evangelist Giorgio Sardo talk about Silverlight 2 for Windows Mobile:




Sunday, November 30, 2008

MSDN Code Gallery

Have you heard of the MSDN Code Gallery? Well here it is: http://code.msdn.microsoft.com/.

If you are a developer blogger or just want to make some code public for others to enjoy, this is an option to upload stuff without having to have a dedicated public server.

Targeting WVGA Screens on Windows Mobile/Smartphone

I wrote a post recently here. I showed a simple technique for supporting multiple screen resolutions when writing GDI code on Windows Mobile. The code doesn't change even with the new WVGA screens (640x800) coming to market. I've copied the code here:
private int DESIGNPOINTSPERINCH = 96;

protected override void OnPaint(PaintEventArgs e)
{
Graphics grfx = e.Graphics;
Brush foreColorBrush = new SolidBrush(Color.Black);
Font boldFont = new Font(Font.Name, 20, FontStyle.Bold);
grfx.DrawString("Hello World!",
boldFont, foreColorBrush,
20 * grfx.DpiY / DESIGNPOINTSPERINCH,
20 * grfx.DpiY / DESIGNPOINTSPERINCH);
boldFont.Dispose();
foreColorBrush.Dispose();
}

Wednesday, November 26, 2008

Submitting an IFramed Web App running within Microsoft CRM 4.0 - from CRM

Jan 09 UPDATE: I have written a better way to do this here.

This is a quick tip that might save you hours trying to figure this out (or maybe not) which is to force a page submit when the user clicks save within CRM.

In the JavaScript OnLoad event of the Form in CRM, place the following JavaScript:

document.frames("IFRAME_name").document[0].submit();

Where "IFRAME_name" is the actual name of your IFrame.

Then in your OnLoad event of your ASPX web page, you can write something like:
if (IsPostBack)
Save();
Note, for each postback you'll end of saving the form - something to bear in mind.

Creating a managed configuration service provider API article



UPDATE: Now published on MSDN which has nicer formatting.

I recently wrote an article for MSDN which can be found here about writing a managed configuration service provider API which is extensible.

Microsoft has also published the article on the Microsoft Developer Centre over at http://www.devx.com/MS_DeveloperCentre/Article/40015 but there is no code attachment included with the article as the article refers other than the code in the document. So until the whole thing is published on MSDN I thought I'd upload the code on the MSDN code gallery which can be found here, or if you prefer a direct link to the code here.

Note: This article kind of extends this post to a much greater level. I decided not to label it "Part 2" though.

Tuesday, November 25, 2008

Micro Focus Case Study with COBOL managed support

Way back in the day....I used to work very closely with Micro Focus. If you didn't know Micro Focus develop a COBOL compiler and IDE called NetExpress. Their latest offering includes support for a COBOL compiler than compiles to IL which plugs into Visual Studio 2008 so COBOL developers can write managed code. The latest version of NetExpress is v5.1.

Micro Focus did a case study on the company I worked for at the time here (if you're interested :))

Monday, November 24, 2008

IE 6 on 6

As you've probably heard by now (announced at Tech Ed EMEA) that Windows Mobile 6.1 Pro and Standard emulators have been released and can be downloaded from here.

One thing I thought I'd mention is the support for WVGA screens (800x640) with these new emulators. So you can test for devices such as the new Samsung i900 or the HTC Touch Pro without having to actually own these expensive devices.



Also IE 6 on 6 (Internet Explorer 6 Mobile) is included in these emulator images. If you don't know what 6 on 6 is, it is the IE engine running on the device. I'm not a "web" guy but this is pretty cool stuff. But sadly this version of IE requires a new ROM image which means you will have to buy a new device or wait for your device OEM/carrier to issue a flash upgrade.


Internet Explorer 6 Mobile

Saturday, November 22, 2008

Extension method support in Compact Framework 2.0 applications

I had a discussion recently with my fellow MVPs and you can use C# 3.0 language features in a CF 2.0 app with VS 2008 and even extension methods with a small hack.

Simply create an ExtensionAttribute class:
using System.Runtime.CompilerServices
{
public class ExtensionAttribute : Attribute{}
}
Then you need to declare this attribute on each extension method in order to implement extension methods. This is because extension methods require the new ExtensionAttribute class introduced in System.Core.dll in .NET 3.5.

Daniel Moth has talked about this in depth here.

Action Delegate on the Compact Framework 3.5

I wanted to just raise awareness of the new Action delegate available on the Compact Framework 3.5. It saves the need to explicitly create delegates then assign methods or even using anonymous delegates as in CF 2.0. This shouldn't be confused with the generic Action delegate introduced in .NET 2.0.

I mentioned the Action delegate in a session I did at Tech Ed EMEA recently and it seems not many people are using it or are aware that it even exists, hopefully this post should change that.

In the bad old days of pre .NET CF 2.0 we had to write some code like the following:
public MyClass
{
private delegate void StorageCardRemoved(string message);
private StorageCardRemoved storageCardRemoved = null;

public MyClass()
{
storageCardRemoved =
new StorageCardRemoved(ShowStorageCardRemovedNotification);
}

private void ShowStorageCardRemovedNotification(string name)
{
MessageBox.Show(name);
}

//Event handler from some worker process running somewhere.
private void DeviceManagement_StorageCardRemoved(object sender,
StorageCardChangedEventArgs args)
{
Invoke(storageCardRemoved, args.Name);
}
}
The above senario is not uncommon for device developers. We are used to writing worker threads to "listen" or just do some work on a separate thread. At some point we need to tell the user that something happend.

The above code is long and complicated. This is where the Action delegate makes this simple. Consider the above refactored to the following:
public MyClass
{
//Event handler from some worker process running somewhere.
private void DeviceManagement_StorageCardRemoved(object sender,
StorageCardChangedEventArgs args)
{
Invoke(new Action(() => MessageBox.Show(args.Name)));
}
}
How much simpler is that. The only limitation with this is that you can't call anything passing parameters. So you couldn't for example delay the message box processing by calling another delegate as you wouldn't be able to pass it the name (as in this case). This is a limitation within the Invoke method not supporting a paramerterized Action delegate. The action delegate supports upto 4 generic parameters with no returning type. This is the same functionality as per the desktop.

Of course you only need to use Invoke and Action in the above example if the event was received on a thread other than the one that owns the controls underlying window handle (UI thread).

Take another scenario that uses the Action delegate. In this example it is a situation where you have some code to be executed, but each time it is executed you want to do some other stuff first. This initial stuff might need to be specified by the caller at runtime. Consider the following code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
var businessClass =
new BusinessClass(() => Debug.WriteLine("Do initialization stuff"));
businessClass.Process(() => Debug.WriteLine("Now do business process"));
}
}
public class BusinessClass
{
public BusinessClass(Action init)
{
Init = init;
}

public Action Init
{
internal get;
set;
}

public void Process(Action action)
{
Debug.WriteLine("Now entered Process");
Init();
action();
}
}
We have a form with a button event handler hooked up to a button. When we click the button the event handler is called. When we construct the BusinessClass, we pass in the constructor an initialization Action delegate that gets executed when the Process method is called and before the Process Action delegate gets executed.

If we run this code and click the button, the output is as follows:
Now entered Process
Do initialization stuff
Now do business process
As you can see, it is quite a powerful and easy implementation. Next I'll talk about the Func delegate....

Friday, November 21, 2008

Designed for Windows Mobile 6 - Guidelines


I had a discussion recently regarding the location of the updated "Designed for Windows Mobile handbook". It can be found here, in PDF format.

I thought I'd post this for my own personal reference as well as others, as I'm always losing it, no longer! :)

Wednesday, October 29, 2008

Comprehension vs lambda queries



It's a very much debated argument like C# vs VB.NET lambda or comprehension queries (LINQ). Personally I prefer LINQ comprehension queries purely because they seem less functional and more imperative and to me they are easier to read.

C#, or VB if you prefer, support both.

Take the following simple LINQ query:
static void Main(string[] args)
{
string[] cities = { "London", "Paris", "New York" };
Console.WriteLine((from c in cities where c.Contains('L') select c).First());
}
Note we are still using extensions methods in the LINQ query. Now consider the lambda version:
static void Main(string[] args)
{
string[] cities = { "London", "Paris", "New York" };
Console.WriteLine(cities.Where(c => c.Contains("L")).First());
}
For me I prefer the LINQ version easier to read.

If we inspect the IL we will see identical generated code. First is the LINQ IL:
        
L_0023: ldsfld class [System.Core]System.Func`2 ConsoleApplication6.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_0028: brtrue.s L_003d
L_002a: ldnull
L_002b: ldftn bool ConsoleApplication6.Program::
b__0(string)
L_0031: newobj instance void [System.Core]System.Func`2::.ctor(object, native int)
L_0036: stsfld class [System.Core]System.Func`2 ConsoleApplication6.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_003b: br.s L_003d
L_003d: ldsfld class [System.Core]System.Func`2 ConsoleApplication6.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_0042: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [System.Core]System.Func`2)
L_0047: call !!0 [System.Core]System.Linq.Enumerable::First(class [mscorlib]System.Collections.Generic.IEnumerable`1)
L_004c: call void [mscorlib]System.Console::WriteLine(string)
L_0051: nop
L_0052: ret
.method private hidebysig static bool 
b__0(string c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
.maxstack 2
.locals init (
[0] bool CS$1$0000)
L_0000: ldarg.0
L_0001: ldc.i4.s 0x4c
L_0003: call bool [System.Core]System.Linq.Enumerable::Contains(class [mscorlib]System.Collections.Generic.IEnumerable`1, !!0)
L_0008: stloc.0
L_0009: br.s L_000b
L_000b: ldloc.0
L_000c: ret
}
.field private static class [System.Core]System.Func`2 CS$<>9__CachedAnonymousMethodDelegate1
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
}
Now we have the lambda IL:
L_0023: ldsfld class [System.Core]System.Func`2 ConsoleApplication6.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_0028: brtrue.s L_003d
L_002a: ldnull
L_002b: ldftn bool ConsoleApplication6.Program::
b__0(string)
L_0031: newobj instance void [System.Core]System.Func`2::.ctor(object, native int)
L_0036: stsfld class [System.Core]System.Func`2 ConsoleApplication6.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_003b: br.s L_003d
L_003d: ldsfld class [System.Core]System.Func`2 ConsoleApplication6.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_0042: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [System.Core]System.Func`2)
L_0047: call !!0 [System.Core]System.Linq.Enumerable::First(class [mscorlib]System.Collections.Generic.IEnumerable`1)
L_004c: call void [mscorlib]System.Console::WriteLine(string)
L_0051: nop
L_0052: ret
method private hidebysig static bool 
b__0(string c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
.maxstack 2
.locals init (
[0] bool CS$1$0000)
L_0000: ldarg.0
L_0001: ldstr "L"
L_0006: callvirt instance bool [mscorlib]System.String::Contains(string)
L_000b: stloc.0
L_000c: br.s L_000e
L_000e: ldloc.0
L_000f: ret
}
.field private static class [System.Core]System.Func`2 CS$<>9__CachedAnonymousMethodDelegate1
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
}
As you can see the code is almost identical. The only difference is in the calling of the Contains method. With LINQ we are calling Contains on IEnumerable whereas with lambda Contains is on the string class. You can see this in the IL b__0 method.

So it's really about personal choice.

Compact Framework v.next

As you have probably heard by now. Visual Studio 2010 and the .NET Framework v4.0 CTP was announced and released at PDC and can be downloaded here: http://www.microsoft.com/downloads/details.aspx?FamilyID=922b4655-93d0-4476-bda4-94cf5f8d4814&DisplayLang=en#filelist

If you're expecting the next version of the Compact Framework to be included in this CTP you'll be dissapointed. CF v.next didn't make this CTP.

The CTP comes as a virtual machine on Windows Server 2008 which also includes TFS CTP 2010.


Monday, October 27, 2008

Inversion of Control Pattern MSDN article

I read a very well written article this month on the Inversion of Control (separation of concerns) pattern by Jeremy Miller. I think it's worth a read here: http://msdn.microsoft.com/en-us/magazine/cc947917.aspx

Sunday, October 26, 2008

LINQPad

A new tool I learned about recently from Eric Nelson called LINQPad. It is a tool that allows you to write LINQ queries directly into its IDE then execute them.

There is support for:

-LINQ to SQL
-LINQ to Xml
-LINQ to Objects

You can of course see the results and also the SQL generated (DLINQ) - which saves you the need to troll through the SQL Profiler when performance tuning your code.

In addition the guy who wrote this tool also wrote a book called C# in a Nutshell. All the code examples in his book can be found in this tool which you can change and execute if you want. A great way to learn LINQ.

It supports VB too. There is no support for LINQ to ADO.NET (Entities) so you won't get to see the SQL generated. Other than that the LINQ will be the same.

Get it here.

Thursday, October 23, 2008

Getting Started with C#

Rob Miles has kindly published (for free) a book that he uses as a basis of the first year programming course at the University of Hull.

Get the book from here.

Sunday, October 19, 2008

The next MSDN Windows Mobile App Developer Chat

The next Windows Mobile Application Developer Chat is on November 11th 10:00 - 11:00 Pacific time.

Synopsis:
Do you have questions regarding Windows Mobile application development that you need answers to? Spend an hour with Microsoft employees and MVPs who are experts in Windows Mobile application development. Please join us for a live chat and bring on the questions! This chat will cover the tools and technologies used to develop applications using the Windows Mobile operating system.

Add this event to your calendar here.

Enter the chat here.

Why the iPhone 3G is rubbish!



Well I bought an iPhone 3G around 1 month ago so I have 1 month experience of using it so I think I have a good idea of it's capabilities.

First lets start with the positives.

The things I like about the iPhone:-

  1. Web browser. This is probably one the best parts of the device. It is usually quick and the zoom features and rendering engine are quite good.
  2. The phone. Of course a big part of the iPhone is the phone, is it any good? Yes very much probably the best phone experience I've had with any phone (although don't upgrade to v2.1 as since I've done this the phone just hangs up randomly while talking to people even though I have full signal)
  3. iPod built-in. The iPod is good. Apple doesn't have that stupid circular "wheel" to control the volume. There is a separate button for this.


The things I don't like about the iPhone:

  1. Web browser. I know I put the web browser as one of the good things about the iPhone but there is no support for Flash/Flash Lite or Silverlight and Apple (currently) don't intend to support either of these in the future.
  2. No support for forwarding SMS??!!??
  3. No support for MMS.
  4. No way to save attachments to the device via emails.
  5. No voice recording.
  6. No video recording support for the camera.
  7. Camera is only 2mp.
  8. GPS chipset sucks (even though it is SiRFIII, which is proven and works great in other devices). When you do get a satellite lock it only lasts for a couple of minutes then its gone again and I've tried this in various locations here in the UK and abroad. I have many GPS devices, phones, receivers and they all work once locked on. My older external GPS receivers maintain a lock-on while the iPhone loses it's lock.
  9. No sat nav software. Even if the GPS worked, what good is it without any kind of satellite navigation software for road users. You can use the Google maps application built-in that comes with the iPhone but it is certainly no match for software such as TomTom. In addition Google maps require the maps to be downloaded (tiles) on the fly, so if you have no radio, you lose you're way!
  10. iTunes - rubbish - I know iTunes is not part of the iPhone, but I could devote an entire blog post on its short comings
  11. Synchronization with Outlook. No support for notes. The iPhone has its own notes store, which has no relationship with outlook.
  12. It is also not possible to sync with an address book that happens to belong on exchange server in addition no support with syncing with offline emails that are part of an exchange server. However it is possible to sync with an exchange server OTA although I could never get this to work with my exchange server which is hosted with external access over HTTP.
  13. Images in emails are downloaded automatically, there is no configuration to turn this off.
  14. Long URLs are truncated in mail making them appear friendly when they might not be. The register has an article on this here: http://www.theregister.co.uk/2008/10/06/unfixed_iphone_vulns/
  15. Only a max of 200 emails can be downloaded to the device until you scroll all the way to the bottom of the list then request another block (I think something like 10 or so). So even though I have 8GB of space it is a painful task to get my entire mailbox downloaded to the phone. Rubbish.
  16. There is no search facility in the mail program. I can't even filter by date or person so finding emails is a task in itself.
  17. The accelerometer (automatic adjusting of the screen in portrait or landscape depending which way up the device is) is ok for some features of the phone such as viewing pictures but when using the iPod software for listening to music I find it very irritating as when the screen is in landscape mode you lose pretty much all the features such as controlling the volume, skipping the track etc. Turning the device back to portrait is the only solution which is minor but just irritating. There is no configuration to turn this off.
  18. Connectivity. As I travel a lot I go from areas where EDGE, 3G are not available so when I previously had a connection, maybe 3G, reconnecting via a different protocol such as GPRS in this case just doesn't work very well. Getting emails and browsing the Internet takes forever and it is quicker to turn the device off then back on again.
  19. Contacts, why can I not search by contact name???? You can tap the letter of the persons name (small A-Z listed on the right hand side of the list) and focus to navigate to that area of the list. The contacts list pretty much always locks up for a brief moment on load which is irritating. Upgrading to 2.1 doesn't fix this.
  20. Email. There are options which allow you to configure the device to poll a pop3 server periodically - which is fine the smallest unit is 15 minutes. But it just doesn't work. You have to load up mail and hit 'request mail'. And why can't I set the device to poll my pop3 server every 1 minute I have an unlimited data plan.
  21. Locking the device. What is this all about. Every time you turn the device on you have to slide this button from one side of the screen to another. This is fine, but why can't I turn it off?
  22. I know the iPhone is a touch device, but why is there no hard button for hanging up or answering. It would be good to have these hard buttons in addition to the on screen touch ones - just a minor irritation.
  23. Security hold which allows you to bypass the PIN security number and gain access to features of the phone. See here: http://blog.wired.com/gadgets/2008/08/massive-iphone.html
  24. Jason Langridge shows a comparison of push email between WM and iPhone here: http://blogs.msdn.com/jasonlan/archive/2008/07/18/iphone-2-0-windows-mobile-for-push-email.aspx
  25. No copy and paste functionality.
  26. The OS is single-task based, so coming from a multitalking desktop environment to the iPhone platform is painful.

There you have it, my comprehensive list. I have since retired the iPhone from my arsenal of devices. Maybe the iPhone will be a major player in future versions, we'll have to wait and see.

Setting the name of a Windows Mobile device programmatically

Setting the name of a Windows Mobile powered device can be achieved by manipulating the registry. Since CF 2.0 we have had the luxury of a Registry managed wrapper, so there is no need to P/Invoke the registry API.

This post shows a simple example how to read and update the name of the device - which is stored in the registry.

I've written a simple bit of code that looks like the following:
using Microsoft.Win32;
public partial class Form1 : Form
{
private const string IDENTITY = @"HKEY_LOCAL_MACHINE\Ident";
private const string NAME = "Name";
public Form1()
{
InitializeComponent();

}

private void apply_Click(object sender, EventArgs e)
{
Registry.SetValue(IDENTITY, NAME, deviceName.Text);
}

private void Form1_Load(object sender, EventArgs e)
{
deviceName.Text = (string)Registry.GetValue(IDENTITY, NAME, "NAME");
}
}
The form looks like the following:


Mobile app pre-change

This can also been seen from the Settings\System\About\Device ID applet:


Device name pre-change

Also this can be seen via the Windows CE Remote Registry Editor (CE Remote Tools):



Now we simply change the "MyDevice" to "NewDeviceName" and click the Apply button. Our change is propagated instantly if we go and check the settings applet again:



It's as simple as that!