I am off

Mon, August 15, 2005, 05:12 AM under Personal
No I haven't started to smell smart-ass :-D

As previously announced here:
  • Friday 12 August - Was my last day at Trend
  • Monday 15 August - In a few hours leaving for Greece
  • Sunday 04 September - Return from Greece
  • Monday 05 September - Start at Avanade

In Thessaloniki the best I may get is a modem connection so this will be a holiday from all online activities as well.

Sometime in September you'll see my next blog post... until then have a great time without me in the blogosphere.

P.S.
Don't forget to place yourself on my brand new Guestmap! Simply left click on your location (and then optionally zoom in for accuracy).

Blog link of the week 32

Sun, August 14, 2005, 02:59 PM under Links
- Pablo points to "Solution Folders", a new feature in VS2005. (Note, it is not available with zero-impact projects so save if you want to use a Solution Folder)

- Tired of all the positive buzz on Indigo? Read this.
BTW, anyone here attending the Indigo event in Seattle? I'll be there :-)

- Even though this is not this week's news, I'll make an exception since I somehow missed it last month: Delphi for NETCF (cool!)

My MSDN article

Sat, August 13, 2005, 02:55 PM under MobileAndEmbedded
My MSDN article is now online. Check it out and, as always, let me have your comments.
(Had it been published in exactly 3 weeks time, the employer name under the author name would have been "Avanade", of course...)

Point-to-Point Message Queues with the .NET Compact Framework


Bug in Substring under netcf

Sat, August 13, 2005, 08:10 AM under MobileAndEmbedded

String s1 = "Some string";
this.Text = s1.Substring(1, s1.Length)
When you run the code under the full framework, you can see the ArgumentOutOfRangeException: "Index and length must refer to a location within the string. Parameter name: length".

When you run it under the .net compact framework v1.0 you see nothing. It is too tolerant (bug).

This is now fixed in netcf v2.0 so if you try the same code you'll get a ArgumentOutOfRangeException: "Specified argument was out of the range of valid values."

If your app took advantage of the bug it will now crash. It is for reasons like this you'd want to run your app in compatibility mode under netcf 2.0 (unless you can recompile your code under CF v2.0, of course).

However, in this case, that won't help you... until we get some msft comments, I guess it is probably a bug in the compatibility mode or maybe compatibility is only there for by-design changes and does not extend to bug fixes...

No more .NET

Fri, August 12, 2005, 01:27 AM under dotNET
Alternative title "What's in a name?"

This should be old news, but "repetition is the mother of all learning" [Greek proverb translated to English]

The ".NET" moniker is being phased out of new Microsoft products. We recall the craziness when .net was first launched: everything got a .NET after its name! Then it moved only to products that were relevant, and now it is being dropped.

The best example of this is Visual Studio. In February 2002 it was launched as "Visual Studio .NET 2002" (targeting .NET Framework v1.0). Visual Studio 6 developers, and specifically VB developers, needed to distinguish between VB6 and the new VB so it was aptly named VB.NET. In April 2003, the next version came along: Visual Studio .NET 2003 (targeting .NET Framework v1.1 & .NET Compact Framework v1.0).

There are real version numbers to go with the above (VS 7.0, VS7.1 and VB7), but everybody uses the .NET moniker (and/or the year) to refer to the products.

With Visual Studio 2005 (expected in November this year), the story changed. No more .NET after the Visual Studio name. No more .NET after Visual Basic - it is now simply VB2005 or just VB.

Another example is Windows CE. After Windows CE 3.x, came Windows CE.NET. That is WinCE versions 4.0, 4.1 and 4.2. The story here gets funnier as v4.0 does not support the .net compact framework so naming it CE.NET was a mistake (for the record, 4.1 and 4.2 do support netcf). So, last summer when Windows CE 5.0 was launched, it came as no surprise that WindowsCE had dropped the dotnet moniker as well.

If we look into the future where OS components are built with dot net code, we see that the trend of not including dotnet in the name continues, e.g: Windows Vista (Longhorn), Windows Communication Foundation (Indigo) and Windows Presentation Foundation (Avalon).

So where does all of this lead? It leaves us (the ones working on the Microsoft platform who have seen the true light) with an understanding of which product is officially named what. It leaves them (the ones who do not choose the Microsoft platform for political reasons alone, with no technical arguments) with ammunition to be able to say "We told you .NET wasn't going to last; where is it now in the latest Microsoft platform?"

