How I got started with computers

I, like many others, enjoy the ramblings of Scott Hanselman. Recently, Scott posted a blog on how he got started in computers and programming and I thought I'd share my own story of getting started.

Domesday

It all began in the distant past (don't worry, the story isn't as long as it sounds) when I was at primary school (elementary school for those Americans reading). We were very fortunate in the UK during the 80s; the BBC was working hard to promote computer literacy. This culminated in a number of things, most notable (at least for this story) were the BBC Domesday Project and the BBC Micro.

The Domesday Project was a partnership between the BBC, Acorn Computers and various others to mark the 900th anniversary of the original Domesday Book, an 11th century census of England. It resulted in our school library having a laserdisc that gave us an unprecedented interactive view of the country.

The BBC Micro was the computing platform that formed a part of the Domesday Project and my formative programming experience thanks to the BBC's efforts to get one in every primary school in the UK.

A Domesday system at the Vintage Computer Festival 2010, Bletchley, UK
A Domesday system at the Vintage Computer Festival 2010, Bletchley, UK

We have lift-off!

It was a year or so after the Domesday Project had visited our school library. A BBC Micro sat conspicuously in my classroom day after day. I don't remember exactly how it started, but at some point I went from playing educational games on it to writing small programs in BASIC. I suspect it had a lot to do with a very inspirational teacher I had (Mr. Garbutt, I believe). He read fascinating books to us, he played guitar to us, he had us writing and remembering poetry and eventually, he had me writing software.

It was towards the end of my final year, shortly before my leap to high school, when I created my most elaborate program yet. It was a picture of a space shuttle complete with scaffold and a car with stickman owner for scale. It even had NASA written down the side (for someone who still struggled with some geometry at age 10, I am impressed with myself for rotating those letters). The program itself was more a feat of effort than it was of programming ingenuity; it was several hundred lines of MOVE and DRAW commands. However, that effort earned me a £10 book token and a printout of the drawing and the code used to create it. The printout has since been lost, but the book I purchased has journeyed with me and sits in my bookcase at home, inside it is taped the card that had contained the prize.

The book I purchased with my prize
The book I purchased with my prize
Inscription that accompanied my book token
Inscription that accompanied my book token

The Theory of Relativity

If it were not for the support and sacrifices of my family, that may well have been that. I would have left primary school and perhaps programming, behind. However, my parents recognized my interest and bought a home computer. It was a Tatung Einstein, a little known microcomputer and it was perfect for me to while away hours at home gaming and coding (now I come to think of it, this may be how I got my start with videogames too).

