There are many, many tools in the .net framework that are there to help solve specific problems that developers may need to overcome.  The big problem is knowing when they are there. For me, a great example of this is a problem that I used IMessageFilter on.

I didn't realize how neat this feature in the Windows Forms framework is, until I had an "off the wall" request from a friend. They had this small application that they created, and they were doing frequent training on it. What they wanted to do was highlight each control (textbox, listbox, label, etc) as the mouse went over it so that it was obvious what they were talking about to everyone in the room (especially the slackers in the back).

So, I gave the usual suspects as suggestions: inheriting from every control (yikes! for a demo only feature?) Trapping the mouseenter event of each control and sending them to a single delegate (but then every control must be hooked up to the delegate, and some are created dynamically. Still too many code changes) So what to do? It has to be easy to turn off, and so require almost no code changes... Hmm, IMessageFilter! We'll trap the mouse_move events and highlight the control

What struck me the most was how easy this was to perform once I found the right tool. Which is always the key with .net -- don't fight the framework, exploit it instead. It's amazing the number of times I'll see people implement elaborate hacks to do something because they didn't spend the time to find tools that would make the solution simple (myself included in these people).

So I've made a resolution: I now keep a list of what I think were "ugly hacks" -- places where I couldn't get .net to do what I wanted and so I beat it into submission. I'm spending just a bit of time per week revisiting the list, and for each item I'll see if these problems already had solutions. It's possible that I spent too much time creating my workaround and hacking away that I didn't spend the time to try and figure out how to remove the problem.

The filter is not a complex solution, but worked extremely well for the problem I was solving. So the points have been driven into my head yet another time -

  1. Solve the real problem. Which of these is the real problem - "users want a border around controls", or "how do we efficiently trap mouse events from controls"? (Hint, the last one is a problem within a possible solution, not the real problem)
  2. Don't become emotionally attached to your solution. Always look for a way to abandon it for something better.
  3. Many times we're under so much time pressure that think we have to bang out code really fast to get it done.  Might the time be better spent reducing the effort to implement the solution?


If you're at all interested in the filter we made to highlight controls, you can find it here . To use it, first put the source in your solution and compile it -- sorry, no pre-build assembly available. Feel free to change the namespace / code, whatever. (It is only one file of a couple hundred lines) Second, call the static HighlightFilter.MonitorForm(), passing in the form on which you want to highlight controls. (you can also call HighlightFilter.MonitorControl() to monitor a control and its children). The filter traps WM_MOUSEMOVE events, determines if the event happened over a control we're monitoring, and draws a rectangle just inside its client area (looking like a highlight rectangle). When the mouse leaves, it tells the control to repaint itself.

Download (er, view) HighlightFilter.cs.txt (a cs file with a text extension)