Archive for the ‘Programming’ Category
Writing an Email client is Hard
Here’s a great Email post about how to write a proper Email client. Certain classes of software are just fundamentally difficult to do a complete job on, things you wouldn’t necessarily expect like a Textbox control or a build system. An Email client is one of these categories – even today if you discard legacy protocols and standards, you’ve still got a Mount Everest to climb. Here’s the epic mail, written by John C. Welch. Which is a shame, because at least on Windows and Mac, most of the desktop mail clients are sorely lacking in my opinion, with little hope of truly improving.
Some Quotes:
Stop thinking about IMAP as if it were some cohesive standard with a consistent implementation. It is not. It’s a bloody mess that manages to work in spite of its implementations, and Google’s IMAP implementation is one of the worst I’ve seen in the last 12 years I’ve been working with IMAP servers.
Regardless of who this project is aimed at, people using it are going to get email from “icky” sources, like Outlook users who have no control over their email format. (You think I’m kidding about this. I’m not. You should see how bizarre an overly locked-down windows shop can be.) They won’t have the option to get the sender to change format, so in addition to “normal” HTML, you should start thinking about building in TNEF decoding. In fact, if you do this well, it would be a monster point in the application’s favor, since that’s a major problem for people in the real world.
Power User != Programmer, Power User != Programmer, Power User !=
Programmer, Power User != Programmer, Power User != Programmer, Power User
!= Programmer, Power User != Programmer. There, point made.
HTML editor. Yes, I know text, blah, blah. Again, as the non-programmer power user, HTML is a reality, and it needs to be properly managed. There’s no reason to have the entire spec, but things like fonts, bold/italic/underline, alignment, real lists, and ‘real’ indents/tabs are not the work of satan. And that includes images. Welcome to the modern world, pretending it’s not there helps no one.
Using Blend Sample data at Design time and real data at Runtime
Sample Data is Awesome
Here’s a clever trick that I found out the other day – one of Blend 3’s best features is Sample Data, which allows you to generate basic data structures in Blend, create sample arrays of them, and mock up UIs so that your DataTemplates actually show something useful. This is a huge improvement over Blend 2 and VS, where important parts of your UI would basically be invisible until you actually could build the project and populate it with real data.
Keep Sample Data all the time
One thing I always struggled with though is, that you always had to switch the binding back and forth between the sample data and the real data – even though Blend has a “Only enable sample data at design time” feature, you could still only bind the data to one place. But there’s a clever hack to get around this, you can see me applying it in this Github commit.
Basically, say you had a Listbox:
<!– Sample Version
<ListBox ItemsSource="{Binding Path=Data, Source={StaticResource SampleData}}" />
–>
<listbox ItemsSource="{Binding Path=TheData}" />
</grid>
Here’s the trick – Blend doesn’t let you redirect the binding at Design time, but it will let you redirect the context. So all you have to do, is group the ItemsControl in a meaningless container, then rig the DataContext; d:DataContext is what Blend will use at Design time and will be ignored by WPF / Silverlight.
<border DataContext="{Binding Path=TheData}" d:DataContext="{Binding Path=Data, Source={StaticResource SampleData}">
<listbox ItemsSource="{Binding}" />
</border>
</grid>
Et, Voila!
Now, whenever we edit in Blend we see our sample data so we can edit the UI, then when we run it, we’ll use the live data instead.
HTML5’s Video tag already works in IE
Just add these two lines to the top of your page:
<script src="http://visitmix.com/dlr/gestaltmedia.js" type="text/javascript"></script>
Of course, this is a hack workaround that uses Silverlight to emulate the Video object, but going from “doesn’t work at all” to “make users install a plugin, once” is a pretty good deal. Here’s the original post describing it.
You can get the crash reports from Windows Error Reporting (Watson)
One of the things I see pop up on Stack Overflow all the time is, people wanting to hide or suppress the Windows Error Reporting dialog – the feature of Windows where crash reports are sent to Microsoft when your app crashes. Developers say, “MS doesn’t care about my app, what’s the point?” If they’re not so bright, they’ll write a try/catch block around their main() and hide all errors, then they’ll never find out why their apps crash in the field. Smarter developers will essentially write their own hacked-up version of WER with varying degrees of success. However, there’s a 3rd option that is superior:
Register with Microsoft, and get the WER Reports
Microsoft doesn’t just trash your reports, we will automatically aggregate them into distinct crashes (called ‘buckets’) and show you a ‘popularity contest’ of crashes – you can find out a ton of detailed information about what is happening in the field. Here’s the MSDN article detailing how to sign up. It takes a bit of leg work, but if you’re writing any sort of production-quality application, it’s 100% worth it.
But here’s what to do if you don’t believe me
Alright, so you have some super-good reason as to why you really don’t want this dialog to show up. Here’s what works on Win2k and higher (Vista has an API to do this explicitly though):
{
TerminateProcess(GetCurrentProcess(),
WhyGodWhy->ExceptionRecord->ExceptionCode);
// Never gonna get here
return EXCEPTION_EXECUTE_HANDLER;
}
int main(int, char**)
{
SetUnhandledExceptionFilter(KillSelfOnUnhandledException)
}
Expression Blend Glitches in VMWare / Parallels?
WPF hardware acceleration dies under VMWare
Just as a note since this comes up a lot from designers who use Macs and are getting into Silverlight / Expression Blend – if you are trying to use VMWare Fusion or Parallels and are coming up with weird graphics glitches or black screens while trying to use Blend, it is because WPF doesn’t get along well with these products’ graphics virtualization (I imagine because both products are focused on gaming / full-screen graphics).
WPF can be forced to run under Software-only rendering however, which clears all of these glitches up (and for Blend, doesn’t seem to have a huge impact on its usability). To do this, check out this MSDN page – you’ll need to open up the Registry Editor (regedit.exe), find the HKEY_CURRENT_USER\SOFTWARE\Microsoft key, create a new folder called Avalon.Graphics, then in that folder, create a new DWORD value called DisableHWAcceleration and set its value to 1. Close Blend and restart it, and everything should work now
A C# 3.5 pattern – the Accept Block pattern
A coworker pointed me towards this blog post as a useful trick to make code read cleaner. I’ve been using this trick in C# for quite some time, as it’s a very fundamental pattern in Ruby programming. In my head I call this the “Accept Block” pattern, but I’m fairly certain its just a syntactic version of an existing pattern (the Strategy pattern?). In some sense, it’s like being able to write your own version of the “using” or “lock” statements.
Here’s the old imperative way you might write some code:
{
SetupTheDatabase();
bool ShouldExit = SomeFunctionThatNeedsADatabase();
TeardownTheDatabase();
if (ShouldExit)
return;
DoOtherStuff();
}
And here’s how you’d rewrite it using the pattern:
{
SetupTheDatabase();
try {
block()
} finally {
TeardownTheDatabase(); // Note: Make sure this doesn’t throw!
}
}
void Foo()
{
bool ShouldExit;
WithEnsureDatabaseIsSetup(() => {
ShouldExit = SomeFunctionThatNeedsADatabase();
if (ShouldExit)
return;
});
DoOtherStuff();
}
In my opinion, the 2nd version is better to read, and more importantly, allows you to encapsulate the “setup/teardown” pattern – this way, this block of code is consistent, removes copy-paste errors from writing the same thing over and over again, and is easily updated if you want to do additional work when setting up the database.
But there’s a gotcha!
There’s a bug in the above code though that’s quite subtle, and that has bitten me a few times – the syntax () => { } is defining a closure, an anonymous function who can use variables bound inside its lexical environment (to understand the difference, take a look at that ShouldExit variable – even though it’s not a parameter of the function, we were still able to use it). When you call return, in the original example we will exit Foo() – in the new version, we will exit the closure and still execute DoOtherStuff()! Here’s how we should fix it:
{
bool ShouldExit;
WithEnsureDatabaseIsSetup(() => {
ShouldExit = SomeFunctionThatNeedsADatabase();
});
if (ShouldExit)
return; // Now we’ll return properly
DoOtherStuff();
}
Ruby doesn’t have this problem
This is a fundamental pattern in Ruby and built into the language and the runtime, so much so that it has special syntax to make it happen. However in Ruby a “block” is a slightly different syntactic structure than a function, so return will do what you expect:
an_array.each { |item| # This is a block with 1 param
print item
return if item > 2 # Actually returns from Foo, not from block
}
end
Convert a .NET 2.0 DLL to 4.0 (VS2010) without source
Converting .NET DLLs to 4.0 by hand is too much work
One of the blockers for upgrading a project to .NET 4.0 is that your old .NET 2.0/3.0/3.5 DLLs will have some difficulty running in .NET 4.0. I’m far too lazy to track down all the 3rd party DLLs like Moq or log4net, download the source, switch the project to 4.0, then recompile the DLL.
Hackery makes life easier
Instead of doing this, for a lot of DLLs, you can get away with roundtripping the DLL using ildasm/ilasm; the only tricky part is changing the assembly references so that they point to .NET 4.0 DLLs instead of the old and busted 2.0 System.* assemblies.
The good news is, I’ve written an IronRuby (or MRI, or JRuby, etc) script to handle this automagically. Here’s how to use it:
How to use:
- Download IronRuby from CodePlex (You can use the .NET 4.0 release too, doesn’t matter), and copy it to
C:\IronRuby - Download dotnet4ify_dll.rb from my website
- Launch the VS Command Prompt (2010) – don’t launch the 2008 one by accident!
set path=%path%;C:\ironruby\binmkdir v4dllsir dotnet4ify_dll.rb C:\path\to\an\old\assembly.dll .\v4dlls\assembly.dll
Some caveats
- While I’ve tested this on some pretty complex DLLs (DotNetOpenAuth, ParallelFramework_3_5.dll), it’s definitely in the “Works on My Machine” class of software; in particular, C++/CLI DLLs will probably not work. Embedded resources do still get embedded in the new binary
- .NET Assemblies get upset if you rename them, so you can’t do something like “ir dotnet4ify_dll.rb foo.dll foo_v4.dll” – just put all your v4 assemblies in a separate directory

