Tuesday, April 24, 2007

Recruiters - how about reading my CV?

I'm not looking for a job currently but my CV must be out there somewhere on the internet from the last time I was looking for work. And it's pretty clear quite a few recruiters just do a keyword search and send out emails without actually ever reading my CV. So I've had emails about C++ positions, which I haven't touched for almost 10 years, PHP jobs, which I'm familar with but wouldn't consider a strong point, testing jobs and even jobs in the US.

Maybe the 'throw enough shit at the wall and some of it will stick' technique works but I suspect it's not highly effective. I tend to remember the recruiters who actually bother to ring me up and actually listen to what I have to say and if I ever need to contact a recruiter again I'll go to them first, since they appear to care about placing people in the right job. The others are simply helping to confirm the bad reputation that recruiters have.

Monday, April 23, 2007

The ZX Spectrum is 25 years old

And how old does that make me feel?* Get an emulator and download some great games at World of Spectrum, read more about the mad genius Clive Sinclair at Wikipedia.

* Short answer - very

Friday, April 20, 2007

How to solve virtually any technical problem

People ask me technical questions all the time. I have no idea why, I don't know any more than anyone, perhaps the fact I can find the answer to these problems leads people to think I actually know the answer. So I'm going to present to you the two steps to find the solution to almost any technical problem.

Google for it - The internet holds the answer to pretty much any question you can ask. The key to finding the answer is to know how to search. This is pretty much trial and error, if one search doesn't bring up the answer, try another phrase until you get something that looks related. If you're getting a specific error message, search for that.

Another point to make here is that if you can't find what you're looking for, consider whether what you're trying to do is a good thing to be doing. I remember trying to find information about hosting .NET WinForms controls in Internet Explorer and not having much luck at all. This was a big red warning light to me that perhaps even attempting to do this kind of work was a bad idea since it would appear very few other people were doing it.

Infinite monkeys - You know the saying, given an infinite number of monkeys with an infinite number of typewriters and infinite time, one of them will produce the works of Shakespeare. So it is with fixing technical problems. Try enough things and one of them will be the right answer. The key to this technique is only to make one change at once, otherwise one of your changes may fix the problem and your other change might break it again. Or you forget one of the changes you made and don't set it back to what it was before and you're in an even worse position.

So now I've given you the tools, you don't need to bother me anymore, OK? 

Tuesday, April 17, 2007

Buy less crap

The idea touted by Red that somehow we can help charities by buying more stuff is frankly preposterous. The idea put forward by Buy (Less) Crap is to not purchase more consumer tat and donate the money we would have spent to charity instead. Now that seems much more sensible. How many fecking iPods do we need anyway?

Monday, April 16, 2007

Doogal's guide to parenting

You can read every book by Gina Ford you want but from my vast experience (ahem) there are only two things you need to master when bringing up a child.

Bribery and blackmail. 

Friday, April 13, 2007

No really, total rewrites don't make sense

I just found this fairly old blog post about rewriting Delphi apps in C# which sits so well with how I think (and puts the point across far more eloquently than I could ever do) that I had to post the link.

The bottom line is if you have an old code base to maintain, rewriting it completely may seem like an attractive option, but there are other ways of getting to the same place without throwing away years of investment in that old code base.

Wednesday, April 11, 2007

Swimming to New York

I'm not the first person to point out the humorous suggestion from Google Maps when you ask for directions from the UK to the US (see step 36), but it got me thinking.

One of the shortcomings of Google Maps is that it has no knowledge of anything but driving so it won't advise me to jump on a plane if I want to get to the US. For that matter if I ask it how to get to London Waterloo from my house, it doesn't know anything about trains so again will tell me how to drive there. It doesn't know anything about congestion charging or parking charges either so doesn't realise only the super rich or super stupid would ever consider driving into central London.

Transport for London has the opposite problem because it completely ignores the driving option, which in some circumstances might make sense (try taking public transport from SW London to SE London without dying of old age on the way for instance).

A while ago I wanted to investigate transport options for getting to my dad's house in Spain. Here things get even more complicated. There are loads of different websites with information about planes, trains and ferries but I had to find them and then compare prices, times etc.

But none of this stuff is properly integrated. The data is mostly available so it just requires an uber geek to figure how to build a mashup site that takes data from all these different sites and pulls it together in one place. I need to be able to enter a start location, an end location and then be able to get results sorted on which is cheapest or fastest or most environmentally friendly and lets me buy all the required tickets. Presumably if somebody did make such a thing, they could probably finance it by getting commission on the bookings.

And another thought, my guess is one of the reasons people who may be concerned about the environment still take flights rather than taking the overland option is that it is so much easier to book a flight than to book the alternative train and ferry. Oh, and cheaper... Er, and quicker... But at least this site could remove one obstacle.

So, any takers?

Tuesday, April 10, 2007

Maintainable XSLT

Doing a search on Google for 'maintainable XSLT' doesn't throw up a great deal but it seems like something that is really needed. There seem to be lots of resources out there telling me how to code in XSLT, but I haven't found any telling me how to do it elegantly or testably (is that even a word?). I've been working on and off on a project that takes an XML file and spits out a HTML representation of it. When I started off I decided to go with XSLT, rather than generating the output in C# using an XmlWriter. I still think that was the right decision. Even though XSLT is pretty verbose, generating HTML any other way isn't too concise or pretty either.

It's not a big XSLT file by any means (about 1500 lines), but I'm already finding it hard to manage and the tool support just isn't there. Visual Studio 2005 is a step up from 2003, but there are still plenty of things missing. There doesn't seem to be a way to get an overview of an XSLT file by showing what templates are in it. This means some of the possible advantages of splitting it out into separate templates are lost. But even if I was to split it out into separate templates, the markup required to call a template means the XSLT file might actually get bigger due to the calls to the templates!

Another thing I'd like to see is the ability to go to the definition of a template from a call-template call, but that doesn't seem to be available. How about regions, like in C#? OK, I want all the features of the C# editor in XSLT, am I barking up the wrong tree? XSLT is fairly different to C# and I'm coming at this with the mindset of a C# programmer but are there different ways of handling this complexity? Where should I be looking for this information?

Wednesday, April 04, 2007

Method calls on value types and boxing

It was DevWeek 2005 and I was in a session with Jeff Richter about low level .NET things and I foolishly asked him a question. He looked at me as if I had asked the most dumb question ever asked by anyone, so I decided not to follow up on my question, even though I didn't feel he'd really given me the answer I was looking for.

So what was the question? Well he was describing boxing of value types and how it can cause performance problems so it was best to avoid it where possible, even though it's not always clear when boxing is occurring. I'd asked didn't boxing need to occur for any method call on a value type. On reflection I'm not sure this was a particularly dumb question but I've never really got fully to the bottom of it, mainly because it's never really been much of an issue to me. But here's my take on it, which may or may not be accurate. Boxing is only going to happen if the method call is a virtual method where the value type doesn't override the base object implementation. Now it might be boxing would also be required if the value type did override the base method (assuming boxing is required to get the virtual method table), if value types could be inherited from. But they can't so the discussion is kind of irrelevant. This may well be why value types can't be inherited from, but this is all frankly getting way too complicated for me to understand, so I'll quickly move on.

Anyway to illustrate the point, here's a little test C# application.

namespace ConsoleApplication2
{
  struct ValTypeTest
  {
    int val;

    public ValTypeTest(int val)
    {
      this.val=val;
    }

    public override string ToString()
    {
      return val.ToString();
    }
  }

  class Class1
  {
    [STAThread]
    static void Main(string[] args)
    {
      ValTypeTest thing = new ValTypeTest(34);
      Console.WriteLine(thing.ToString());
      Console.WriteLine(thing.GetHashCode());

      int number = 34;
      Console.WriteLine(number.ToString());
      Console.WriteLine(number.GetHashCode());

      Console.ReadLine();
    }
  }
}

If you look at the IL code for this in Reflector using .NET 1.1 (I'll explain why I'm using .NET 1.1 shortly), you'll see this -

.method private hidebysig static void Main(string[] args) cil managed
{
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
    .entrypoint
    .maxstack 2
    .locals init (
        [0] valuetype ConsoleApplication2.ValTypeTest thing,
        [1] int32 number)
    L_0000: ldloca.s thing
    L_0002: ldc.i4.s 0x22
    L_0004: call instance void ConsoleApplication2.ValTypeTest::.ctor(int32)
    L_0009: ldloca.s thing
    L_000b: call instance string ConsoleApplication2.ValTypeTest::ToString()
    L_0010: call void [mscorlib]System.Console::WriteLine(string)
    L_0015: ldloc.0 
    L_0016: box ConsoleApplication2.ValTypeTest
    L_001b: callvirt instance int32 [mscorlib]System.ValueType::GetHashCode()
    L_0020: call void [mscorlib]System.Console::WriteLine(int32)
    L_0025: ldc.i4.s 0x22
    L_0027: stloc.1 
    L_0028: ldloca.s number
    L_002a: call instance string [mscorlib]System.Int32::ToString()
    L_002f: call void [mscorlib]System.Console::WriteLine(string)
    L_0034: ldloca.s number
    L_0036: call instance int32 [mscorlib]System.Int32::GetHashCode()
    L_003b: call void [mscorlib]System.Console::WriteLine(int32)
    L_0040: call string [mscorlib]System.Console::ReadLine()
    L_0045: pop 
    L_0046: ret 
}

