Ask Dr. GUI #35

(Remember, he's not a real doctor. But he has become an expert in herbal remedies.)

July 1997

Still GUI After All These Years

Dr. GUI is pleased to note that this issue of Developer Network News marks MSDN's fifth anniversary. How time flies. The event has provided me with a marvelous opportunity to take a look at all of the old Dr. GUI columns over the past five years. (The columns were nearly 150 pages when printed out!) The good doctor managed to find some interesting history that he thought you might enjoy.

Five Years of Dr. GUI

"Ask Dr. GUI" was originally written by Bob Gunderson, one of MSDN's original employees and a member of the original Windows development team. Since (as you'll recall) MSDN's original (and current!) purpose was to make life easier for Windows programmers, early Dr. GUI columns focused on in-depth answers to common Windows programming questions. For instance, take a look at Ask Dr. GUI #1. In those days, Dr. GUI's personality was very business-like: you asked a question, Dr. GUI answered. For instance, this question was typical of the old days:

Deleting Stock Objects

Dear Dr. GUI,

I know the documentation says not to delete stock objects, but it is darned inconvenient to save a bit to indicate if an object is stock. I have many instances of code like the following:

if ((hobj = alloc an object) == NULL)
     hobj = GetStockObject(stock object);
// Use object
DeleteObject(hobj);

My question is:

Is it really a no-no to delete a stock object? Windows versions 3.0 and 3.1 both seem to handle it OK.

Also, the documentation says that GetStockObject can fail. Can it really fail if I ask for a legitimate stock object?

Dr. GUI replies:

It is absolutely safe to delete stock objects. GDI checks for this specific case and ignores the request if the object is a stock object.

While GetStockObject never fails when asked for a legitimate stock object, selecting a stock object into a device context (DC) using SelectObject can fail. When you select an object, GDI realizes it and may need to allocate memory. If memory is tight, the SelectObject call can fail. Your application needs to be able to handle this failure.

But from the beginning, Dr. GUI has had a certain bluntness and honesty that endeared him to other developers. If it's a bug, Dr. GUI calls it a bug. For instance:

OpenFile Documentation Bug

Dear Dr. GUI,

On page 10-5 of the Microsoft Windows version 3.0 Software Development Kit (SDK) documentation, in the Guide to Programming manual under section 10.5, "Reopening Files," the following statement appears:

"When a file is reopened, the file pointer marking the current position in the file is moved to the same position it was in just before the file was closed."

This statement is wrong. This documentation error has been around since version 2.03 of Windows. Please remove this statement from future releases of the SDK documentation.

Dr. GUI replies:

You are right! In fact, the statement has never been true.

 . . . or this:

Background Patterns and Wallpapers

Dear Dr. GUI,

I would like to change the background pattern and wallpaper from a DLL. What's the best way to do this? How does the Control Panel do it?

Dr. GUI replies:

Before Windows version 3.1 was released, the answer to this question would have been: "It's a secret; I can't tell you." Actually, the interface between the Control Panel and the window manager part of Windows was so cryptic and fragile that we really couldn't document it. All of this changed with Windows version 3.1. We knew that people wanted this information, so we created a completely new interface and documented it. The interface was implemented through a function called SystemParametersInfo. You can use this function to do almost everything that the Control Panel can do. For example, if you want to change the desktop's wallpaper, call:

SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "mypict.bmp", 
SPI_UPDATEINIFILE);

Dr. GUI always called it as he saw it, even if he had to pronounce parts of his beloved Windows "so cryptic and fragile that we really couldn't document it." This bluntness and honesty for the developer's sake has long been an important part of MSDN culture.

Dr. GUI would answer anything—even simple questions—if it would help a developer:

Capturing Screen Images

Dear Dr. GUI,

Hi. I'm in need of a screen shot tool that can take shots of a window and can also capture open menus. I'd like to avoid drawing menu bars by hand.

Dr. GUI replies:

Actually, you don't need a special tool to do this. Starting with Windows version 3.0, you can use the PRINT SCREEN key to capture an image of the entire screen. This image is placed in the Clipboard. If all you want is the active window, use the ALT+PRINT SCREEN combination. Simply paste this into your favorite bitmap editor (such as Microsoft Paintbrush), and trim the image you want.