Worked for me, but I make no guarantees it won’t replace DLLs with a lolcat
Patching Silverlight Media Framework to work with MP4/WMV files
For a project I’m working on at work, I had a need for an easy to embed video control into my Silverlight UI – previously I had been using some code hacked out of an Expression Encoder template, but it had a few bugs and didn’t look very nice. I was quite happy then, when Microsoft released the Silverlight Media Framework during PDC09. It’s got a nice UI, it’s easily themeable and embeddable, and a fairly complete player framework (supports things like timeline markers, etc).
Much to my dismay however, I discovered that it was only compatible with IIS Smooth Streaming files, not the standard MP4 files that I had been using. However, they also ship the source, so I have a chance to do some hacking and turns out, it was pretty easy to make this work properly.
index f642d2c..fadd5e6 100755
— a/Microsoft.SilverlightMediaFramework.Player/CoreSmoothStreamingMediaElement.cs
+++ b/Microsoft.SilverlightMediaFramework.Player/CoreSmoothStreamingMediaElement.cs
@@ -725,7 +725,7 @@ namespace Microsoft.SilverlightMediaFramework.Player
maxSelectedStreamBitrate = 0;
// get video stream
- var streamResult = (from stream in SelectedStreams
+ var streamResult = (from stream in SelectedStreams ?? Enumerable.Empty< StreamInfo > ()
where stream.Name == "video"
select stream).SingleOrDefault();
So, if you don’t grok what this is saying, here’s what it means – download the source, open the Microsoft.SilverlightMediaFramework.Player/CoreSmoothStreamingMediaElement.cs file, then go to line 728 or so, and replace "from stream in SelectedStreams" with "from stream in SelectedStreams ?? Enumerable.Empty<StreamInfo>()". Then, rebuild the project (remember, you have to download Microsoft.Web.Media.SmoothStreaming.dll from here before you’ll be able to build the project.
Once you have the patched SMF, you should be able to play any file by doing something like:
WPF WebBrowser blank? Check your Airspace!
WPF’s WebBrowser control (and in fact, all native controls, like the Ink controls), have a pretty subtle "gotcha" that made me spend a decent amount of time pulling my hair out. The control would render as all white like it hadn’t loaded the page, yet you can still see Tooltips from the web site as you mouse over the control! Clicking on links still works, scrollbars show up, yet the control is all white! What gives?!
My problem has to do with Airspace; WPF completely discards the concepts that Win32 and WinForms have used to handle UI rendering in the past – all controls in WPF are "Windowless controls"; there is only one HWND allocated to the entire window, whereas Win32 windows typically have many, many HWNDs allocated (one per control). It is this "impedance mismatch" that causes a lot of tricky issues, especially with keyboard/input focus. My Window had the "AllowsTransparency" bool set, so it was being created as a layered window.
The way I solved this in my app was simply to set the AllowsTransparency property of my Window to "false". I suggested that WebBrowser should throw an Exception when it encounters this situation, and the WPF team filed a bug against it for .NET 4.0 so hopefully, this specific gotcha won’t continue into the future.
One of the cool things about StackOverflow is…
…that sometimes you run into some semi-famous CS people on there.

Good thing the author of the book I forgot still remembered that he wrote it.