As you can see, the call to GetHashCode causes the value type to be boxed, whereas the call to ToString doesn't, because ToString has been overridden whereas GetHashCode hasn't been. But if we look at the IL code in .NET 2, it looks like this

.method private hidebysig static void Main(string[] args) cil managed
{
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
    .entrypoint
    .maxstack 2
    .locals init (
        [0] valuetype ConsoleApplication2.ValTypeTest thing,
        [1] int32 number)
    L_0000: nop 
    L_0001: ldloca.s thing
    L_0003: ldc.i4.s 0x22
    L_0005: call instance void ConsoleApplication2.ValTypeTest::.ctor(int32)
    L_000a: nop 
    L_000b: ldloca.s thing
    L_000d: constrained ConsoleApplication2.ValTypeTest
    L_0013: callvirt instance string [mscorlib]System.Object::ToString()
    L_0018: call void [mscorlib]System.Console::WriteLine(string)
    L_001d: nop 
    L_001e: ldloca.s thing
    L_0020: constrained ConsoleApplication2.ValTypeTest
    L_0026: callvirt instance int32 [mscorlib]System.Object::GetHashCode()
    L_002b: call void [mscorlib]System.Console::WriteLine(int32)
    L_0030: nop 
    L_0031: ldc.i4.s 0x22
    L_0033: stloc.1 
    L_0034: ldloca.s number
    L_0036: call instance string [mscorlib]System.Int32::ToString()
    L_003b: call void [mscorlib]System.Console::WriteLine(string)
    L_0040: nop 
    L_0041: ldloca.s number
    L_0043: call instance int32 [mscorlib]System.Int32::GetHashCode()
    L_0048: call void [mscorlib]System.Console::WriteLine(int32)
    L_004d: nop 
    L_004e: call string [mscorlib]System.Console::ReadLine()
    L_0053: pop 
    L_0054: ret 
}

Now it's no longer clear whether boxing occurs or not, because both calls use the IL constrained opcode. It would appear this opcode has been added for a variety of reasons, but one of them is to help with binary compatibility, so if a value type changes so it adds an override for a virtual method or removes an override, it will still work without any changes to the calling app. The downside of this is that boxing is even more hard to spot than it was before.

Saying that, worrying about boxing is often not really worth the trouble. It smells of premature optimization and in most cases isn't likely to cause problems. Saying that, it does suggest if you're writing your own value types, you're probably going to want to override most of object's base methods, particularly GetHashCode, which is used in quite a lot of places.

Tuesday, April 03, 2007

The number one internet resource for Metastorm crap

It's always interesting to look through the search terms that have led people here or to the other sites I have something to do with. It's certainly a great work avoidance tactic. So I was pleased to see that the term Metastorm crap had landed somebody here. Then when I did a search for Metastorm crap myself I was even more pleased to see I'm number one for that search term. So there you are, come here for all the Metastorm crap you could ever need...

In fact I've just done a search for Metastorm shit and I'm number one for that as well! I must point out at this point that although the words may have appeared on the same page, they didn't actually appear in the same context... OK, they do now, but I'm not implying anything, OK?

Saturday, March 31, 2007

Some useful web resources

I came across a couple of useful websites today which I thought I'd post here for others and for my own information.

First is Domain Tools, which provides the usual Who Is lookup and a whole lot more. Most useful I thought was the SEO text browser that shows how a website looks to a search engine and gives a few pointers to how your pages could be improved for SEO.

That site led me to About Us, that is an interesting attempt at generating a Wiki for websites. I imagine this could become an interesting site to browse and find new sites to visit. If nothing else, adding your site will add another inbound link to your site.

Another useful resource that I didn't find today but follows on from the SEO text browser above is the HTML Validator provided by the W3C. Running your site through this will show any problems with your HTML code. I've no idea if valid HTML will improve your search rankings but I'm fairly certain it won't hinder them.

Friday, March 30, 2007

The evil #if DEBUG

I recently received a bug report for an ASP.NET site I've been maintaining but when I went off to test out the problem running the site through Visual Studio everything worked fine. Slightly confused, I went back to the live site and immediately reproduced the problem. So I thought the problem must be caused by the site not being in sync with the the development box so I uploaded the latest code. The problem was still occurring... I was fairly unfamiliar with the code so I started stepping through it. You've no doubt guessed the problem by now from the title of this post. There was some code wrapped in an #if DEBUG directive that actually overrode the parameters passed into the page via a query string. I removed that and the problem on the live site was reproducible in Visual Studio. But I wasted an hour or so getting to the bottom of it.

So the moral of the story is don't change behaviour of your code with #if DEBUG statements. The only use I've found for #if DEBUG is to log things, and generally that can be avoided through the use of the trace listener infrastructure. 

Monday, March 26, 2007

Not everything is high priority

If every email you send to me is marked as high priority, they tend to lose their impact, I assume none of them are important. What will you do when you really do want to send me a high priority email? There is no priority zero...

I presume you're familiar with the boy who cried wolf?

Saturday, March 24, 2007

Meaningful descriptions for enums

Getting a string representation of an enum is pretty simple, just call ToString() on the enum. However, we often want to have a more user-friendly string to display to the user, that includes spaces and the like. I guess one way of achieving this would be to override ToString on our enum class, except you can't override ToString in an enum... And how to go the other way, from the string representation to the enum? The solution set out below uses an EnumDescription attribute that can be applied to the values of an enum. Now I can't claim to have come up with the idea for this, I think I first saw it on Richard Blewett's blog, but his archive doesn't seem to go back as far as it should. Saying that, I've also made quite a few alterations so I can claim some of this code as my own. The use of generics means it will only work with .NET 2.

using System;
using System.Reflection;

namespace Utils
{
  /// <summary>
  /// Attribute used to give textual descriptions to enums.
  /// </summary>
  [AttributeUsage(AttributeTargets.Field)]
  public sealed class EnumDescriptionAttribute : Attribute
  {
    /// <summary>
    /// Creates a new <see cref="EnumDescriptionAttribute"/> instance.
    /// </summary>
    /// <param name="text">Text.</param>
    public EnumDescriptionAttribute(string text)
    {
      this.text = text;
    }

    private string text;
    /// <summary>
    /// Gets the text description.
    /// </summary>
    public string Text
    {
      get
      {
        return text;
      }
    }
  }

  /// <summary>
  /// Helper class to get descriptions of enums.
  /// </summary>
  public sealed class EnumDescription
  {
    private EnumDescription()
    {
    }

    /// <summary>
    /// Gets the description of the specified enum. If there is no description attribute, returns the 
    /// enum as a string
    /// </summary>
    /// <param name="e">The enum to get the description of.</param>
    public static string GetDescription(Enum e)
    {
      string ret = e.ToString();
      Type t = e.GetType();
      MemberInfo[] members = t.GetMember(ret);
      if (members != null && members.Length == 1)
      {
        object[] attrs = members[0].GetCustomAttributes(typeof(EnumDescriptionAttribute), false);
        if (attrs.Length == 1)
        {
          ret = ((EnumDescriptionAttribute)attrs[0]).Text;
        }
      }
      return ret;
    }

    /// <summary>
    /// Gets the enum value from its description.
    /// </summary>
    /// <param name="description">Enum description.</param>
    public static T GetEnum<T>(string description)
    {
      Type type = typeof(T);
      FieldInfo[] fields = type.GetFields();
      foreach (FieldInfo info in fields)
      {
        // if the passed-in description is the name of the Enum, return that
        if (info.Name == description)
          return (T)Enum.Parse(type, info.Name);

        // otherwise look at descriptions
        object[] attrs = info.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);
        if (attrs.Length == 1)
        {
          if (((EnumDescriptionAttribute)attrs[0]).Text == description)
          {
            return (T)Enum.Parse(type, info.Name);
          }
        }
      }

      return default(T);
    }
  }
}

Usage is something like follows

  public enum LogEntryType
  {
    Workflow,
    [EnumDescription("User information")]
    User,
    [EnumDescription("Workflow runtime")]
    Runtime,
    Error
  }

  string logEntryTypeString = EnumDescription.GetDescription(logEntryType);

  LogEntryType eventType = EnumDescription.GetEnum<LogEntryType>(logEntryTypeString);