Using ALT+PRINT SCREEN to capture dropped menus may be a little tricky because the menu manager uses the ALT key. But if you follow these simple steps, you can do it easily:

  1. Make the program active.
  2. Hold down the ALT key.
  3. Press the keyboard accelerator key for the menu desired (without releasing ALT).
  4. Move the selection with the arrow keys (keeping ALT down).
  5. Press the PRINT SCREEN key.

In these old days, the good doctor hadn't developed much personality—but he sure did know how to be a geek. Here's another instance of Dr. GUI doing whatever it takes to help a fellow developer out:

Disappearing Ice Cubes

Dear Dr. GUI,

So, I fill up my ice cube tray to the very top and stick it in the freezer. A month later I take out the tray (OK, so I don't use much ice) and notice that the ice cubes are gone. I live alone and I don't think thieves would break into my house just to steal my ice cubes. Where did they go? How can I keep them from disappearing? I mean, it's a real bummer to have a hot date over and find that I don't have any ice to chill down the $2 bottle of champagne I bought.

Dr. GUI replies:

Normally, I don't talk to people who buy $2 champagne, but I'll make an exception just this once.

What you are experiencing is called, in technical terms, sublimation. Sublimation happens when something that is solid becomes a gas without first becoming a liquid. Normally, in the case of ice, you heat it and it becomes liquid water. Heat it more and it becomes steam, a gas. But if the conditions are right, as is the case in your freezer, ice can become water vapor (a technical term for cold steam) without having to melt first. It all has to do with something called molecular bonding.

For the longest time scientists believed that molecular bonding, a measure of how well molecules stick together, was something that just happened. But today psychochemists are starting to understand the true inner feelings of molecules and their reasons for bonding. It turns out that molecules do have feelings and those feelings directly affect how willing they are to stick around. Imagine if someone stuck you in the freezer and ignored you for a month. You'd want to sublimate and get the heck out of there, too.

So, what can you do? Talk to your ice. It worked for plants, and it can work for ice, too. Tell your ice how grateful you are that it exists. Encourage your ice to keep bonding. Remind it of the long-term benefits of faithful bonding relationships. Sing songs of empowerment to it, such as "We Shall Overcome" and "Frosty, the Snowman." Do this and your ice will stick with you through thick and thin.

Then again, your ice might think that anyone who talks to it is really whacked out and want to sublimate and get the heck out of there.

And Dr. GUI clearly always understood his people:

Work Ethic

Dear Dr. GUI,

I have a recurring problem that may be shared by other dedicated hackers out there. Often while I am cranking out code late at night, I get hungry and throw a slice of pizza into the old microprocessor. Sometimes I forget what I am doing and just scarf a huge byte. Needless to say, the hot gui cheese burns the roof of my mouth. If I act fast, I can recursively stuff in a few more bytes (without swallowing) before the pain process kicks in. However, once the pain starts, it steals more and more attention cycles until it is hogging the entire system. My mouth quickly becomes non-reentrant, effectively blocking the nourishment task. Taking a slug of Jolt cola only seems to enhance the pain process. After uttering a few choice 32-bit words, about the only thing I can manage at all is a quick, mindless game of Solitaire before I am forced to power down and go take some offline time. This, of course, puts a major crimp in my 22-hour-a-day development schedule.

I have tried opening another window to help the pizza cool, but what with the Jolt and programmer's calculator in one hand, the pizza and mouse in the other, and 20-thousand-odd lines of code meandering around in my skull, I usually end up with a UAE due to system overload and have to reboot.

Some time ago an acquaintance of mine (my wife) suggested that I get a Life, but I already have seven versions of that stupid game taking up valuable space on my hard disk. What do you recommend?

Dr. GUI replies:

I see nothing wrong with this lifestyle. Reminds me of the night before we shipped Windows version 2.03. Ah! Those were the days!

Bob did the columns through Dr. GUI #10, when he was replaced by Dennis Crain. After his first column (Dr. GUI #11), Dennis chose to leave his name off the column, thereby giving Dr. GUI the anonymity he craves today. All subsequent Drs. GUI have kept this hallowed tradition. Dennis did Dr. GUI until about a year and half ago. Since then, there have been at least three Drs. GUI, all of whom would prefer to remain nameless.

Dr. GUI's personality developed quickly over the next few columns. Out went "I recommend," in came "the good doctor prescribes." And the titles for the questions started to be given a humorous medical twist. This is the personality Dr. GUI's had ever since.

Questions in these years shifted from being only basic Windows programming questions and began to include a mix of MFC and other questions:

Hey Doc, I'm Losing My Buttons!

Dear Dr. GUI,

For some reason my MFC 2.0 application is losing WM_LBUTTONDOWN messages. In my app, I have the OnLButtonDown, OnMouseMove, and OnLButtonUp handlers. In some cases, OnLButtonUp is getting called without a corresponding OnLButtonDown. What is going on?

Dr. GUI replies:

Thank goodness you still have your marbles! I was beginning to think that I was doing psychiatric rounds. In the Microsoft Foundation Class Library version 2.0, all frame and view windows (including MDI child windows) have the CS_DBLCLKS style. When a window class has the CS_DBLCLKS style, the following message sequence:

is converted to:

The above is what happens if the second WM_LBUTTONDOWN is within the system limit for a double-click. What is happening in your application is that the second WM_LBUTTONDOWN is being translated into a WM_LBUTTONDBLCLK. The easiest way to rid yourself of this double-click processing is to define an OnLButtonDblClk handler and have it call the OnLButton handler. For example:

  void CMyView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
   //
   //Don't do double-clicks.
   //
   OnLButtonDown(nFlags, point) ;
}