So let's start changing our lexilogion and every time we are inclined to say ".NET" use the word "managed" instead. After all, that is what it is all about: Developing our apps with tools/languages that allow them to run in a managed environment.

Before anyone jumps in and says that Java also provides a managed environment, that helps my point. Make sure you realise "managed" is the way forward, and then make your choice... based on technical facts. I've made mine.

Sharing Cursor.WaitCursor and InputPanel in VS2005

Thu, August 11, 2005, 04:33 PM under MobileAndEmbedded
Most PPC apps use the SIP (see point 1 here). Now that resx files are compatible, many developers will try to share code at the windows forms level.

So rather than try to conditionally compile in or out the InputPanel do the following: in your desktop project only, simply add a file that provides stubs for the InputPanel class:
namespace Microsoft.WindowsCE.Forms {
public class InputPanel {
public event EventHandler EnabledChanged;
private bool mDummy;
public bool Enabled {
get { return mDummy; }
set { mDummy = value;}
}
}
}
Next hurdle will be changing the cursor. On the full framework, every control has a Cursor property and that is what you assign; on the compact framework, there is a single cursor which you access globally through Cursor.Current

So, add a new code file to your project (and share it in both projects) that has the following:
namespace YourNamespace {
public static class TheCursor {
public static void CursorCurrent(Control c, Cursor defaultOrWait) {
#if FULL_FRAME
if (c != null) {
c.Cursor = defaultOrWait;
}
#else
Cursor.Current = defaultOrWait;
#endif
}
}
}
Now, through a global find and replace (which I usually advocate against), replace all occurrences of:
Cursor.Current = Cursors.Default and
Cursor.Current = Cursors.WaitCursor
to
TheCursor.CursorCurrent(this, Cursors.Default) and
TheCursor.CursorCurrent(this, Cursors.WaitCursor) respectively.

If you get any compile errors it means you were assigning Cursor.Current from a method of a class that is not a control:
a) Review that design decision
b) If you stick with it, change the this to null

Now in your desktop project, wherever you were going to code the following:
someControlOrFormEtc.Current = Cursors.Default and
someControlOrFormEtc.Current = Cursors.WaitCursor
instead code:
TheCursor.CursorCurrent(someControlOrFormEtc, Cursors.Default) and
TheCursor.CursorCurrent(someControlOrFormEtc, Cursors.WaitCursor) respectively.

Not a strict subset

Thu, August 11, 2005, 10:20 AM under MobileAndEmbedded
We say that the .NET Compact Framework is a compatible subset of the full .NET Framework with few elements existing in the netcf and not the full fx.

For v1.0 I've mentioned previously and allow me to quote:
"[...] the CF is a subset of the full framework, but a closer look reveals functionality specific to the CF in the Microsoft.WindowsCE namespace (such as MessageWindow and InputPanel), the infrared classes and of course the SQL stuff is different."

MSDN has a couple more links for those compact framework unique areas here and here.

With v2.0, the CF-exclusive classes grow.

In particular, the Microsoft.WindowsCE.Forms namespace gains the following elements:
1. HardwareButton
2. MobileDevice.Hibernate
3. SystemSettings.ScreenOrientation
4. DocumentList
5. Notification
6. LogFont

NETCF 2.0 also adds the Microsoft.WindowsMobile.DirectX and .Direct3D namespace (as I mentioned here).

That's it... everything else in the compact framework is API compatible with the full framework. Happy reading :-)

Display Full Signature

Wed, August 10, 2005, 12:35 PM under Whidbey | VisualStudio
It seems the promise is delivered in the Visual Studio 2005 June CTP.

The first clue is on the Class Diagram toolbar and menu.

With Beta 2 there is a menuitem (and toolbaritem) that reads "Display Member Types" and it can be on or off - to either display the return types of methods and the types of fields/properties... or not.

With June CTP, there are 3 options as the following screenshot shows:


For a VB example of what a class on a diagram looks like when we "Display Full Signature", click here.

Before I show you a more involved C# example let me share with you a tip: Since VS2005 allows you to reference assemblies built with VS.NET 2003, even if you are not planning on moving to VS2005 any time soon
, you can visualize the publics of your assemblies with VS2005; in other words, use VS2005 just for the Class Designer so you can draw your class diagrams!