Wednesday, March 21, 2007

Not liking Vista so much

Doing a search on Google for 'liking Vista' brings up this site as the third in the list. I'm not triyng to show off by saying this, but it perhaps shows that there's not that many people who are liking using Vista. And I'm slowly moving from the liking Vista camp to the not liking Vista so much camp. To be fair most of the problems I'm having probably aren't Microsoft's fault but they are still annoying.

My major problem is the lack of sound coming out of my Dell Dimension machine. This was forgivable initially since I installed Vista before it hit the shops but even though Dell have released new drivers I still can't get anything to come out of my speakers. Vista thinks everything is OK, the only indication that something is wrong is the 'Failed to play test tone' error message when I do a test of my speakers. I've contacted Dell and talked to a tech support guy who said he'd get back to me and I've never heard anything from him since. It seems like other people are having the same problem so I'm hoping this should be resolved soon. Good job I've got an XP machine with sound for Skype.

Next up is my USB wireless connection. It works fine but every time Vista starts up it tells me the driver has been blocked (5 times for good measure) and doesn't tell me how to get rid of the error message.

Finally, SonicWall haven't released a version of their VPN client that works with Vista. Apparently they should have one out by Q2. Again my XP machine has saved me, since I need to use SonicWall virtually every day.

Dude, where's my AdSense revenue?

I was never going to become rich from my AdSense income, but I used to get a small amount of spending money from it. But over the last few months, even though I'm getting more hits to my sites, I'm getting less and less money from ads. I think it's down to the fact that I'm getting less money per click. There was a time when some clicks would earn me a dollar or more (which, to be fair, seems ridiculous) but now I'm lucky to get more than 20 cents per click. So I guess the question is whether there is a general downward trend in prices being paid for clicks or if Google is taking a bigger slice of the action. Of course it could be just me who's suffering from this and it may be something specific to my sites causing the lack of cash. 

Tuesday, March 20, 2007

Twitter - What the ...?

I don't get it, why would I want to use it? Why would I even want to read it, do I really care that complete strangers are on their way to work or having a dump? Even if there were people on there I knew, I wouldn't be interested. "Hmm, it's 11pm at night, what do you know, my rate Roger is off to bed, what a fecking surprise"

I believe we are meant to be looking for ways to save energy these days, so if anybody has access to the power switch on the Twitter server, just turn it off. You'll be saving us from the most pointless website ever and helping the environment at the same time.

Sunday, March 18, 2007

Has my fire really gone out?

So Paul Weller asked in 1993, to which the obvious answer was "In short yes. The Jam were pretty good, The Style Council had their moments (although sometimes in an unintentionally laugh out loud way) but your solo career has been pretty unspectacular". Just like the vast majority of musicians, Weller started suffering from Musician's Dementia when he hit the age of 30. Rather than produce anything worth listening to, they start to make sad facsimiles of their older material or they try and branch out into new genres and tend to look ridiculous.

So it is also true of IT? Do programmers in their 30s suffer from Programmer's Dementia? Have I got it? Would I even recognise it if I did have it? Am I just producing a sad facsimile of what I was doing in my 20s? Have I lost the ability to pick up new skills? Is there a good reason why coders over 30 are viewed with suspicion?

Or is this just the start of my mid-life crisis? Surely 10 years too soon.

Friday, March 16, 2007

Google, you are such a tease

You really are. The Random Pub Finder gets an inbound link and you start indexing all our pages, we get lots of hits, then a couple of weeks later our pages start dropping out of your index again. It's a little bit frustrating. And perhaps more concerning is the power you wield. But so long as you stick to your 'Do no evil' mission statement, I'm sure there isn't a problem, right?

Thursday, March 15, 2007

WFPad - DIY workflow designer

So previously I'd thought writing our own designer for Windows Workflow might be too time consuming, but today I found this lovely little designer which could be the basis for our own designer. It doesn't have any support for adding code to a workflow but I consider that a plus point. I don't actually want our business analysts to even see a code editor. If we can import and export to Visual Studio whilst keeping any code behind intact this may be a marvellous solution. Keep watching...  

Tuesday, March 13, 2007

Loving Windows Workflow, hating Windows Workflow

I've been messing around with Windows Workflow lately and it's a bit of a love-hate relationship. Here's what I love, the fact I've got a workflow runtime that I can host in any application and, even better, it costs nothing. Hosting the runtime and persisting workflows to SQL Server is also reasonably straightforward, although I'm not sure my implementation is rock solid (I'm sure I'll find out if/when we go live). I love the fact I can develop workflows in Visual Studio and I can drop into C# whenever the activities provided don't quite do what I want. I love being able to write my own activities so I can parcel up commonly used functionality. I love being able to plug activities and properties together without writing any code. But then I'd like to think a business person might be able to design workflows and I can't see them picking up Visual Studio to do that. OK, I can host the Designer as well, but that's a pretty big job that I don't have time to do. I guess we could look at using SharePoint or BizTalk, but that would rather defeat the purpose of using Windows Workflow, which is primarily the cost. This seems to be the major problem workflow has always faced, making it simple enough for your average business person to understood (not suggesting they are simple of course...) but powerful enough so it can be used for real integration work. Coming from a background of using Metastorm e-Work there's a few obvious things missing from Windows Workflow that are available in e-Work. One is roles management, the other is easy forms integration. I guess both can be achieved but I need to investigate how easy it will be to do them, especially integrating forms in a fairly generic way. There is a good reason for not providing these features, since Windows Workflow is meant to be database and client platform agnostic. As ever, making a product as flexible as possible tends to make it somewhat complex and I think Windows Workflow has turned up the flexibility to 11. I have a few other niggles. Versioning doesn't seem to be supported. Workflows are persisted using .NET serialization so rebuilding a workflow assembly can cause any running workflows to fail. In fact I've had situations where I'm unable to do anything with a workflow, even terminate it. One other problem is there seems to be no simple way of getting data in and out of a workflow, without designing this data exchange into the workflow itself, something I was hoping to avoid since I was hoping to be able to do it in a generic way. But overall, given it's a version 1 product, I think Windows Workflow is pretty cool. Hopefully some of my problems are just caused by not understanding how it all fits together, so it's time for me to go and read a book.

Thursday, March 08, 2007

Panic Over - Climate Change is a Swindle

I was under the impression that we were all in agreement, that climate change is happening and it's out fault. But according to Channel 4's documentary this evening, we've all been conned. Apparently, although historical rises in CO2 do match rises in temperature, it's the rises in temperrature that drive the rises in CO2 rather than the other way round. I get the feeling that if this were the case, there would be a few more dissenting voices in the scientific community so I won't be going out to buy a mechanical hippo tomorrow. Even if it is true, the fact is fossil fuels will run out one day so we have to find alternatives, and the sooner we start to do that the better.

Sunday, March 04, 2007

Is Peak Oil here?

Apparently Saudi oil production was down 8% in 2006. I don't know enough about the subject to know if this is important or not, but it makes for interesting reading. http://www.theoildrum.com/node/2325

New template

I've finally taken the plunge and upgraded my template for the latest version of the Blogger software. I think the design looks much slicker and the template editing tools in Blogger look more powerful, although I haven't really done much with them yet. I've lost a few things from my template which I will be adding back when I notice them. Edit- Yes, the template editing is much better. Adding tags to posts is a pretty poor experience though. It looks much like adding tags in GMail but the usability is pretty poor. If you add a tag to a post, you're then sent back to the top of the first page of your posts after applying the tag. You can choose to show 300 posts per page but then it all gets very slow and after applying a tag to a post, the post remains selected. This means you have to trawl through all your posts again to find the post to deselect it before adding any other tags.

Wednesday, February 21, 2007

Sorting in a DataGrid