The tag line after the title has always (well, usually) been fun—and it's changed over the years:

(Remember, he's not a real doctor.)
(Remember, he's not a real doctor, but he's beginning to think he is.)
(Remember, he's not a real doctor. He's not even a veterinarian.)
(Remember, he's not a real doctor. However, he has a first aid card.)
(Remember, he's not a real doctor, even though he owns a cast saw.)
(Remember, he's not a real doctor. He doesn’t even play one on television.)
(Remember, he's not a real doctor, although he has a friend who is.)
(He often wonders what his life would be like if he finished pre-med.)
(He ordered his MD from the 1918 Sears catalog.)
(Remember, he's not a real doctor. He's just a figment of your imagination.)
(Remember, he's not a real doctor. In fact, he's not even a he.)
(Remember, he's not a real doctor. He is a toaster.)
(Remember: He’s not a real doctor, and he doesn’t do house calls.)
(Relax: Dr. GUI's still a human. It's not Dr. GUI who's changed: It's his environment.)
(Remember, not only is he not a real doctor, but he also doesn't remotely resemble George Clooney.)
(Remember, he's not a real doctor. He just plays one on CD.)
(Remember, he's not a real doctor. But he has a degree higher than a bachelor's.)
(He recently walked eight miles in a blizzard to deliver a keg of hot java to stranded developers.)

Interestingly enough, "Ask Dr. GUI" consisted entirely of questions until #20, when a brief note was added about Dr. GUI at Software Development East '94:

SD '94 Memories

From the desk of Dr. GUI

I had the privilege to meet many of you in the member lounge at the SD '94 conference held in Washington, D.C. during the first week of October. I will never forget you folks. How could I? The first character I met was James. James' conference badge indicated his title as "Psych." We talked at length about old technology. When he left he told me to simply put an "o" on the end of his title. Sounds good to me, James. Then there was Peter. Peter is a real doctor at the National Institutes of Health. He became disenchanted with medicine during his internship and turned to kinetic modeling. Sounds a bit like me (although I was never a real doctor and I have never done kinetic modeling!). His favorite disease? Ornithosis, a disease spread by pigeon droppings. I think that he made a wise move out of medicine, don't you? And what about Rusty? A FoxPro nut whose business card bills him as a ski instructor! What was he doing at SD '94? If you ever go to Whitetail, just look for some guy carrying a laptop on the ski lift.

I had fun. I hope all of you did too. I still owe many of you e-mail with follow-ups, so hang in there. Your questions may appear in this column in the future.

For a while, there were no more introductions (except for #21, which only explained that the column consisted of Microsoft questions rather than reader questions).

But then all hell broke loose. In "Ask Dr. GUI #25," Dr. GUI underwent a regeneration and became a she:

CH-CH-CH-Changes

It's a strange world. One day you put your faith in some guy who calls himself a doctor (but he really isn't). You can handle this. I mean, what's a little white lie between friends. Then, the next day, you find out that not only isn't the doctor a real doctor, but he isn't even a man! You wonder: Has my hero had one of those operations that people talk of in hushed voices? Have I been hornswoggled? Is hornswoggled a word? (Yes, it is.)

Well, there's no need to panic. The answer's really very simple. Those of you who are fans of the BBC television show "Dr. Who" are aware of an interesting anomaly that occurs every so often: The doctor regenerates into a new form. Usually this happens when the good doctor finds himself in a situation where, were he a normal human being (and not a time lord), he would die. Time lords don't die. They regenerate. Similarly, Dr. GUI didn't move on to do something more interesting and profitable—he regenerated. Now he's a she and, like her previous incarnation, she's not a real doctor. She does, however, golf on Wednesdays whenever possible.

Then, in #26, she regenerated again—and ended up a toaster:

WM_REGENERATE

I started hacking on my own private version of Windows 95 and added the WM_REGENERATE message. What a mistake that was! In my first sample application using this message, I inadvertently added the following code:

switch (message) {case WM_MOUSEMOVE: SendMessage(hwnd, WM_REGENERATE, wParam, lParam); break;

This has led to much inconvenience. Last column I was a woman; this column I appear to be a toaster. One second, do you smell smoke? Probably just from my editor's office. Anyway, I wonder what I will be in the next column, toast?

Then the good doctor went AWOL after Comdex:

Dr. GUI Goes AWOL

Editor's note: We regret to report that Dr. GUI has gone Dr. AWOL. The doc—who in recent months had undergone unsettling transformations of gender (from a "he" to a "she") and function (from developer-advice columnist to a toaster)—was last seen in the aftermath of November's COMDEX, striding unsteadily into the Nevada desert. We hope the doctor will find enlightenment there. So, with an eye to future columns, we have entered into serious negotiations with the doctor's long-lost twin brother. (He, too, of course, is not really a doctor.) In the meantime, we rummaged through Dr. GUI's desk and found, amid the pistachio shells and a discarded copy of the "Buns of Steel" video, the following leftovers from previous columns.

Dr. GUI eventually returned to Seattle (with a little help from his friends), got his own email account (drgui@microsoft.com), and has been ever since adapting to the Internet, Java, and other new technologies such as Windows CE.

Through all this, the questions have pretty much been a constant: you ask 'em, and the good doctor answers 'em.

What's in the future? Who knows? Dr. GUI's been looking into ways to help you all out even better—more frequent columns, maybe even a Web site. But one thing's for sure: Dr. GUI is looking forward to many more years of helping you have a good time and make lots of money by writing programs for Windows.

Dr. GUI’s Java Update

Dr. GUI has recently learned that Java's cross-platform capabilities aren't all the good doctor hoped they'd be. While "Write Once, Run Anywhere" sounds good on paper, differences in implementations of Java virtual machines mean that it's more like "Write Once, Test Everywhere." This shouldn't be a surprise: responsible software developers always test their programs on every platform/VM/browser they intend to support.

Dr. GUI apologizes for not noticing this earlier: since he runs only Windows 95 and Windows NT, Java appears to him to be very solid. But other publications spill the beans that many applications will not run unaltered on most of the available Java implementations (see "Java: A Field Guide for Users" in the May 27 issue of PC Magazine). PC Magazine's test suite wouldn’t run on most of the VMs without being altered. Performance also varies widely—sometimes by a factor of 100!

So is Dr. GUI abandoning Java? No, and here's why: Even if porting is required, Java apps are still likely to be easier to deploy across platforms. Easier porting means more customers. Dr. GUI is sure that the compatibility problems will get better—but don't think, even for an instant, that all the Java code you write is guaranteed to run correctly everywhere.

But there's a second, more important reason for sticking with Java: Java is a way cool way to develop great Win32 applications. The reviewers generally agree that Java runs best on Windows 95 and Windows NT—especially with Microsoft's virtual machine.

So before you commit to Java, be sure that it'll really do what you need. Do pilot projects. Test, test, test. And, as Dr. GUI's Polish grandmother said, "Fooled me once, shame on you. Fooled me twice, shame on me."