So,
1. In VS2005 add a reference to OpenNETCF.dll
2. Switch to Class View and make sure "Show Project References" is checked
3. Drill in the Project References until you reach the namespace OpenNETCF.ComponentModel
4. Now right click on it and choose View Class Diagram

There you have it. A class diagram showing the BackgroundWorker and its friends :-)

I followed the steps above in a C# project and the results, with full signatures, are here.

GenerateMember

Tue, August 9, 2005, 12:27 PM under Whidbey | VisualStudio
If you look at the form designer generated code (InitializeComponent and friends), when you add a control to your form, you'll see that the control gets created, sized, positioned etc and then finally added to the Controls collection of the form. That is all fine and necessary, what is not always necessary is having a form level field that points to the control. It is an extra 4 bytes per member and more importantly clutters the code and intellisense (and any diagrams you auto generate).

In this area, there is a small enhancement that I loved when I first saw Whidbey and I don't think it has had enough coverage, so here goes.

In Visual Studio 2005, when having a form open, you can select a control and toggle a new boolean property from the properties window (under the Design category): Generate Member. As the documentation says, it "Indicates if a member variable will be generated for this component."

So for all those projects you have upgraded, go though the controls on your forms and check to see if you are accessing the control variable outside InitializeComponent; if you are not set GenerateMember to false. For new projects make sure you remember to make that decision every time you add a control to your form; e.g. most Label instances never get accessed after you set their Text in the designer.

Note that this is not a true property, i.e. you don't get programmatic access to it of the Control class. It is simply a design-time thing done via an extender no doubt.

Show numeric SIP for WinCE devices

Mon, August 8, 2005, 12:25 PM under MobileAndEmbedded
Everybody knows that to show the Soft Input Panel on a WindowsCE device you have to use the Microsoft.WindowsCE.InputPanel (set the Enabled property to true/false to show/hide).

A common request, to which there is no clean answer, is to show the SIP in numeric mode or not so the user doesn't have to do it.

However, Alex Feinman has a great hack that provides just that; it checks for the color of the "123" button and sends a windows message depending on if it is black or white (pressed or not). Go download it here.

If you are targeting PocketPCs then use it and that is the end of the story, see you next time.

If you are targeting custom Windows CE devices, you need to make a few small changes (on our platform we are using the small keyboard with the "Large Keys"):
1. The calls to GetPixel/SetPixel take the X,Y coordinates which are hard coded to 2,2. Change the Y to be 77.
2. Change the last parameter in the two calls to Message.Create to be: new IntPtr(0x00490009).
3. Change the condition so it caters for showing a numeric sip in non-numeric mode.

I've wrapped the changes in an InputPanelEx class:
a) In your projects replace all occurrences of InputPanel to InputPanelEx.
b) Wherever you have inputPanel1.Enabled = true, add another line inputPanel1.Show(true) [if you want to show numeric SIP].

Blog link of the week 31

Sun, August 7, 2005, 03:50 PM under Links
If she writes a book, I'll be the first one to buy it. This week: Application.DoEvents is *not* OK (don't say I didn't tell you)

GeneratedCodeAttribute. I say... finally!

Arguing over details... my kind of arguing :-)

ProjectProperties->Signing vs AssemblyInfo

Sat, August 6, 2005, 05:54 AM under Whidbey | VisualStudio
This has been on my "to blog" list but, since someone else beat me to it, please go read: Visual Studio 2005 and Signing with strong name keys.

Why is there a warning against using the old way of signing in the AssemblyInfo.cs? When sharing code between Smart Device and desktop projects, we used to share the AssemblyInfo file. Now, to strong name both projects/assemblies, I need to do it via two different project properties dialogs rather than a single code file!
Note that VB projects seem more tolerant to using the AssemblyInfo.vb for this purpose.

In addition, there is another bug with Beta 2. Say you created a desktop project and added the strong name (resulting in the silly copying of the snk file to your project folder). Now you create a Smart Device project in the same folder and using *its* project properties try to add the snk file from its original location: VS2005 dies a horrible death! The workaround is to browse to the snk file that was copied in your project folder.

Project properties nuisance

