July 1, 2003

By Karen Kenworthy

IN THIS ISSUE

So, you want to be a programmer? I don't blame you. It's one of the most interesting, rewarding jobs you can have. No two days are the same. And you're always learning something new. If you like to solve problems, be a detective, invent, and work indoors, it just might be your ideal job.

To help you decide, I thought I'd share a few days in the life of a professional programmer. Then you can decide if this is the life for you...

A Simple Request

It started innocently enough, a few evenings ago. Several readers have recently requested the same new tool, a program that would shut down their computers at a certain time of the day (or night).

Some of these folks have children who like to stay up half the night, chatting online or playing computer games. Others want to make sure their office computer is powered off at the end of each day, even if they are in a meeting or out of the office.

These seemed like reasonable requests -- especially since I already had two halves of the solution to their problem. One half was our Show Stopper program. As most of you will remember, this Power Tool can shutdown Windows in several ways. Depending on your hardware and version of Windows, it can power off your computer, log off the current user, force your computer to hibernate, or slow to an imperceptible, energy-saving crawl (suspend mode).

The other half of the solution was our Countdown Timer II. This venerable Power Tool remembers important events, and displays the number of days, hours, minutes, and seconds until the event occurs. At the appointed time I can jog your memory by sending an e-mail message, playing a sound file, running a program, or even cause an on-screen cartoon-like character (an "MS Agent character") to wave and speak a message. The Countdown Timer can also remember repeating events, such as those that occur every evening.

Sounds like a perfect match, doesn't it? Tell the Countdown Timer when the computer should be shutdown each day. And ask it run the Show Stopper to perform the deed. What could be simpler?

Well, as we all know, nothing in the world of computers is a simple as it seems. Unfortunately, the Countdown Timer does more than we ask of it. When asked to send an e-mail message, display an Agent character, play a file or run a program, it does as it's told. But it also displays an "alert window". And this window stays on-screen until a user clicks its OK button.

This sounded like a good idea, back when I designed the Countdown Timer. By staying on-screen until dismissed, the alert window insured the user was successfully notified of an event's arrival. And normally, this worked out well.

But when trying to automatically shutdown a computer, especially when the user is away, the alert window can create a problem. When asked to run a program like Show Stopper, the Countdown Timer needs to skip its customary alert window, waiting for an absent user to give their OK.

Fortunately, I wrote the Countdown Timer. And I can change it, making the alert window optional. Best of all, I thought, this should be an "easy change" -- a phrase that should be dropped from every programmer's vocabulary...

Unraveling

First I'll stick a new checkbox on the Countdown Timer's setup window. Then I'll add some text beside the box, reading "Display Alert window". That was quick! The user interface changes are done. No checkmark, no alert window. It's lookin' good!

Now I must find the instructions that display the alert window. They're somewhere in the program's "timer loop". These instructions execute once every second, updating the on-screen countdown display. They also check to see if an event's time has come.

If so, these instructions herald the event. They might send an e-mail message. Or play/open/run a selected file. They might even display a Microsoft Agent character and have it wave and speak. And of course, they always display an alert window.

Ah, here they are. Yes, just as I thought, a single instruction displays that pesky alert window. Now to make it "conditional", executed only if the user requests an alert window for this event.

That was easy! A few new lines of "code", and we're done. That's just the kind of enhancement I like -- useful and easy.

But something's wrong. If you disable the alert window, all the other forms of announcement get disabled too. No e-mail, no play/run a file/program, no Agent. The event comes and goes without any fanfare. But if you re-enable the alert window, everything works properly. Time for a little "debugging"...

Ah! I see the problem. Over the years, as I added announcement options to the Countdown Timer, I placed their instructions inside the alert window. That made sense at the time. Since an alert window was always displayed, its instructions could handle the other, optional, methods of notification. Display the alert window, and its code would take care of the rest.

OK, so I've got to store the notification instructions somewhere else. That's easy. I'll move them to a "module", my programming language's name for a location not associated with any particular on-screen window. A little cut and paste, a few more lines of code -- I'll be done in no time...