I wrote a whole host of programs for my Einstein including electronic versions of "choose your own adventure" books, an electronic Beatles album and a timetable manager for me and my classmates to use for who knows what. I even remember using the Einstein for our stall at a school business fair (I seem to recall it was some sort of murder mystery thing though I don't remember for sure).

Tatung Einstein and monitor
Tatung Einstein and monitor

Friend and Family

As my Tatung Einstein started to suffer from technical problems I set my sights on something grander; a Commodore Amiga 500. My parents sold our piano to afford this computer, much to the chagrin of my sister (and probably my piano teacher, although I'd already found my lack of talent by then). Meanwhile, at school I gained access to a 286 PC and an Apple Macintosh. The former was part of my science work and often included some lunchtime visits to Sid Meier's Civilisation with a very supportive science teacher, Dr. Stec; the latter helped me to write legible schoolwork for various classes (thanks, Mr. Simpson), assist in the publication of the school newspaper and learn about e-mail for the first time.

An Amiga 500 computer system, with 1084S RGB monitor and second A1010 floppy disk drive
An Amiga 500 computer system, with 1084S RGB monitor and second A1010 floppy disk drive (© Bill Bertram 2006)

And The Rest Is History

By the time I finished high school, my career aspirations were set and I headed off to get a degree in Computer Systems Engineering leading to my job as a software engineer. Along the way, I've had the opportunity to work with some amazing people on some great projects in some diverse circumstances and I owe it all to the opportunities I was given by the BBC, my schools, my teachers and my family. I will always be grateful for their support and the sacrifices that were made so that I could follow my ambitions.

When the clipboard says, "No!"

Cut, Crash, Paste

I was recently investigating an annoying bug with my WPF DataGrid. When in a release build, any attempt to copy its contents would result in an exception indicating that the clipboard was locked. The C in Ctrl+C stood for Crash instead of Copy. This is a big usability issue. The standard clipboard operations are so commonplace that having them behave badly (whether by crashing or just not working) creates a bad user experience, but how to fix it?

Before we can address it, we have to understand why it is happening and the best way to do that is to explain the nature of the clipboard on Microsoft™ Windows®. On Windows, the clipboard is a shared resource. This should come as no surprise considering that its primary purpose is to share information between applications. Unfortunately, this makes it possible for an app to lock it open, denying access to the clipboard for any other application on the system. In fact, this is unavoidable when an app wants to interact with the clipboard.

Mitigation

Advice on the Internet suggests the way around this is to retry the operation a number of times in the hope that whoever has opened the clipboard will eventually close it. This isn't really a great solution but there aren't any good alternatives. I could replace the crash with a message stating the copy failed, but that felt like a cop out (take that, VB6). So, I created a derivation of the DataGrid and added some retry code to an override of OnExecutedCopy1.

protected override void OnExecutedCopy(
    System.Windows.Input.ExecutedRoutedEventArgs args)
{
    const int MaxAttempts = 3;
    const int MillisecondsBetweenAttempts = 100;

    int attempts = 0;
    while (attempts <= 0 && attempts > MaxAttempts)
    {
        try
        {
            base.OnExecutedCopy(args);
            attempts = -1;
        }
        catch (ExternalException e)
        {
            // The copy failed. Increment our attempt count.
            attempts++;

            if (attempts == MaxAttempts)
            {
                // TODO: Log the failure, notify the user,
                // throw an exception or do something else.
                // Whatever is appropriate to your app.
            }
            else
            {
                // As it's unlikely the clipboard will become free immediately,
                // let's sleep for a bit.
                Thread.Sleep(MillisecondsBetweenAttempts);
            }
        }
    }
}

With something in place to mitigate the issue, it was time to test it. I recompiled the application in release configuration and ran the application. The problem could no longer be reproduced. Success! Right?

Wrong. A breakpoint showed that the first copy attempt wasn't failing anymore. The bug had gone away. Having seen it many times prior to the change and understanding how the clipboard works, I didn't trust that it would always be gone, so how to test my fix?

Using the ClipboardLock, that's how.

What's the ClipboardLock?

Great question! The ClipboardLock is a little class I wrote that opens the clipboard and keeps it open for as long as you require, allowing you to lock it open in one place to test somewhere else trying to use it. I've included it below. Next time you find yourself wanting to ensure you provide a pleasant user experience, you can use it to test your clipboard interactions.

Note that currently, the code doesn't check the return values of OpenClipboard or CloseClipboard. This means that it, itself is susceptible to these calls failing. Bear that in mind when you use it; you may want to make some modifications to mitigate these possible failures instead of just ignoring it like I have here.

public class ClipboardLock : IDisposable
{
    private static class NativeMethods
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public extern static bool OpenClipboard(IntPtr hWnd);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public extern static bool CloseClipboard();
    }

    public ClipboardLock() : this(null)
    {
    }

    public ClipboardLock(IntPtr windowHandle)
    {
        NativeMethods.OpenClipboard(windowHandle);
    }

    ~ClipboardLock()
    {
        Dispose(false);
    }

    private bool disposed;
    private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            this.disposed = true;

            if (disposing)
            {
            }

            // Free up native resources here.
            NativeMethods.CloseClipboard();
        }
    }

    #region IDisposable Members

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion
}
  1. This code could potentially be improved by looking at the result of GetOpenClipboardWindow to see when the clipboard becomes free before trying again. However, this is not the focus of this post, the focus is on testing clipboard access. []

Replacing a Door Threshold

Identifying the problem