There doesn't seem to be a lot of information around on getting sorting in a WinForms DataGrid to work with custom collections. So I've done the hard work for you and here it is. First I wrote a sorting class, hopefully generic enough to sort pretty much any kind of simple data types (if your collection contains other objects you'll probably need to update this somewhat).

  internal class Comparer : IComparer
  {
    private PropertyDescriptor sortProperty;
    private ListSortDirection sortDirection;
    public Comparer(PropertyDescriptor sortProperty, ListSortDirection sortDirection)
    {
      this.sortProperty = sortProperty;
      this.sortDirection = sortDirection;
    }

    #region IComparer Members

    public int Compare(object x, object y)
    {      
      Type propType = sortProperty.PropertyType;
      int sort = 0;
      if (propType == typeof(string))
        sort = string.Compare((string)sortProperty.GetValue(x), (string)sortProperty.GetValue(y));
      else if (propType == typeof(DateTime))
        sort = DateTime.Compare((DateTime)sortProperty.GetValue(x), (DateTime)sortProperty.GetValue(y));
      else if (propType.IsEnum)
        sort = (int)sortProperty.GetValue(x) - (int)sortProperty.GetValue(y);
      else if (propType == typeof(int))
        sort = (int)sortProperty.GetValue(x) - (int)sortProperty.GetValue(y);
      else if (propType == typeof(Type))
        sort = string.Compare(sortProperty.GetValue(x).ToString(), sortProperty.GetValue(y).ToString());
      else if (propType == typeof(bool))
        sort = string.Compare(sortProperty.GetValue(x).ToString(), sortProperty.GetValue(y).ToString());
      else
        throw new NotSupportedException();

      if (sortDirection == ListSortDirection.Descending)
        sort = -sort;

      return sort;
    }

    #endregion
  }

Then I had to implement the IBindingList interface. Actually most of the IBindingList interface is redundant (makes me wonder why it wasn't broken down into a few smaller interfaces, ISortList, ISearchList etc), so here are the bits that are different to the stubs provided by Visual Studio.

    void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)
    {
      sortProperty = property;
      sortDirection = direction;
      objectList.Sort(new Comparer(sortProperty, sortDirection));
    }

    private PropertyDescriptor sortProperty;
    PropertyDescriptor IBindingList.SortProperty
    {
      get
      {
        return sortProperty;
      }
    }

    bool IBindingList.SupportsSorting
    {
      get
      {
        return true;
      }
    }

    bool IBindingList.IsSorted
    {
      get
      {
        return (sortProperty != null);
      }
    }

    void IBindingList.RemoveSort()
    {
      sortProperty = null;
    }

    private ListSortDirection sortDirection;
    ListSortDirection IBindingList.SortDirection
    {
      get
      {
        return sortDirection;
      }
    }

objectList is my internal ArrayList that contains the collection of objects I'm interested in.

I'm not entirely happy with this solution. I have a lot of collection classes and each one has this same bit of code in it, which always smells a bit bad to me. At some point I might try to create a base class that encapsulates this functionality but it doesn't look too straightforward, since IBindingList requires IList, ICollection and IEnumerable implementations as well... 

Tuesday, February 20, 2007

Metastorm Resources

As well as getting hits from people searching for remedies to their medical problems with their bell ends (hint: go and see a doctor), I also get a few hits from people trying to track down information about Metastorm e-Work/BPM. So here's a short list of potentially useful sites.

Process Mapping - OK, it's my employer so I'm biased but it has some useful stuff. If you develop with e-Work be sure to grab a copy of the Procedure Documenter Designer add-in, which not only automatically documents your procedure but also checks for problems in your procedure that are missed by the Designer's validation.

Process Mapping Forums - OK, it's my employer again but if you're looking for an online community to discuss e-Work issues, this is definitely the best place to go. The official Metastorm newsgroups are like a ghost town, the once great eworkdev.org is now a site about Chinese babies and the only other one I'm aware of, eworkhelp.org, seems to be dying due to lack of people and increasing spam.

FreeFlow - Hmm, alright, this is mine... But if you want to integrate .NET and e-Work, these class libraries may well help. There's also a replacement for the abysmal Metastorm admin tools, which I use everyday (can't remember when I actually used the official tools) 

BRD - Thought I better add something that hasn't got anything to do with me just to make me look a little bit impartial. BRD produce the Swift client, an alternative web-based client, that provides quite a few features not available in the standard Metastorm client.

If you have any other links, let me know and I'll update this list. 

Thursday, February 15, 2007

DataGrid copy to clipboard

Here's some code I knocked together to copy the contents of a WinForms DataGrid to the clipboard. Probably won't work for all possible data sources but it was good enough for my needs. 

    public void CopyToClipboard()
    {
      StringBuilder builder = new StringBuilder();
      for (int i = 0; i < ts.GridColumnStyles.Count; i++)
      {
        if (i > 0)
          builder.Append("\t");
        builder.Append(ts.GridColumnStyles[i].HeaderText);
      }
      builder.Append(Environment.NewLine);

      CurrencyManager manager = (CurrencyManager)BindingContext[DataSource];

      if (DataSource is DataTable)
      {
        DataTable dt = (DataTable)DataSource;
        foreach(DataRowView r in manager.List)
        {
          for (int i = 0; i < dt.Columns.Count; i++)
          {
            if (i > 0)
              builder.Append("\t");
            builder.Append(r[i].ToString());
          }
          builder.Append(Environment.NewLine);
        }
      }
      else if (DataSource is IList)
      {
        for (int i = 0; i < manager.List.Count; i++)
        {
          object item = manager.List[i];
          Type objectType = item.GetType();
          for (int j = 0; j < ts.GridColumnStyles.Count; j++)
          {
            string colName = ts.GridColumnStyles[j].MappingName;
            PropertyInfo propInfo = objectType.GetProperty(colName);
            object propertyValue = propInfo.GetValue(item, null);
            if (j > 0)
              builder.Append("\t");
            builder.Append(propertyValue.ToString());
          }
          builder.Append(Environment.NewLine);
        }
      }
      else
        throw new NotSupportedException();

      Clipboard.SetDataObject(builder.ToString(), true);
    }

Saturday, February 10, 2007

Resizing columns to fit in a DataGrid

I wanted to automatically set the width of columns in a WinForms DataGrid to something sensible based on the contents (using .NET 1.1 for a number of reasons). I've seen the solution to this in a couple of places but they didn't work for me because I'm using a grid that inherits from DataGrid and adds a few helper methods. So here's what I've come up with.

    public void AutosizeColumns()
    {
      Type t = GetType();
      t = t.BaseType;
      MethodInfo m = t.GetMethod("ColAutoResize", BindingFlags.Instance  BindingFlags.NonPublic);

      for (int i = 0; (i < TableStyles[0].GridColumnStyles.Count); i++)
      {
        m.Invoke(this, new object[]{i});
      }
    }

Sunday, February 04, 2007

The CSS media attribute

I was going to write about this some time ago and never got round to it but Jeff Atwood covers it much better than I could ever hope to. Another reason I thought I'd highlight this is after a conversation with one of our clients who'd paid a company to write an ActiveX control to produce printer friendly versions of web pages. There really wasn't any need, it's trivially simple to produce a stylesheet for printer-friendly output, generally all you need to do is hide some of your headers and menus etc. Even with my pathetic CSS skills I managed to create one for the Random Pub Finder.

On the other hand I'm not so sure about the use of a handheld stylesheet though. I did one of these for the Random Pub Finder as well, but as far as I can see we never get any hits from handheld devices. Also, I may be wrong but I think quite a few handheld devices actually ignore the handheld stylesheet and just render websites using the standard stylesheet. This is probably due to the lack of websites that actually provide a handheld stylesheet, meaning any handheld device needs to be able to cope with full-size pages anyway. And finally, it's a right pain testing your site against the huge number of devices out there, particularly as the emulators always seem to be a pain to set up.

Friday, February 02, 2007

Installing a .NET assembly with COM interop

I've written a .NET 1.1 assembly that needs to register for COM interop. I've been using the Visual Studio 2003 installer to build my installer, because it's generally good enough for what I'm doing and it's free. OK, it's not exactly free, but who buys Visual Studio for the installer bits?

Anyway, the installer had been working fine by setting the Register property of the assembly to vsdrpCOM but when I went to test the installer I'd built today after some changes to the assembly it wasn't getting registered. Oddly the install completed and didn't suggest there was a problem but the registry was empty. I could register the assembly using regasm, but that doesn't seem like such a good solution for customers!

So after a not so quick Google later I came across this newsgroup posting (near the bottom) which showed a solution to the problem. And it worked. Problem solved. What I particularly like about this solution is that I'm now back in control of registering my assemblies, rather than being in the hands of the installer's black box implementation, which I've had weird problems with before.

Thursday, February 01, 2007

So what is a bell end?

I noticed that a search for what's a bell end on Google brings up this site at number one, so I thought I better answer the question.