Fri, August 5, 2005, 12:54 PM under Whidbey | VisualStudio
Nobody likes modal dialogs, but the Visual Studio.NET 2003 properties dialog is *not* modal.

Nevertheless, we prefer docked windows (apparently), so in Visual Studio 2005 the properties window is "inlined" in the main area as if it were a code file.

With this change we lost a great usability feature. Easiest way to describe this is an example:
1. Open a VS2003 solution with more than 1 project (e.g. 3 or 10)
2. Collapse them all [btw, when are we going to get a "Collapse all" in VS?!]
3. Select a project and choose Project Properties to show the popup window
4. Select "Common Properties" -> "References Path"
5. Change the value(s) (or verify it is what you want)
6. Without closing the dialog, select another project in the solution
7. See how the “project properties” updates for that project?
8. Go back to step 4 and select some other section of the Properties dialog
9. In solution explorer, use the keyboard up/down keys to quickly verify that a setting is the same for all projects

I use the above all the time (e.g. to quickly toggle Debug/Release constants, change default namespace etc). When you change project selection, if you have made changes, you get the prompt to save or discard changes (which is nice).

So how can I achieve the same with VS2005? That wasn't a rhetorical question... please tell me!

For all projects in a VS2005 solution, try to change the output path from bin\Debug to bin\DebugCF. Count the number of clicks/mouse movements and do the same for VS2003 in no time.

How irritating when a great product takes a step backwards...

...or maybe I should get out more ;)

How to upgrade VS2003 projects to VS2005

Thu, August 4, 2005, 01:04 PM under Whidbey | VisualStudio
If in Visual Studio 2005 you try to open a project created with Visual Studio .NET 2003, the conversion wizard appears. Apart from the option to backup the existing solution, there isn't much more to it other than clicking the "Finish" button. It basically takes the project file (which is v7.1 or v7.0) and converts it to VS2005 (v8.0); all code files (.vb or .cs) remain untouched.

When you install VS2005 you can quickly tell in your file explorer which solutions were created with which version of Visual Studio, check out this screenshot.

Note that if you double click on a 7.x *project* file in explorer, you will be presented with the upgrade wizard in VS2005, whereas doing the same for a 7.x *solution* file, correctly opens it in VS.NET 2003.

So I was upgrading some VB device projects with Beta 2 and noted a few subtle differences between the *upgraded* VS2005 projects and *new from scratch* VS2005 projects of the same type. The differences are easier observed by opening the project files in notepad (or an XML editor) and comparing them (you know of course about MSBuild).

For example, the upgraded project has a bunch of empty tags (which are not needed): ApplicationIcon, AssemblyKeyContainerName, AssemblyOriginatorKeyFile, AssemblyOriginatorKeyMode, StartupObject and PreBuildEvent/PostBuildEvent under PropertyGroup under FileUpgradeFlags. It also has a bunch of tags with default values (whereas new projects omit them) or tags that don't apply to NETCF projects: DelaySign, OptionCompare, OptionExplicit, OptionStrict, RegisterForComInterop, RemoveIntegerChecks, TreatWarningsAsErrors, WarningLevel and Name/Private under Reference Include under ItemGroup.

Newly created projects will have the new properties structure I described previously here. You can observe this in the new files in the text editor with tags such as: AutoGen/DesignTimeDependentUpon under Compile Include for Resources.Designer file. Also for tags such as: Generator/LastGenOutput/CustomToolNamespace under EmbeddedResource Include for Resources.resx file.

Sooo...

If you still wish to go down the upgrade wizard path for your VB device projects, here are my recommendations for your project properties window:
1. Select Option Strict On
2. Select “Error” as the Notification for all Conditions except "Use of variable prior to assignment"
3. Check "Treat all warnings as errors"
4. Check "Generate XML documentation file"
5. Go to "Advanced Compile Options". On the "Generate debug info" combo, select "Full" (at least for a debug configuration) DebugType
6. Go to references and remove unused ones (Unused References->Remove)
7. Uncheck assembly COM-Visible [unless you explicitly want it to be visible]
8. If you want AssemblyInfo in its own folder, create one in the project and move it there.

Alternatively, if you want clean projects following the new style:
a) Create a brand new project in VS2005 (of the same type as the one you will upgrade)
b) Delete the default code file (e.g. Form1 or Class1 etc)
c) Copy attributes from the old AssemblyInfo file to the new one as appropriate
d) Copy settings from the old project properties to the new one as appropriate
e) Add references to the new project to match the old ones
f) Deal with resx files as discussed here