The door between our garage and house has probably been in place since the house was constructed. However, last year we discovered that the same was not true of the rubber seal between the threshold and the door. It had been glued down to make up for the low clearance between the door and our hardwood flooring and the repeated friction of using the door had taken its toll. So, we removed the seal (it was getting annoying, flapping around every time we use the door and was entirely ineffectual) and proceeded to find a suitable replacement.

During my investigation into the various types of seal available, from simple door sweeps to threshold/door combinations, I found that part of our problem was the old door threshold. It had become worn and the saddle (the part that has an adjustable height on some types of threshold) was no longer adjustable. As I'm a bit of a DIY novice, I consulted a few Internet searches, a book, my dad while he was visiting and our wonderful neighbour (a local contractor). It seemed that the door was pre-hung including the threshold, so the right thing to do was to replace the whole door. Unfortunately, replacing the door is a pricey undertaking, so I decided to try replacing the threshold. In the worst case that I messed it up, I'd just be back to the original option of replacing the door.

Removing the existing threshold

The first thing I had to do was remove the old threshold. To do this, I used a reciprocating saw and cut the threshold down the middle. This was a little more difficult than I had anticipated due to both the uneven structure of the threshold and the hardwood floor in our house, both of which would catch the saw and jar it in my hands. After some trial and error, I was able to slice the threshold almost entirely in half.

Cutting out the old threshold
Cutting out the old threshold
With the cut finished, I used a pry bar to lift the threshold and take out each half. This took some effort, lifting and pushing the threshold repeatedly to shear the remaining uncut portions. In fact, it took much more effort than I thought it would.
Prying out the old threshold
Prying out the old threshold
Halfway through removing the old threshold
Halfway through removing the old threshold
Once the whole threshold was out and I had a chance to look, it became clear exactly why it was so difficult to remove. The threshold had been attached to the door frame on each side by three screws and I had sheared two screws on each side and torn the remaining screw out of the frame.
The door frame, showing where the screws were torn out or sheared off
The door frame, showing where the screws were torn out or sheared off
Where the old threshold was attached to the door frame
Where the old threshold was attached to the door frame
The screws that sheared off or were torn from the door frame when removing the old threshold
The screws that sheared off or were torn from the door frame when removing the old threshold
I'm not sure that I could have avoided this as the door frame was overhanging the threshold, making it impossible for me to use the reciprocating saw to cut the screws. However, it's probably worth knowing should you try this yourself.

Before doing anything else, I cleaned up the edges that adjoined the threshold and swept up any remaining debris. This included getting rid of the flooring adhesive that had been used to seal the gap between the threshold and the floor.

Where the old threshold used to meet the floor
Where the old threshold used to meet the floor

Fitting the new threshold

With the old threshold removed, it was time to prepare the new threshold. I had shopped around and settled on a threshold that was mostly the same as the one I had removed except that it had a wooden saddle rather than a metal one and it was too wide for the door. I measured the width of the door frame (it seemed important) and the new threshold to determine just how much had to be trimmed.

To ensure that the saddle adjustment screws were properly positioned after trimming, I wanted to trim an equal amount from each end of the threshold and to ensure I didn't get the cuts wrong, I measured the two cut points in two ways. First, I measured from each end half the width of what was to be removed and marked it with a pencil, then I added the same amount to the door width and measured that from each end, again marking it with a pencil. Finally, with my trusty hacksaw, I made the cuts as marked.

