Adding to the swarm of developer blogs since 2007

Tuesday, March 16, 2010

What a cruel fate, to be Ctrl-V'd

Questions like this pop up now and again over at StackOverflow and usually I find myself agreeing with the majority; copy-paste coding leads to smells and all sorts of nastiness. In our current code base here, I have had the joy task of refactoring some C# code that looks something like:

switch (caseName) {
  case "First":
    // Many lines of boilerplate
  case "Second":
    // Many lines of the same boilerplate with a single value changed
  // and so on

Inexcusable? Perhaps. However, sometimes the reality of business hits and you've got a day to implement a new feature for a demo tomorrow and right about then you start clinging to the Ctrl-C chord pretty hard. After all, shipping the product is a feature. So sometimes you suck it up and paste that switch statement together and hope for the best.

There is a line I like to draw, and that is when you start duplicating code that you don't understand. Recently I stumbled across the following blog post detailing a method to hide the checkbox from arbitrary items in a TreeView. I'll duplicate the important part of the code here (C#):

TVITEM tvItem = new TVITEM();

tvItem.hItem = node.Handle; 
tvItem.mask = TVIF_STATE;
tvItem.state = 0;

IntPtr lparam = Marshal.AllocHGlobal(Marshal.SizeOf(tvItem));
Marshal.StructureToPtr(tvItem, lparam, false);
SendMessage(this.treeView1.Handle, TVM_SETITEM, IntPtr.Zero, lparam);

What's missing here? Why that's correct, we're missing a call to Marshal.FreeHGlobal since MSDN says we need to free that memory. Now this is just sample code so you might be tempted to say that it is the reader's burden to interpret and understand the code (and I would agree with you). Looking at the comments to this post however, I see many individuals that seem to have taken the code literally and no doubt used it without thinking through it. As if further proof was needed I recently found nearly that exact same code polluting our own code base and fixed it. Now many of our developers are new to C#, and indeed, to Windows programming in general so I can't entirely fault them. I just find it hard to consider oneself a software developer (or moreso, an engineer) when actual design and engineering principles are ignored as often as they are in this field.

In case you were wondering, the correct code for hiding a checkbox on a TreeView doesn't need to allocate any unmanaged memory directly at all:

public const int TVIF_STATE = 0x8;
public const int TVIS_STATEIMAGEMASK = 0xF000;
public const int TV_FIRST = 0x1100;
public const int TVM_SETITEM = TV_FIRST + 63; 

public struct TVITEM  {
  public int mask;
  public IntPtr hItem;
  public int state;
  public int stateMask;
  public string lpszText;
  public int cchTextMax;
  public int iImage;
  public int iSelectedImage;
  public int cChildren;
  public IntPtr lParam;

static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, ref TVITEM lParam);

private void Hide_Checkbox(TreeNode node) {
  TVITEM tvi = new TVITEM();
  tvi.hItem = node.Handle;
  tvi.mask = TVIF_STATE;
  tvi.stateMask = TVIS_STATEIMAGEMASK;
  tvi.state = 0;
  SendMessage(this.Mission_treeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi);

It's almost funny to note that this code is both simpler and more efficient (although I haven't proved it) than the other (broken) code.

Thursday, March 11, 2010

Blog Post Mark II

Wow, 2007.

So it has been a while since this was updated; and yes I know it's pretty standard to say that but we're going on 3 years here so bear with me.

What has happened in all this time? Well PixelRPG ran out of the traditional developer resources (willingness to write mounds of boilerplate code) and is stalled pending further time and energy.

So where does that leave me? Well I'm working for a little company called Northrop Grumman and in doing so get to work with some talented folks writing software to display and manipulate some pretty big images. How big? Well I will say that our software has managed to load a 17 gigabyte file and display it at interactive framerates. I'll touch on some of the interesting things that can be done when you can't load an image into memory in a future post.

So lets get down to the motivation for this entry: blogs. I've noticed in my blogspace (blogsphere? blogodome?) traversals that there is some art to posting interesting and informative blog posts some people get, and some don't. You have people like Joel who may not post often but really truly put that extra effort in to make sure their post is fun to read and poignant. On a different side of the coin, you see people like Raymond who have an enormous backlog of posts coming at you every (work)day that are informative but not always fun. On the third side of our bizzare blog-coin you see the people that don't manage to nail the fun or the informative portion (I'm going to avoid naming names here but I think we've all see couple of these).

That said, here's what I've seen as important points to make a great blog:

  • Talk to your strengths: The classic advice given for speeches applies doubly so when people have time to really think about your posts. I've found it enjoyable to read what knowledgeable people have to say about subjects they've studied for ample quantities of time, or even smaller things like new usages for old tricks. Stay away from ranting about things that you clearly have very little idea about (for me, cooking).

  • Analogies are great (sometimes): If you've never had an analogy run away from you, you're probably in the minority of people. Sticking too hard to analogies can leave you trapped in a confusing world where you have robots applying lambda functions to sheep and now you've lost me. This post by Joel is an excellent example of how to set up an analogy effectively without running away with it.

  • Pictures! (or images, if you're a programmer): Images really make reading a blog feel less like a chore. Even pointless block pictures taking up space can exercise the reader's eyes and visually draw their attention down the page. I can't count the number of times I've stopped reading a blog that had Wall 'o Text syndrome.

  • Talk about ME: I'll end this short list with the most important one; we aren't too different, you and me, so use language that is personal and reflects that we're on similar footing. Relate challenges and interesting occurrences to common programmer experiences and issues. Don't just talk about how great your pet project Foo is, let us know how that dynamic event-based DSL parser threw you for a loop when it deadlocked every fifth run. Programmers that have been there can relate and (I would like to think) we appreciate that you are a human and not a marketing robot.

I would like to flesh this list out much more, however I'd need to go back and relive many of the blogging nightmares and that's too much for one work day.