Finally, and continuing from my last point above, it makes sense that you upgrade your projects (one way or the other) bottom up. In other words, start with your class library that references nothing but framework assemblies and work the projects up to your Application (the exe). Note that VS2005 will allow you to reference assemblies built against v1 of the framework! So be sure you are referencing *upgraded* dlls and not the original/old ones.

AssemblyInfo 1.0.* -> 1.0.0.0

Wed, August 3, 2005, 09:24 AM under Whidbey | VisualStudio
In VS2005 the version number does not default to "1.0.*" like it does with VS.NET 2003. Instead it starts off with more sensible "1.0.0.0". You can check this for yourself by examining the AssemblyInfo file (or through the project properties and the "Assembly Information" button).

However, I would prefer a checkbox on the dialog (or a wildcard character in the file) that would result in auto-incrementing the revision part of the version. This is exactly what VS2005 offers for ClickOnce application and you can see that for yourselves by navigating to the "Publish" of the project properties dialog ("Automatically increment revision with each publish").

To be perfectly honest, what I would really like is to pass to the AssemblyVersion attribute the following parameter "1.0.*.0". I would then expect the build part of the version number to increment by one every day as it does now, to indicate the number of days since January 1st 2000. Alas, we cannot add anything after the *... maybe in Orcas!

Another use of partial types

Tue, August 2, 2005, 04:03 PM under Whidbey | VisualStudio
We've looked at partial types before but what use are they?

Their primary use is for code generation tools. The main/best example is the windows forms designer which uses them for splitting the designer code from the code we (the developers) write. I think that code generation will play an even larger part in every day development as years go by but that is another story...

Another use could be to split a class in privates and publics. So one file has all the (private) fields and private methods while the other has all the members that are externally callable.

You can take the previous idea too far and have a file per member category i.e. one for fields, one for methods, one for properties and one for events (or even another for internal types such as structs/classes/delegates).

If a class implements an interface (or many), why not split the interface implementation into its own file...

Some might even split a class into files according to the areas that different developers are working on (thus assisting with source control check ins/outs).

Finally, if you find yourself declaring your own code regions in VS.NET 2003, consider whether you can extract them into their own file using partial classes.

I am not advocating any of the above but I am not being a purist against it either. For the record, I do believe that classes should be controlled from growing too large; objects should be designed to do one thing only and do it well.

Recently I discovered another reason. A few years back, when I migrated a whole bunch of dotnet code to the compact framework, I came across types that while designed to do one thing only, they had a fatter interface than what appropriate for an embedded platform (and some of their members were simply not applicable to windows ce). There were a number of approaches I took depending on the situation:
1. "Carry" the extra class members but not call them
2. Conditionally compile parts of the class for the NETCF (or vice versa)
3. From a single class, extract a base abstract class and two specialisations (each in their own file). In the Smart Device Project I only use two files out of the three (the base class and only the one subclass that is applicable).

It is obvious where this is going, isn't it? :-)

A 4th option with Visual Studio 2005 is to use partial classes and thus exclude the files you don't want from one of the projects. One more support option for sharing projects between the two platforms.

Resx compatibility for Smart Device projects

Mon, August 1, 2005, 04:05 PM under MobileAndEmbedded
The punchline is that with VS2005 there is no more incompatibility for resource files (resx) between the compact and full frameworks!

To quote from my post on writing cross-platform code with VS.NET 2003:
"Trying to share the form code would effectively mean not using the designer at all."

This statement is no longer true with VS2005. You can follow the steps for sharing code files (as described in that blog entry) for forms as well. You may still prefer not to share forms between the two platforms but at least it will be technically possible now.

A side effect is that we no longer need cfresgen (as previously mentioned here) and instead we can use resgen (for both platforms).

Another side effect of this improvement is that existing resx files you have that work in your cf v1.0 projects, cannot be added to VS2005 projects. They have to go through the upgrade wizard. So although you have been told that the VS2005 upgrade wizard only affects solution and project files and nothing else, now you know that it also affects resx files; even though the (Beta 2) conversion report does not indicate that!

Overall, good stuff from the VSD team (and in this particular case, Xin Yan).