96 DPI

Illustration

Probably every programmer on this world has his image collection to use in toolbars. It is usually collected over years and gets reused quite a lot. I have collection of my own and it seemed like a natural solution to use it in WPF also.

As I am big fan of high DPI setting and I got used to expect little bit of blurriness in my toolbar as unfortunate result of scaling bitmap from 16x16 (at 96 DPI) to 20x20 (at 120 DPI). However, nothing could prepare me for amount of blur that WPF brought.

Quick search discovered a clue and look on my system confirmed it. Almost all images I had were 72 DPI. That meant WPF did scaling even on systems with “normal” DPI settings.

Scott gave easy fix in form of PNGOUT tool. I tried it out and checked results in Paint.NET. Unfortunately, instead of promised 96 DPI, I got 120 DPI images. Issue here is that PNGOUT uses DPI settings as defined on system. High-DPI setting on my system meant that PNGOUT will not work correctly without configuration change (and required logoff/logon).

Quite annoyed I made quick program in C# that just loads whatever image you give it on command line (e.g. “dpi96.exe *.png”) and changes it’s DPI setting. This finally worked as promised. This small utility is available for your use also.

P.S. Yes, I know that I should prepare separate bitmaps for all common DPI settings. I am lazy and artistically-challenged.

P.P.S. This utility was made in less than 10 minutes. Do not expect extra-quality code (or any exception handling).

Bing Maps - Presentation Done

Illustration

Another presentation is now done. I do hope that everything went fine and that everybody present had much fun.

This one was about Bing Maps and you can download all materials here.

For everything to work you’ll need GPS device that supports Windows 7 API. In absence of it you can GPSDirect NMEA Sensor Driver with any GPS that has serial port support (either physical or virtual).

If you preffer working inside, you’ll need emulator. Unfortunately there is no official support for any so you are on your own here. I used both Geosense and GPSDirect NMEA Sensor Driver (simulation mode). While Geosense will give you sensible result, location will not change. GPSDirect will update “your location” but simulation mode is based on random numbers instead of file input. That means that Murphy will locate you somewhere near either south or north pole.

Do not forget to put your Bing Maps user ID and password in App.xaml.cs since I cannot share mine. If you do not have developer account, you will need to get one.

This example uses Bing Maps staging environment and thus you must use token service. Non-staging service can use keys and that is definitely better solution than having your user name and password available in program. Bad side is that access to it counts against your daily limits (1000 request).

P.S. It seems that every time during presentation I forget that NMEA stands for National Marine Electronics Association and not, as I probably said, “Nautical something”. :)

VHD Attach 1.60

Illustration

Since first version of VHD Attach there were requests for auto-mounting of drives upon startup. With this version that feature is finally available. :)

Other change that some will like is possibility to enable/disable context menu items for explorer. Now you can choose whether you want all items there, some of them or none.

Download is available here.

The Devil Is In The Details

In quite few programs I see following pattern:

void OnMyEvent(EventArgs e) {
    if (this.MyEvent != null) {
        this.MyEvent(this, e);
    }
}

I must confess that I use same pattern in quite a few pieces of my own code. Nevertheless, this is wrong.

Issue here is that MyEvent can change between check and call statements. If change consists of adding one more delegate everything is fine. If change is removing all existing delegates you are in trouble.

Here is scenario. First line will check whether MyEvent is different than null (which it is at that point in time) and, exactly at that time, control switches to another thread and makes MyEvent null. Once our thread resumes it will use MyEvent which is now null. Exception!

This issue is highly timing sensitive and it is near impossible to reproduce it. You may have that bug for couple of years and never hit it. But it is there.

There are two distinct paths to remove this problem. One is just putting everything into lock statement. This will fix issue but it will also introduce overhead, performance problems and even potential deadlocks. It all depends on what exactly is done in called method. It is not a pattern I would be comfortable with.

Another path is to exploit fact that event delegates are immutable. Every instance has all data needed and if you copy it to local variable there is no need to worry about it changing value. With simple change we now have correct code:

void OnMyEvent(EventArgs e) {
    var ev = this.MyEvent;
    if (ev != null) {
        ev(this, e);
    }
}

10-4

Illustration

Visual Studio 2010 is here!

MSDN subscribers can start download immediately while others will need to wait a little.

As soon as I download it, fate of Visual Studio 2008 is sealed. So long, and thanks for all the fish.

[2010-04-12: Express editions are available for download now.

[2010-04-12: Trial version of full Visual Studio is also available .

[2010-04-12: Unfortunately there is no Ribbon control for managed code. Big disappointment for me.