Well, that took a bit longer than I expected. It turns out the alert window's code did some other jobs I'd forgotten about. For example, it handled repeating events, those that are automatically rescheduled when they arrive. Moving those instructions out of the window was a little tricky, but not too bad.

Now I'm ready for a final test.

Hmm... Something's still wrong. Now the program can't display those cute Agent characters, let alone have them wave and talk. Each time it tries, an error message appears.

The agent software is installed properly on my computer. And it's working too. Other programs, like my Power Toy, can still display and control Agents. Only the new Countdown Timer has the problem. But why?

This is turning into a bigger job than I expected. But I'm too far along to give up. Besides, this is personal. I'm going to get this program working if I have to stay up all night. Wait a minute. Is that daylight coming through my window? OK, I'll get this program working if I have to stay up all day too.

Two Days And Two Nights

Surely this has happened to some other hapless programmer. I'll bet there's an explanation and workaround somewhere on Microsoft's developer web site, http://msdn.microsoft.com. No? OK, it's time to turn to Google (http://www.google.com). That search engine never fails. It'll turn up a solution in no time.

OK, looks like I'm on my own. What could I have done that "broke" the program, preventing the Agent from working? I did make a few changes, simplifying the code. But an hour or two spent reversing those changes, and trying some new ones, doesn't help.

Of course, I also moved the instructions out of a window, into another location. Could that cause the problem? Can Microsoft's Agents only be controlled from within a window?

Nah, that can't be. None of my Agent code refers to a window. It's just plain, vanilla programming -- instructions that can be run from anywhere.

Still, my program's broken. Let's try an experiment. I'll move my Agent instructions into a brand new window. Nothing else will change. I'll just move those instructions to a new location.

Bingo! That's it. Now everything works. For some reason, code that controls an Agent character must reside in a window. And I think I know why, too.

A program can be notified when a character finishes a movement or speech. That allows the program to trigger the character's next action. The notifications are sent in what Microsoft calls a "window message", a bit of data sent to a particular on-screen window.

My program doesn't use this technique. Instead of waiting for a window message to arrive, it monitors the Agent character directly, read to send the next command as soon as the previous command has been completed.

But Microsoft's Agent software always looks for a window, even if none is needed. If the code controlling the Agent doesn't have a window, the error message I've been seeing for the last few hours is displayed. And the Agent character refuses to load. :(

Whew! I'm not home yet. But I can see the porch light. The Agent code will have to stay in its new window. The window will be loaded into the computer's memory whenever an Agent character must appear. But the new window won't be seen. Once the Agent has done its job, the window removes itself from memory. The invisible window will do its job, and no one will be the wiser!

I don't know about you, but I make my best decisions when I've gone 36 hours without sleep. At least that's what I think at the time.

With a clear head, I might have stopped making changes to the Countdown Timer, content with making alert windows optional. But with a head that felt like it was stuffed with cotton, this seemed like the perfect time to add all those other Countdown Timer features that readers have requested. :)

Ironically, we don't have time to talk about the half-dozen other changes I made to the program, during my programming marathon. That will have to wait until the next time we get together. Don't make up your mind about a career change until you hear the end of the story!

In the meantime, you can enjoy the fruits of my labors. Just visit the Countdown Timer II's home page at:

    https://www.karenware.com/powertools/ptcount2

As always, the program is free (for personal use). And bleary-eyed programmer-types can download the program's free Visual Basic source code too!

Or if you prefer, get the latest version of every Power Tool, including the new Profiler, on CD. The disc also includes three bonus Power Tools, not available anywhere else. You'll find every back issue of my newsletter, and a few articles, in the CD's library. The CD even includes a special license that lets you use your Power Tools at work.

Best of all, buying a CD is the easiest way to support the web site and this newsletter. To find out more about the CD, visit:

    https://www.karenware.com/licenseme

Until we meet again, if you see me taking a nap, please don't wake me. But if you see me on the 'net, be sure to wave and say "Hi!"