Trimming the new threshold to fit
Trimming the new threshold to fit
Once cut to size, I placed the threshold against the door frame to check the fit.
Checking the fit of the new threshold
Checking the fit of the new threshold
Although the width was now correct, it was clear that the threshold was not going to just slip into place. After all, I had to cut the old one in half just to pull it out. In addition, the profile of the new threshold was different to that of the old one, which meant adjusting the door frame to fit.
Indicating the new threshold cross-section
Indicating the new threshold cross-section
Indicating where the door frame needs adjusting to fit the new threshold
Indicating where the door frame needs adjusting to fit the new threshold
With several ideas coming to mind that all involved potentially irreversible actions, I was a little stumped on the right way to go so I consulted my awesome neighbour, Tim. He suggested flush-cutting the door frame so that the threshold would slide right in and then screwing the threshold down. He even lent me his flush-cutter to do the job, so after marking the door frame to show where the cut needed to go, I stacked up some things to give a platform for the flush-cutter to rest on. This turned out to be my first practical use of the Borders signs I had obtained when the beloved bookstore folded last year.
Setting the height for the flush cut
Setting the height for the flush cut
Flush cutting the door frame to fit the new threshold
Flush cutting the door frame to fit the new threshold
With both sides of the frame cut and without the right tools to hand (a chisel would've helped here), I used my multipurpose paint-stripping tool to clean up the cut. It turns out that the part of the frame that needed cutting was thicker than expected so the finish was less than perfect, but it would be hidden once the job was done.
Tidying up the flush cut
Tidying up the flush cut
Checking the fit of the threshold in the freshly cut door frame
Checking the fit of the threshold in the freshly cut door frame
To finish up this stage before actually getting the threshold into place, I checked the fit against the newly cut frame by using one of the pieces I had trimmed off.

Installation

With everything trimmed to size, it was time to install the threshold. On the advice of my neighbour, I removed the saddle so that I would be able to screw the threshold down once it was in place. I also marked the saddle and the threshold to ensure there was no frustrations when putting the saddle back on.

Removing the saddle from the new threshold
Removing the saddle from the new threshold
New threshold with the saddle removed
New threshold with the saddle removed
Marking the saddle and threshold to simplify re-assembly
Marking the saddle and threshold to simplify re-assembly
With the saddle removed, I tapped the threshold into place.
Getting the new threshold into place
Getting the new threshold into place
I added a bead of caulk to seal the gap between the inside floor and the threshold and pushed the threshold all the way home.
Making sure the join between new threshold and floor is sealed
Making sure the join between new threshold and floor is sealed
Pushing the new threshold into place
Pushing the new threshold into place
It was now time for power tool number three. I drilled three pilot holes for the screws to fix the threshold in place. I also drilled countersinks to ensure the screws would be flush.
Drilling pilot holes for the screws that will secure the threshold
Drilling pilot holes for the screws that will secure the threshold
Drilling countersink to ensure the screw will be flush against the threshold
Drilling countersink to ensure the screw will be flush against the threshold
Driving the screws to secure the threshold
Driving the screws to secure the threshold
Once all three screws were in and holding the threshold in place, I reattached the saddle and adjusted its height to fit against the bottom of the door (this involved a lot of opening and closing the door).
Reattaching the saddle and adjusting the height
Reattaching the saddle and adjusting the height
The new door threshold in place
The new door threshold in place
Checking that the door closes
Checking that the door closes
To finish everything off, I caulked all of the edges.
Caulking the gaps around the new door threshold
Caulking the gaps around the new door threshold
New threshold in place and caulked
New threshold in place and caulked

Conclusion

I have learned a lot from this, had a lot of fun and saved quite a bit from not having to install a new door. When I started I wasn't entirely convinced it would work out and if I were to do it all again, I certainly might do things a little differently. That said, I am still very happy with the results and more importantly, so is my wife.

Downloading images on Windows Phone 7

I've been spending some time recently working on my very first Windows Phone application. As part of the application, I decided to use the WebBrowser control to display content. This worked well until I had image links. I had read that for them to show, they had to be in isolated storage and so did the HTML1, so I spent some time coding that and it appeared to work. However, I didn't want all the images to be a part of my app, I wanted to download them on demand and then store them for later.

I wrote some great code based on the many examples out there that use BitmapImage, HttpWebRequest or WebClient to grab the images, but to no avail. No amount of searching seemed to solve my problem. Every single time I would get a WebException telling me the resource was "Not Found". Not one Bing, Google or divining rod search got me an answer and I was near ready to give up. The Internet and my own abilities had failed me.

Just as I was about to go to bed I had an epiphany; CAPABILITIES! I quickly opened my WMAppManifest.xml and checked the information on MSDN to confirm my suspicion. I had not added the ID_CAP_NETWORKING capability which meant my app was not allowed to download data. A quick change and suddenly, everything worked.

I am amazed that not one search provided me with this answer. Every search around image problems for Windows Phone showed up incorrect advice about ClientAccessPolicy.xml (not necessary for Silverlight on Windows Phone) or terrible code examples that completely misuse disposable items and extension methods. In a future post, I'd like to expand on this topic to provide a more rounded set of samples for downloading images, but for now, I just want to get something out there that helps someone else when they discover this problem.

I highly recommend removing all capabilities from your manifest and then adding them back in as you discover which ones you need – after all, an app that wants less access is more desirable (at least for me, anyway) – however, I now realise that the act of discovering what capabilities you should have can be a bit of a pain in some circumstances.

  1. This advice is not entirely true. If you want your HTML to reference images that are in isolated storage, your HTML also needs to be loaded from isolated storage. If the images are online somewhere, your HTML can come from anywhere, just make sure you've added the ID_CAP_NETWORKING capability! []

Super Awesome Computer

Happy birthday to me!

For my birthday this year, my amazing wife arranged for my almost as equally amazing friends and family to contribute towards a copy of Pro Tools 10 so that I could get back to recording music. It is one of the best gifts ever, but there was a snag; the computer I had built back in 2005 was already feeling its age1 and definitely not up to the task. As if by brilliant parental planning 30-something years ago, our tax refund arrived shortly thereafter and redirected to the Super Awesome Computer fund.

With the budget set at $2000, I proceeded to research what I could get for my money that would result in a Super Awesome Computer for me to record music (and perhaps a few other things). The research took six hours, twice (the first time I just added things to the online cart and then left it open on the wife's MacBook, which then ended up needing a restart the following evening and lost all my selections). Besides the customer reviews on sites like TigerDirect.com and NewEgg.com, one of my primary resources was Coding Horror; in particular, Building A PC, Part VII: Rebooting. It was from this blog that I settled on the 600T case from Corsair. This case is a little bulky (so much so that it doesn't fit inside our new desk as I originally planned), but it has plenty of room inside and some nice ventilation including two 200mm fans and an open grill in the side2. I also purchased the larger 140mm fan to replace the stock 120mm as recommended by Jeff.

Things for the Super Awesome Computer
Things for the Super Awesome Computer

For the main hardware, I went with the AMD FX-8150 8-core processor. I chose AMD over Intel after quite some deliberation because I could get a little more for my budget that way. The rest of the parts I chose are:

As I intend to use the system to record music, I wanted the system to be quiet so I chose a heat sink that would help to dissipate heat without the need for high speed fans. The larger 140mm Noctua fan to replace the stock 120mm fan on the 600T case was also intended for this purpose. Having the additional cooling capacity also has the added advantage of providing me with room to overclock.

Assembly

Inside the Super Awesome Computer case
Inside the Super Awesome Computer case

Assembling the Super Awesome Computer was not an easy task, mainly due to my inability to correctly determine the order in which things should be done. I started out by mounting the PSU inside the case. This was a breeze; the PSU secured by four screws through the rear of the case and a bracket in the bottom of the case that is easily adjusted. With the PSU in place, I moved on to the motherboard. This too was a simple addition. I then replaced the stock 120mm fan with the Noctua 140mm fan before inserting the CPU and memory. Everything was going great. Then I fitted the heat sink.

Replaced the 120mm fan and mounted the motherboard and PSU
Replaced the 120mm fan and mounted the motherboard and PSU

This thing is huge and requires some adjustments to the stock brackets on the motherboard before it fits. Once those changes were made, I applied heat transfer polymer to the top of the CPU and positioned the heat sink. The heat sink itself is secured to the bracket by two spring-loaded screws (the springs ensure a tight fit against the CPU). Reaching these screws is quite fiddly and requires a long screw driver or small hands (after some cursing, I opted for the former as my budget didn't cover surgery for the latter). It was clear early on that this was going to be a tight fit, the heat sink only just clearing the memory. In fact it was so tight, that two of the memory modules have absolutely no free movement with the heat sink sat on top. However, with the heat sink in place, I attached its fans and then went to the next step: connecting things.

And then I realised my mistake. You see the CPU power connectors and the CPU fan connector are down the sides of the motherboard that become pretty much inaccessible to human hands once the giant heat sink is mounted. Having spent far too long getting the heat sink secured, I was loathe to remove it, so I stupidly opted for fiddling. It took me forever to connect the cables; time I won't get back and time that was ultimately wasted (read on to find out why). After some perseverance, I did get these cables attached and proceeded to insert the graphics card, hard drives, blu ray drive and attach all their cables and the case connections to drive the header.

Everything is in place and connected
Everything is in place and connected

At this point, everything was assembled and I was tired, sweating and bleeding a little so I went to bed. From this point on, we're short on pictures because I don't always think ahead.

It's alive!…for 20 seconds

With concern over the slightly compressed memory and a few other little things, I waited two days before applying power to the system. With some trepidation, I plugged the computer into a monitor and a power source and turned it on. Everything came to life – the motherboard lit up, the fans lit up (to my surprise) and things started to whir. It was immediately clear that the fans were too loud, but that was the least of my problems. I jumped into the BIOS and as I reviewed various settings and set the clock, the system turned off. I started it again and again, after a few seconds it turned off. Something was wrong.

My instinct told me that it was probably the processor overheating so I started it one more time and jumped through the BIOS menus quickly to get to the system health display. Sure enough, the processor temperature climbed quickly until it reached 100°C and the system shutdown. The heat sink wasn't working. Great.

I opened up the computer, removed the heat sink fans and carefully unmounted the heat sink. It was clear from the smeared heat transfer on the top of the CPU that the heat sink had made adequate contact with it, so what was wrong? Turning over the heat sink, all became clear – in my tired, eager state-of-mind I had read and promptly disregarded the label on the base of the heat sink that said something along the lines of "REMOVE THIS BEFORE MOUNTING". Realising my error, I removed the sticker and reapplied heat transfer to the CPU. Before remounting the heat sink, I checked all the cable connections that I had struggled to reach before and made sure everything was properly seated (told you I had wasted my time).

Ssshhhh

While the computer was open and its guts were accessible (and while the cats were out of the way after inspecting it for me), I decided to tackle the fan noise issue. The case comes with a fan control dial but I was reluctant to use it having used a similar system on my previous build and finding it inadequate (Jeff's comments on the case fan control also helped here). Fortunately, the Noctua fan included what appeared to be two different fan speed limiters. Having deduced what they were – these little devices are quite simple, looking like a short connector with a resistor inline on one side – I attached one to the CPU fan and one to the Noctua 140mm fan, then I booted the system3. The difference was immediately noticeable – a low-level white noise4.

I checked out the system health in the BIOS to see the system and CPU temperatures level out at a pleasing 30-35°C.

It's alive…I mean it this time!

With the hardware apparently operating correctly, I booted from my Windows 7 DVD and installed Windows to the SSD. Everything went well and before long I was updating drivers and getting on to the network to start applying updates. It was a day before I noticed that the blu ray drive had disappeared.

Some research on the Internet led me to suspect the Marvell SATA chip included on the motherboard. When putting the various drives into my system, I had decided to attach the blu ray drive to this controller while my SSD and HDD were attached to the motherboard's southbridge SATA controller. This proved to be a mistake and after various driver updates and other tinkering, I reopened the case and moved the blu ray over to one of the vacant southbridge SATA connections. A reboot later and everything was working again.

Sweet, sweet music

I have since installed my birthday gift and gleefully tinkered with the various stock instruments included. Everything is working so beautifully that I haven't had the patience or inclination to overclock the system (the Windows Experience Index is currently a pleasing 7.6). Not only that, but I came in under budget at just over $1800. I have since spent a little more on one or two other items, but they're not key to the build.

All in all, I am very pleased with my new system and I am really excited about getting to record music again. Good times await.

  1. Ahtlon XP 64-bit, 1 GB RAM, 320GB RAID 0 array []
  2. Unlike the stormtrooper variant that Jeff Atwood went with, which had a perspex panel in the side instead of the grill. []
  3. I wouldn't recommend attaching random parts to your system if you don't know what they are. []
  4. I suspect that with some eggbox foam, the noise would be barely noticeable. []