So here goes, bell end refers to the end of a man's, er, manhood. The name came about because it's shaped somewhat like a bell (go on have a quick check, nobody's looking) and it is, in fact, the end. It's a simple as that, although it's often used as something of a derogatory term, where someone might say "he's such a bell end".   

The obvious follow on question is why on earth I chose it as my blog name? And the answer to that is I'm not entirely sure. I've certainly been called it quite a few times (due to the surname) and couldn't think of anything more appropriate at the time.

BlogSpot not very well

Lots of people getting a bX-vjhbsj error, as am I. So you probably can't see this...

Wednesday, January 24, 2007

Snow


This morning we woke to a world of white. As is usual with snow in London it didn't last very long. It had all melted by lunchtime. So here's the photographic evidence.

Tuesday, January 23, 2007

Skype has reached critical mass

Looking at my Skype client running today, I see there are nearly 9 million people logged on as I write this. Some would say that's enough to show Skype has reached critical mass. But for me the real sign that Skype will soon take over the world is this. My mum uses Skype. I don't mean it's installed on her computer and she ignores it. No, she actually called me up on it the other day. And today she started an instant messaging session with me. So congratulations to Skype for writing a piece of software that is simple enough for a pensioner with techno-fear to use. And congratulations on your impending world domination. 

Friday, January 19, 2007

Things annoying me today

Empty try-catch blocks - "Oh shit, this bit of code fails, I can't be bothered working out what's going on, I'll just catch the exception (and any other exceptions that are ever thrown) and ignore it. Oh and I won't bother putting a comment in the code to explain why I'm catching this particular exception, cos I don't really know why I am."

Well, I guess the thought process is something like that.

Pointless member variables - OK, so you know what a class is and you know what a member variable is, but that doesn't mean every single variable has to be a member variable. It doesn't make your code more object-oriented, it just makes it more complex. If it's only used in one function, then it probably only needs to be declared in that function. In a managed environment, it means the variable goes out of scope earlier and doesn't have to live for the entire life of the class instance. And your code is more maintainable. Although I'm guessing maintainability wasn't the prime concern of whoever wrote this app...

Wednesday, January 17, 2007

Why you should be using the .NET Framework

Larry Osterman has written a series of posts about software contracts. Well that's what they are meant to be about, but in the end they've been more about the fact that using the PlaySound API asynchronously is really amazingly difficult. One problem is that it's not documented particularly well, but the main problem is the design. The caller allocates some memory, which it must clean up after the sound has finished playing, but if you play it asynchronously you don't get any notification of when it has finished. There's a number of solutions, like kicking off the call synchronously in a separate thread or polling to see when the sound has finished. Larry even went so far as to provide some code to find out how long a WAV file is. Unfortunately some developers 'solve' the problem by just never freeing the memory.

Anyway, this just reminded me of what a complete PITA the Windows API can be, with weird structures and pointers to pointers, and all the docs expecting you to be a C programmer. To be fair, lots of it was designed 15 or more years ago, when PCs were completely different beasts to what they are now but I'm so glad most of my development is now using the .NET Framework. And playing a sound? Actually that was a gaping hole in .NET 1.1 but .NET 2 has the SoundPlayer class. For an async experience, call AsyncLoad, respond to the LoadCompleted event and then call Play and that's it.   

Friday, January 12, 2007

IE7 Uptake

According to the IE blog, they reckon 25% of web users are now using IE7. I'm seeing about 20% on my sites, but I bow to their bigger sampling space. Even so, it looks like I was somewhat over-optimistic with my prediction.

Thursday, January 11, 2007

Things annoying me today

FOR XML RAW - Why on earth would you ever use this in a stored procedure? OK, I can think of one use, when you want to do some kind of XSLT on the stored procedure output to produce some HTML or whatever, but not just so you can treat the output from a stored procedure as an XML document. What's the point? Just traverse the record set using the provided database classes.

Commented out code - If you're using a source control system (and if you're not then you're doomed), why leave commented out code lying around? It's all stored away in the file history. If I do a search for a call to a function, finding lots of commented out code is a waste of my time.

Copy and paste code - It's great to fix a bug in some code, then to find it's been reproduced verbatim in 4 other places in the project...

Monday, January 01, 2007

John Naughton's predictions for 2007

I always read John Naughton's column in the Observer, I'm not really sure why. Sometimes he has some valid points but he seems so consumed with hatred for Microsoft that he often completely loses the plot. His predictions for 2007 (towards the bottom of this article) seem to me to be some way off the mark.

First up, we'll see the "continued decline of Microsoft". He's been predicting this for so long, he's bound to get it right at some point. Apparently Vista may be the last version of Windows, er why? There's nothing in the article to back up this theory. Also some customers may have to upgrade their hardware to run it. Nothing new there, that has been the case for every new release of Windows but isn't reason enough for it to fail.

Not only that, "The trauma of producing Vista has shaken Microsoft to the core". Really? Sure, it took longer than expected but then so does every bit of major software. He then goes on to say Microsoft has become a middle-aged company, a point that I do agree with. Of course the bigger question is whether Microsoft can continue to use its huge cash reserves and near monopoly position to overcome that particular problem.

He goes on, "the PC is no longer the cornerstone of our information ecology. The network has become the computer". Hmm, unless I'm mistaken every time I connect to the internet I do it through some kind of computer, I can't mind-meld with Google just yet. And most of those computers still run Microsoft software (about 90% of the ones that hit my sites).

Then he moves on to Google's rise. He says its dominance is "underestimated by the usual market-research statistics, which put Google's market-share in the upper forties". I agree with this point, our logs suggest Google is driving about 70-80% of our search traffic. But as the Internet Outsider points out this is not necessarily a good thing. Google is going to find it hard to increase its market share much more, so where will revenue growth come from, since most of its income is based on search?

Finally he moves onto virtualisation technologies being a big thing in 2007. He correctly points out that server farms use up a hell of a lot of resources but I fail to see how virtualisation is going to help here. Having two virtual servers running on one physical server doesn't double the processing power, since each virtual server will essentially have half the processing power of the real server, in fact slightly less due to the overhead of the virtualisation software. Where virtualisation is useful is for running a piece of software on a different OS. So a Mac can run Windows software or vice-versa. I think this could be very useful to a company like Microsoft, since it can forget about backwards compatibility in its operating system, instead letting incompatible software run in its own virtual machine, which in turn may mean their next OS release will be a little easier to get out of the door.

Saturday, December 30, 2006

Deadpool 2007

It's that time of the year again when I have to submit my list for the Deadpool game. If you're one of the celebrities on this list, don't panic. I haven't come close to winning in the several years it's been running. I always keep the same list except for any additions, a strategy that has been spectacularly unsuccessful. 

  • David Rockefeller, 1915, Very rich, very old
  • Denis Healey, 1917, Old Labour
  • Billy Graham, 1918, time to meet his maker
  • John Glenn, 1921, It could be one space mission too many
  • Hugh Hefner, 1926, Viagra overdose? 
  • Boris Yeltsin, 1931, A popular choice, with good reason
  • Larry Hagman, 1931, Already on his second liver
  • Alex Higgins, 1949, Snooker player with throat cancer, apparently
  • Shane MacGowan, 1957, Singer with a soon to be non-functioning liver
  • Holly Johnson, 1960, Frankie Goes To AIDS Clinic
  • Monday, December 18, 2006

    Displaying a tick mark in HTML

    This afternoon's challenge was to get a tick mark to appear in a HTML file. Not too taxing I thought. I'd already done it, using the HTML entity &#10003;. But this didn't properly in all browsers. I initially thought the problem was some kind of encoding problem but it seems that unfortunately it's one of those HTML things that works in 'modern' browsers but doesn't seem to work in IE6 (this ✓ should be a tick mark, if you're one of the lucky ones). Given that most people are still using IE6, it's not really an ideal solution.

    So what to do? I thought I'd search for a fairy common font that had a tick mark available. WingDings does and although it's a Windows font, I thought it would be available on enough computers to suit my needs. Unfortunately, as this page shows, FireFox doesn't display WingDings fonts at all, even when they are installed on the computer. Most odd, although it seems that this is how browsers should work...

    You may be asking why I didn't plump for the simplest solution, displaying an image? Unfortunately I'm generating a web page on the fly on the user's PC and I don't want to be generating extra images if I can avoid it. Life could get very complicated if they already have a file with the same name on their PC. I guess they wouldn't appreciate me overwriting it.

    So my not very neat solution was to use a standard checkbox, <input type="checkbox" disabled checked>, . This wouldn't be too bad if I could apply some styling to it to make it look less like a checkbox, but CSS for a checkbox is ignored so I'm not very happy with the resulting output. If anybody knows of a better solution, let me know.

    Addendum - Since quite a few people are finding this page, you might be interested in the follow-up posts, which have a potentially better soluton to this problem

    Sunday, December 17, 2006

    Another way to get more hits to your site

    I guess like most sites the Random Pub Finder gets most of its hit through Google searches. But a drunken chat with a friend led to another way to drive more traffic to the site. I've uploaded all the pub images to Flickr and added links to the reviews on the site. So far results have not been spectacular but it means we have deep links into some of our pages so their PageRank should improve. And who knows, it might work for you.

    Thursday, December 14, 2006

    Setting a display from: address using CDONTS

    Since it took me so long to find the answer to this problem I thought I'd post it here (and also so I don't need to look it up again). Not sure if this applicable to other ways of programmatically sending email but I guess it probably is. To show a friendly display name when setting the From: address of an email using CDONTS just use the following syntax -

    (Test address)<test@test.com>

    Wednesday, December 13, 2006

    Testing, testing

    Just testing out Windows Live Writer with the new version of Blogger... And it works, hurrah!

    Tuesday, December 12, 2006

    Reading embedded resources in C#

    Reading embedded resources in .NET isn't particularly hard but since I always forget how to do it, I thought I'd write it down for my own benefit. 

    First thing to do is set the Build Action property of the file you want to embed to 'Embedded Resource'. Next download my Resource Explorer from

    http://www.doogal.co.uk/ResourceExplorer.php

    After building the assembly, inspect it with this little utility to find out the name of the resource. If you're clever you can probably work out the resource name for yourself but I'm lazy and/or stupid (depends which day it is).

    Finally, the code to read it is something like this.

    Assembly assem = GetType().Assembly;   
    using (Stream stream = assem.GetManifestResourceStream("resource name"))
    {
      stream.Position = 0;
      // read data from stream

    Thursday, December 07, 2006

    Visual Studio 2003 on Vista

    OK, I should have known better. I'd read about the lack of support for Visual Studio 2003 on Vista, but then I read another article claiming all I needed to do was turn off UAC. I was planning on doing that anyway, since UAC seems like the biggest PITA of all time (and I seem to avoid any kind of virus/malware without it). So I went ahead and installed Vista. And Visual Studio 2003 falls over all the fecking time... I can't edit any of the code-behind files in one of my websites.

    Fingers crossed Microsoft will release a version of VS2003 that actually works on Vista. If it means turning off UAC, I'm cool with that. Their excuse is that they want to use their scant(!) resources on the next version of Visual Studio. Even if I believe they haven't got the resources to get VS2003 to run on Vista, can't they slow down a bit? .NET 1.1 does most of the things I want to do pretty well, .NET 2.0 adds a few nice things, but nothing mind blowing, I don't even care about .NET 3.0 yet, so I care even less about the next version. The thing is I have a job to do and that job is to get working stuff to clients, they don't care what version of .NET I'm using and certainly don't want to be paying for me to upgrade to the latest and greatest version every other day... 

    Currently listening to 'Nothing' by 'No-one' from the album 'My soundcard doesn't work on Vista'

    Monday, December 04, 2006

    Reflector insanity

    I spent a couple of days at a conference last week, which was fun. What did I learn? A few things, but the weirdest thing I learned was about Reflector's crazy behaviour. Often when Reflector starts up it informs you there is a new update available. Generally I'll let it do its thing and download the update. But it turns out if you don't download the update when you exit Reflector it deletes itself from your hard disk...

    Wednesday, November 29, 2006

    Liking Vista, mostly

    I've got no sound, Visual Studio 2003 is a bit unsure of its new environment, it took me an hour to fix up my source control installation due to Vista clobbering file permissions, UAC is crap (I have turned it off and turned off the warning telling me to turn it back on) and SonicWall VPN Client doesn't work but... Vista is actually pretty good. Search works quickly for the first time ever in Windows (and searches emails as well!), the new UI is actually quite beautiful (something that could never be said about the XP Fisher-Price look), IIS 7 is a damn fine upgrade (although it took a while to get my ASP.NET 1.1 apps up and running) and performance seems to be pretty much the same as XP, which is quite remarkable given all the visual additions and extra services that have been added.

    No doubt the Mac did it better two years ago but the Mac doesn't have any apps I need. My Mac OSX box sits unloved in the corner with nothing to do...

    Sunday, November 26, 2006

    Vista headaches

    I'm a bit of a fool when it comes to new software, if I can get a copy of something cool for free I'll probably install it. So, since the company I work for now has an MSDN license I thought I'd give Vista a spin.

    So I pretty much ignored the warnings the installer gave me about the problems I might have and went ahead and installed it. And the warnings were pretty much spot on. I now have no sound and I can't play videos. I have no idea why but I guess it's a driver problem. Hopefully Dell will fix the problem PDQ because sound is kind of important for me since I use Skype all the time...

    Other than that Vista seems to work fine. I'm not sure at this point whether the upgrade was worth it, nothing has jumped out at me as an aboslutely must have feature.

    Saturday, November 18, 2006

    FireFox and IE differences

    Often when I'm reading up on support for particular HTML or CSS features, I'll see something along the lines of "Most modern browsers support this feature, Internet Explorer doesn't". A loose translation of this could be "if you use this feature it won't work for 80% of your users".

    I do most of my testing in IE then go over to FireFox to make sure it looks OK and probably because of this it always seems to be the other way round, FireFox doesn't support a lot of stuff that IE does.

    FireFox doesn't have a way to render text vertically. OK, there's no official way to do this, so IE has come up with it's own CSS attribute, but I'm kind of surprised that FireFox hasn't come up with some way of doing it, it seems like quite a common thing to want to do.

    Another problem is hiding and showing rows in a table. FireFox kind of supports using 'display:block' but the row gets taller and taller with each hide and show. So I have to use 'display:table-row', which doesn't work in IE. Not sure which is standards-compliant but 'display:block' seems like the more consistent approach.    

    Friday, November 17, 2006

    XSLT not completely insane

    I've played with XSLT before and never quite got to grips with it, but over the last few days I've finally got a basic understanding of what it's all about. It still seems like it was designed by somebody who was an XML/HTML addict and could only think in terms of tags when developing a programming language. Like the old saying goes, when the only tool you have is a hammer, every job looks like a nail. But the thing is if you have an XML document and you want to transform it to some other flavour of XML or HTML then XSLT is a fine choice. I'm still not sure if my XSLT is any good or not, I've not seen any coding standards for it anywhere. Should I be splitting things out into multiple templates? Should I be doing anything in particular to make my XSLT more maintainable? Dunnow. But I've got 1000 lines of it and it produces quite a nice HTML document so that's good enough for me at the moment.

    Currently listening to Love Less by New Order from the album Technique

    Wednesday, November 15, 2006

    Well done Ken

    Chelsea Tractors are going to be hit by another tax soon, as the London Congestion Charge will be increased to £25 for band G vehicles. Well done Ken!

    Tuesday, November 14, 2006

    Breaking news: No-one buys Borland's IDE tools

    However they try to spin it, it's fairly obvious that Borland were unable to find a buyer for their IDE business. So my prediction was right. Is it good or bad news for Delphi and their other tools? It doesn't look great but at least they can hopefully stand on their own two feet and won't have their income sucked away to finance the ALM business.

    Currently listening to The Only One by Billy Bragg from the album Workers Playtime

    Crude awakening - Peak Oil

    Found a couple of interesting videos about peak oil and some of the possible solutions

    Part 1

    Part 2

    Saturday, November 04, 2006

    IE7 take-up

    IE7 hasn't been released as part of Windows Update yet, but its usage is up to 6% of all IE users on the Random Pub Finder. Saying that, FireFox 2 is being used by 38% of all FireFox users. I reckon that is down to the techy nature of most FireFox users. Funnily enough 20% of our visitors are now using FireFox, which is pretty astounding. I'd guess we've had quite a few techy people visit recently due to the coverage we've had.

    Thursday, November 02, 2006

    Build it and they will come

    After five years, the Random Pub Finder has finally become an overnight success. Google seems to have started re-indexing pages, although there's still a random nature to its indexing. We were up to 300 pages indexed, now we're back down to about 150. But the main reason for the sudden surge in traffic has been appearing at Programmable Web. Thanks to that, we've been covered on a couple of other sites. We've never had so many hits.

    Now I'm actually getting traffic here as well, thanks to this post. Seems I'm one of the top results on Google if you search for directmailchat. Clearly I'm not the only one suffering from this spam.

    Tuesday, October 31, 2006

    I am a sex god

    I've been getting a lot of emails like this recently

    Hi,
    Hope I am not writing to wrong address. I am naice, pretty looaking girl. I am planning on visiting your town this month. Can we meet each other in person? Message me back at qzyv@directmailchat.info

    Today was different, it came from somebody called Johnathan...

    Makes you wonder how successful these kind of spams are, with a To: list of several people, a From: address that doesn't match the address they've asked me to reply to, a load of spelling mistakes and apparently coming from a girl with a boy's name.

    Monday, October 30, 2006

    Hurrah for Richmond Council

    Richmond Council are introducing increased parking charges for high-polluting vehicles. This brought all the usual rubbish from the 4x4 drivers. Lets go through the points one by one.

    4x4s are efficient

    If your 4x4 is efficient then it won't be charged very highly. The charge is based on CO2 emissions, not car size.

    I need a big car, I've got 4 kids

    Presumably it was your decision to have 4 kids. Having kids is expensive, you have to feed and clothe them, house them. You wouldn't expect these to be subsidised would you? It's not like we have a shortage of kids on the planet.

    Climate change is just a theory

    Even though the vast majority of scientists agree that temperatures are rising and we are at least partly to blame, this line still gets trotted out. Can someone explain why I've still got bees flying round my garden at the end of October?  This isn't normal. But let's assume climate change isn't in fact happening. Cars produce pollution at a local level, are noisy and generally reduce quality of life, particularly in cities like London where there isn't enough space to accomodate them. Not only that, but fossil fuels will run out, some time. So it seems like a good idea to reduce our dependence on them.

    It's undemocratic

    The motoring dinosaur Jeremy Clarkson claimed the whole thing is undemocratic. How's that then? The council were voted for by the people of Richmond. If the residents don't like it, they can vote them out again.

    What I like about this scheme is that it shows we can do something about climate change at the local level, we don't have to wait for the government or, even worse, the international community to do something. Since we live in the neighbouring borough and our council is also run by the Lib-Dems, I'm going to be lobbying them to introduce the same scheme.

    Currently listening to Have A Day / Celebratory by The Polyphonic Spree from the album The Beginning Stages Of... [UK]

    Friday, October 27, 2006

    iTunes and Windows Live Writer love-in

    For the past few months I've been using my Toshiba Gigabeat to listen to music in my office, but something has been bugging me about it for a while. The random play functionality is completely whacked out. It seems to be random based on the artist, so if you've got one track by an artist, that artist will get as much coverage as an artist with 100 tracks.

    So I decided to move my MP3 collection on to my new PC and use iTunes instead. That in itself was a bit of a pain. The Gigabeat converts MP3s into a file with a SAT extension so you can't just copy them back across, since nothing but the Gigabeat knows what a SAT file is. But if you plug it in right, Windows recognises it as a media player and knows what to do with the files and does the conversion on the fly. All seems a bit odd really, but I could now listen to my MP3s through iTunes.

    And now I've found a very nice plugin (well two actually) that lets you insert the track you're currently listening to into your blog post. Perhaps it should be called 'Completely Pointless Vanity Plug-In' but I like it.

    Couple of things to note. The Apple website doesn't seem to be correct when it tells you where to put plug-ins for iTunes to pick up, it says they should go under 'My Documents' somewhere but I had to put it in C:\Program Files\iTunes\Plug-ins.

    The Live Writer plug-in goes in C:\Program Files\Windows Live Writer\Plugins but by default the plug-in will insert 'Nothing playing', you need to update the HTML template to something like <P>Currently listening to %t% by %a% from the album %al%</P> to get it to work.

    Currently listening to Carrion by British Sea Power from the album The Decline of British Sea Power

    Tuesday, October 24, 2006

    Disabling the Dell malware

    When I purchased my new PC it came with a whole host of crapware that I didn't want. Most of this could be removed but one piece of software remained, an extension for IE that brought up a Dell search page whenever a website failed to load. I've never tried to get rid of this because it's never caused too much harm but today it began interfering with my work so it was time to get rid of it. IE7 makes it pretty easy to disable pointless or dodgy add-ins. If you have the same problem as me, go to Tools/Manage Add-ons/Enable or Disable Add-ons and disable CBrowserHelperObject object. No more 'helpful' Dell search page, yippee!

    Sunday, October 22, 2006

    Google Sitemaps improvements

    I'm not sure when these changes were introduced to Google Sitemaps but there are now some useful little graphs that tell you how often your site is crawled and how responsive your site is. Go to the Diagnostic tab and click on 'Crawl Rate' to see it. You can even tell Google to crawl more often if you like (not sure if their bot will actually take any notice of this request or not). Overall, I like it a lot.

    Saturday, October 21, 2006

    So how quickly will IE7 be adopted?

    Apparently IE7 will be distrbuted as part of Windows Update, so I wonder how quickly it will replace IE6? Looking at the stats for the Random Pub Finder, of the 85% who used Internet Explorer to visit this month, 4% were using IE7. I'm guessing it will take about 2 months for the majority of IE users to have switched. Lets wait and see... 

    Thursday, October 19, 2006

    Somebody listened

    OK, probably not to me, but the silly error message no longer appears in the final released version of IE 7

    Wednesday, October 18, 2006

    IE7 Stupidity

    Internet Explorer 7 is mostly a good experience. Yeh, it's ripped off some of Firefox's features, but that's what Microsoft do well.

    But what on earth is this dialog box about? I tried to paste into a field in Google Maps and it popped up. I understand that Microsoft is getting a little paranoid about security these days, but of course I want to allow the webpage to access my clipboard, I just hit CTRL-V! Oddly enough this doesn't happen on all websites, so perhaps Google Maps is doing some odd scripting when I do a paste. Who knows, but please someone fix it!

    Exciting new website

    In their ongoing attempts at SEO, BetterDeal have got a new site (New Car Showroom) and they want some inbound links. Where better to get them than from here, with my huge number of visitors and massive PageRank?

    Monday, October 09, 2006

    Hello World for ZX Spectrum lovers

    When I was a young lad, there was nothing I liked more than going down to my local Dixons after school and typing my very own Hello World application into the nearest ZX Spectrum. But the Hello World apps I see today just don't match up to the beauty and elegance of that original version, so I've written one for C#

    using System;
    
    namespace HelloWorld
    {
        class App
        {
            [STAThread]
            static void Main(string[] args)
            {
                 line10: Console.WriteLine("Doogal is cool!");
                 line20: goto line10;
            }
        }
    }

    Who says goto is evil? I think I might adopt this style for all my applications...

    Sunday, October 08, 2006

    Bid on my birthday present

    My brother has given everybody the opportunity to bid on my birthday present. Looks like he'll send it to me, even if somebody else outbids me, but any proceeds go to charity, so get bidding!

    Thursday, October 05, 2006

    Google have cocked up again

    It looks like Google has cocked up its data update again. The PageRank updates it started a few days ago look like they are being rolled back, so the Random Pub Finder is back to PR 0. More worryingly, if I do a site: search, all URLs bar three are now shown as supplemental. But If I do a search for particular keywords, other pages on the site are returned and aren't marked as supplemental. Go figure.

    Wednesday, October 04, 2006

    How to have a reasonably successful website

    I can't pretend to know a lot about making a website a huge success, none of the sites I've been involved with have been massively successful, but I've kind of worked out how to get a reasonable number of visitors to a site without any kind of massive outlay. Here are a few of my thoughts.

    Don't spend a lot of cash

    Websites are pretty cheap to run. Even if your website is your business, you can probably keep it running with no visitors and no income for a pretty long time. Blowing any money you do have on advertising before you're even sure your site is up to scratch is a sure fire recipe for disaster. Better to get just a few visitors in who'll give you a good idea if you're heading in the rifgr direction and you can fix any problems you have before too many people spot them.

    I think advertising in the old media is pretty much a waste, it's very expensive and it's hard to see if it's been a success. You can advertise using AdWords for next to nothing, giving you the chance to see if it works at all and also trying out different advertising approaches.

    Don't ignore SEO

    Google is fond of saying that you should optimise for the end user, not the search engine. I can understand where they are coming from but essentially this is pretty much untrue. If end users can't find your site, whether the site has been optimised for users or not is pretty much irrelevant, they'll never see it. Chances are search engines will be the biggest source of traffic to your site, so of course you need to optimise for them. I managed to triple the number of visitors to the Random Pub Finder just by applying some simple SEO, all completely above board and not impacting on the end user at all. I found this free download a very useful read.

    Design isn't too important

    There are many examples of butt ugly sites being pretty damn successful (craigslist being the most obvious example) and plenty of examples of beautiful sites that have crashed and burned (boo.com comes immediately to mind). The fact is if the idea behind your site is appealling, people will come back. If the idea doesn't appeal, it doesn't matter how good looking it is, people will go elsewhere.

    One company I worked for redesigned their site about 4 times in one year, in an attempt to get more conversions. I've no idea how much they spent in total but the effect on conversions was pretty minimal, so it was pretty much wasted cash. Every redesign brought a host of new problems that needed fixing, along with pages stored in search engines that no longer existed. Not only that but time spent on those redesigns could have been spent refining and improving what was already there.

    Keep focussed

    I've never really stuck to this advice (this site covers whatever I can be arsed to write about) but if you want to get people coming back to your site it sure helps if your site covers a single topic, or a few related topics.

    Iterate and watch

    I come from a software development background and I've always practised a kind of iterative development technique. And I use the same approach when developing websites. Make a small change, see if it works, move on. Unlike software development, when developing websites the 'see if it works' stage doesn't just mean 'make sure it runs OK'. it also requires looking to see how it has affected traffic, so the iterative cycle can be somewhat longer. and to see if it works, you need to have some data. The cheapest tools (i.e free) for this job are Google Analytics and Google Sitemaps, which tell you how many visitors you're getting and what keywords are driving them there, along with heaps of other information.

    Take advantage of free advertising

    There are plenty of opportunities to get more hits on your site that cost nothing. When I post to a forum and I'm given the opportunity to provide a URL I always do. Of course, posting randomly to forums just to get a link to your site is generally considered as spam and will likely cause more harm than good. Sites like Technorati and digg can drag in more readers and directories related to your site can help pull in yet more eyeballs.

    Wait, and wait some more

    I have no knowledge of the search engine algorithms but I'm pretty sure, all other things being equal, a site that has been around for 5 years will rank higher than one that's been around for 1 month. So if you just hang around doing nothing, your site should start to get some more hits. I've never really done anything to get hits to doogal.co.uk, but I now get about 200 visitors a week.

    Monday, October 02, 2006

    PageRank update

    I've just noticed that Google seems to have updated PageRanks across my various sites. And finally The Random Pub Finder has got some PageRank! It's been PR0 for about a year, now we are up to PR3. My home page and this blog are both up, wahey!

    Wednesday, September 27, 2006

    The Great Australian Survey are spammers

    I signed up with the Great Australian Survey (www<dot>aussiesurveys<dot>com<dot>au) to see where BetterDeal were mentioned and I started getting the usual crappy offers from them. Kind of expected that, but the emails had an unsubscribe link at the bottom. I've clicked on that twice now and ticked the relevant boxes on their site but I'm still getting the emails. Either they are completely incompetent (why on earth are they sending emails to a .co.uk address anyway?) or they are spammers.

    Thursday, September 21, 2006

    Working from home is different

    Working from home is certainly different to the usual office environment. In most offices I've worked in I didn't have a window to look out of, never mind looking out to see a fox, who seems to have taken a liking to lying on my shed's roof in the afternoon sun.

    Wednesday, September 20, 2006

    The changing face of spam

    The Random Pub Finder has been getting a lot of spam reviews recently. This isn't a big deal, the reviews go straight to my inbox and don't appear on the site until I put them there, but the weird thing is the content of these spams. Many of them are bacon-related. Here's an example

    "a rasher ( and reland), or a slice ( orth merica). raditionally the skin is left on the cut and is known as bacon rind. indless bacon, however, is quite common. n the"

    I just can't work out what on earth they are trying to achieve.

    On the other hand, email spam seems to be getting more sophisticated. I'm now getting quite a lot of spam emails that contain a single image offering whatever penny stocks I really need to buy, followed by some text that isn't related and is obviously being added to get through the spam filters. How can we ever defeat that kind of spam?

    Sunday, September 17, 2006

    Saturday, September 16, 2006

    Dell vs HP

    I've got a new computer from Dell and now my HP DeskJet 5550 doesn't work. Funnily enough the reason I've got the printer is because my de-facto mother-in-law bought a Dell computer and the printer wouldn't work for her either. Who's to blame for this I wonder? I've been fiddling around with it for most of the day and can't get it to work. I can print out the HP test page but any other page refuses to do very much except throw out a blank sheet of paper. Based on my experiences with the new computer that have been mostly positive (except for the shitload of rubbish software it came installed with) I'm going to blame Hewlett Packard.

    Do you ever need to do a complete rewrite?

    Joel Spolsky's article about rewriting software has always struck me as a very well reasoned argument for never rewriting software from scratch. He mainly talks about Netscape's attempt to rewrite their browser from scratch. You might claim this was a reasonable success in some respects since it led to FireFox, which now has a pretty decent share of the browser market (about 10% I guess). But compared to the market share Navigator had before they started their rewrite it is still pretty miniscule. Of course they may well have lost a lot of that market share anyway, since MS was installing their browser on every new machine that was sold. But MS stopped developing Internet Explorer after they achieved almost complete ownership of the browser market, which gave FireFox a chance to gain ground. So basically we'll never know what would have happened if Netscape had continued with their old codebase.  

    So I was somewhat disturbed to find out one of my previous employers had decided to rewrite one part of the software product they sell. I could say who it is but I don't really want to have them getting their legal dogs onto me. I worked on this part of the system for over six years and it is pretty large (with third party code it's over 500,000 lines of code) and pretty central to the whole product. It is written in Delphi and the rewrite will be in C#. As a developer, you always want to work on the latest cool technology and always think the legacy code you're working on is a complete mess, so I'm sure they are happy to be involved on a green field project like this but I'd hope the people in charge would have a very good reason for wanting a complete rewrite, but frankly I can only think of one. It's probably getting increasingly difficult to get hold of good Delphi developers. The market is shrinking and from what I can see the good Delphi developers are moving onto other things, like C#.

    I've heard they have a team of five people working on this and it is planned to be done in a year. OK, here's my guess on how long it will take. Whilst I worked there, there were probably on average about 2 developers working on this bit of the system. I'm guessing it continued with the same level of manpower after I left. When I started they already had a working product, if a little rough round the edges, so say that took 2 man years. I started in '98, 8 years ago, so we have another 16 man years of work, 18 in total. Divide that by 5 people and we have about 3.5 years to write a piece of software that has the same functionality as what they currently have... Lets hope they have five really good developers...

    As an aside, it has to be pointed out you'd need to have very good reasons to want to get to C# anyway, whether through a rewrite or a migration. Whatever people say, Delphi is still a fine choice for Win32 desktop applications. OK, it is missing some of the nicer features of .NET like reflection and the availability of 3rd party controls is drying up but it still produces small, quick native apps. And if you have a stack of Delphi code, throwing it away is a very expensive thing to do.

    But is there any other way? I thought about this when I worked at the company. Like any developer I wanted to move onto new technology so I had a long hard think about how to get from the Delphi codebase we had to C#. One choice was Delphi for .NET, but this looked like a pretty painful route, especially with the number of 3rd party controls (many no longer supported) we were using. My though in the end was the best route to take would be to componentise what we had using COM. OK, this wouldn't really be a step forward, more a step sideways, but once you've got those components in place you could start to replace each bit piece by piece.

    But I hear you saying, that would take even longer, since you still need to rewrite each bit and you have the overhead of separating them into COM components in the first place. And you'd have to use that horrible COM Interop stuff as well. All true, but the major advantage of this approach is that you will always have an application in a state that is ready to ship, or very close at least. A complete rewrite means there will be a very long period of time when you can't ship anything at all, unless you want to add new features to the old codebase at the same time as adding them to the new codebase, which will be even more expensive and painful.

    So I wish them good luck with their development. I really do hope it works out, because my livelihood now depends on their software...

    Wednesday, September 13, 2006

    ASP.NET State Service crashes on shutdown

    Am I the only person to suffer from this? Can't find anything on the web but whenever I shut down my machine the ASP.NET State Service crashes. I thought it was caused by my old machine but my new machine has exactly the same problem. No big issue since the machine still shuts down but odd that nobody else seems to be suffering with it.

    Tuesday, September 05, 2006

    We are all doomed

    There are still people who claim climate change is only a theory, just like there are people who think that evolution may not be correct or the Holocaust never happened, but there seems to be pretty much total consensus amongst scientists that it is happening and we are to blame. But even if climate change isn't happening, there is another problem awaiting us, which certainly can't be ignored. Fossil fuels will run out and, more importantly, we will pass the maximum level of production, possibly quite soon. And once that happens, if demand continues to increase, the price will rise pretty quickly. And oil is fairly fundamental to our economy, due to the amount used to produce and transport goods. I was pretty stunned when I noticed some apples in our local supermarket were being imported from New Zealand...

    But running out of oil was bound to happen at some point in the future but unfortunately we have completely failed to address the issue, so we head into an uncertain future where "the Thames estuary is the most vulnerable place in northern Europe to major storm surges", which could affect me fairly directly.

    I'd always thought that computers would help out here. I'm doing my part by working from home but unfortunately it turns out that growth of the Internet is actually sucking even more power from the grid, so perhaps that isn't part of the solution either. So, as the post title says, we are all doomed.

    Monday, September 04, 2006

    100th Post

    So somehow I have managed to reach 100 posts on this blog. I was presuming that by the time I reached this point I would be a major web celebrity with millions of readers and I'd be rich beyond my wildest dreams through the adverts on-site. But it hasn't quite panned out that way and I have to say I'm disappointed in you all. Where are you and why are you choosing to read some boring old shite rather than the riveting stuff here? I feel like this kid...

    Friday, September 01, 2006

    The Apostrophe Protection Society

    Some people seem to have a real problem understanding where apostrophes should and shouldn't be placed so I was pleased to find the Apostrophe Protection Society, who were set up "with the specific aim of preserving the correct use of this currently much abused punctuation mark in all forms of text written in the English language". Their site explains all the rules which are generally pretty easy to understand, except for the occasional edge case.