Widgets!

I wrote here last month about fooling around with Konfabulator, and I have been having a lot of fun with it. It really does remind me of working in BASIC all those years ago, with little programs that do cool stuff, and nary an MSDN browser session in sight. Working with Konfabulator reminds me of those days in other ways as well. Debugging facilities are pretty much limited to print statements, log messages, and alert boxes. You don’t have to be a programmer to enjoy Konfabulator. It is a compact program, trivial to install and set up, and comes with a bunch of cool widgets. Many more are available on the online gallery. But if you are a programmer then you can hardly use it for very long without making widgets of your own. True to form I couldn’t do a simple “Hello World” thing. Nope. I have a new computer built on AMD’s dual core Athlon XP processor, and I wanted a widget that monitored CPU loads for both cores. Why would you want to monitor CPU loads? Just because. I called my widget CPUSpy, and it looks like this:

If you have Konfabulator you can [download removed]. Once it is downloaded just double click the file to install it. You’ll need Windows XP, Server 2003, or Vista, for reasons I will detail below. Creating this widget turned out to be an interesting and sometimes frustrating exercise, for a couple of different reasons.

The first thing I had to do was create some images. I used to do a lot of this years ago, back when Paintshop Pro was shareware, but my skills were very rusty. The current standard for creating web graphics is Adobe’s Photoshop CS. This is an amazingly powerful program, with a suitably astronomic price tag: a full retail version costs more than $450. I started with Ulead’s Photoimpact. This product is priced in the $89 range, and you can download a fully-functional 30-day trial. The product has been evolving for more than ten years. It’s not as powerful as Photoshop, but it is powerful, and neither program is trivial to learn and use. Ultimately, though, PI’s clunky interface got the better of me. Fortunately there was a third choice, a cut-down version of the Adobe product called Photoshop Elements. Priced in the same range as Photoimpact, this is a slightly less powerful program with a much better user interface, and you can buy and download it (although there is no trial version). I think the widget turned out pretty well, and it actually looks better onscreen than the jpeg above would indicate. One of Konfabulator’s coolest features is it’s alpha-blended window and font transparency. If you install CPUSpy right click the widget after it starts running, and choose Widget Preferences from the context menu. In the Appearance tab you can play all aspects of the widget’s UI, including overall color scheme, transparency, and fonts. However, I have not yet mastered Photoshop to the point where I can reproduce the beautiful, glossy, fluid shapes of the widgets that Arlo Rose created for Konfabulator.

The second thing that made creating this widget an interesting and sometimes frustrating project was simply that you can’t get realtime information about the processor cores from within Konfabulator’s javascript implementation. But the creators of the shell environment provided the two essential tools you need to get around this limitation: a timer facility and COM interoperability. The timer facility is necessary because you need some javascript to execute every so often and update the display. The COM interop is necessary to drill down into Windows and get the data you want, namely processor loads. Armed with this basic strategy I began creating a DLL to house an ActiveX control that I could use from javascript. Inside the control I would call into the Windows API to probe for processor data. Sounds simple, right? Hell no it doesn’t.

The first problem was to figure out how to get processor data. The first solution that came to mind was the Windows performance monitoring model. If you run perfmon.exe you can see this facility in action. Windows maintains a layer of objects that represent abstractions of the hardware, including a Processor object. One of the counter properties of the Processor object is Percent Processor Time. That was the one I needed to get the processor load. There are a couple of different ways to hook into this information. One is the pdh library, that should work on any Windows platform. Another is the Windows Management Instrumentation (WMI) high performance formatted data objects. These are only available on the platforms I mentioned above. Neverthless I decided to go this direction because the WMI has a COM automation layer that supports a low-overhead high-performance means of querying the hardware objects. Performance as important, because the performance monitoring object model is essentially stored in a database that you have to query using a SQL-like syntax called WML. Queries take significant amounts of time (a second or so), and using the WMI high performance objects you can query for the object you want, grab handles to the counters you want, and then just refresh them and read them from time to time. Much faster. Still, I may try to make a pdh version of this and see how it performs.

Debugging was an issue as well, and I had to relearn some old tricks and make up a few new ones. Print statements and log messages are fine for javascript code, but debugging problems in an ActiveX control is another story alltogether, and I had a lot of problems. The WMI has to be programmed in very specific ways, and the documentation is often insufficient to make it clear what you should do. Thankfully we have Google, and everything has been done by someone, and probably blogged about. In the process of figuring it all out, though, I tossed a lot of exceptions. Early on I used a VB program to create the control and exercise its interface, and that was very convenient as I could easily set breakpoints in the control’s code. I did have to figure out how to get the debugger to handle mixed managed/unmanaged code, and since I was on the beta 2 of Visual Studio 2005 at that time, the docs weren’t terribly helpful. That framework took me pretty far, but when I started using the control from Konfabulator I ran into a bunch of additional issues. Fortunately I figured out how to use Visual Studio to attach to the Konfabulator process that was hosting my widget, and once again was able to set breakpoints in the control code.

So that’s my first widget story. CPUSpy is now in version 1.1, and very complete I think. Hope you download it and give it a try. If you do, pass along your comments to me at mark@markbetz.net. I’m leaving this one behind for the moment, and have started on the next project: a widget to monitor TCP/IP connections visually. When I have one or two additional widgets done I may make a page to host them.