Why does my property sheet blink and the immediately disappear?


Occasionally, a customer will ask, "I'm trying to display a property sheet, but when I call the PropertySheet function, the property sheet blinks onto the screen and then immediately disappears. What is wrong?"

Recall that displaying a property sheet entails filling out a PROPSHEETHEADER structure, which in turn contains a pointer to either an array of HPROPSHEETPAGEs, or more often, an array of PROPSHEETPAGE structures. Each HPROPSHEETPAGE or PROPSHEETPAGE structure describes one page of the property sheet.

When you ask for a property sheet to be displayed, the property sheet manager looks up each of the pages you specified in order to get its title, and then it starts off by displaying the page you specified in the PROPSHEETHEADER.nStartPage member.*

Of course, in order to display the page to the user, the property sheet manager needs to create the dialog whose template you specified. And that's where the property sheet can blink out of existence: If the property sheet manager tries to create the dialog corresponding to a property sheet page, but the call to CreateDialog fails†, then the property sheet manager deletes that page and tries the next page. Now you see how the rookie mistakes we've been looking at so far combine to form a sophomore mistake.

If you make a rookie mistake and either specify the wrong dialog template or fail to register all the classes that your dialog template requires, then the property sheet manager will try to create your first property sheet page and fail. "Fine, let's try the second one, then." And that fails. "How about the third one?" And that fails. Finally, the property sheet manager has tried every single page and none of them could be created. That's when it gives up and tears down the property sheet.

This also explains why you might see a property sheet page that disappears once you click on its tab. The same thing happened: The property sheet manager tried to create the dialog, but the CreateDialog failed, so it deleted that page and tried the next page.

This is what often gets mistaken for psychic debugging. You just explore the space logically, consider at each step what could go wrong, and from that list of possible mistakes, choose the one that sounds the most likely. If you just jump directly to your conclusion, people will think you're psychic.

"I call PropertySheet and the property sheet appears on the screen for a split second, and then vanishes. What am I doing wrong?"

"My psychic powers tell me that you forgot to call InitCommonControlsEx."

"Wow, that's amazing! How did you know that?"

Sherlock Holmes used the same technique to draw startling conclusions in many of Arthur Conan Doyle's stories. Each step in the chain of reasoning was relatively simple and straightforward, but by chaining them together and announcing the conclusion directly, people will think you're psychic.

Nitpicker's corner

*You can override the title by setting the PSP_USETITLE flag and putting the custom title into the pszTitle member, and you can use the PSP_USEPSTARTPAGE flag to switch to using the PROPSHEETHEADER.pStartPage member to specify the starting page.

†Actually, it's CreateDialogParam since the lParam of the WM_INITDIALOG message points to a property sheet page structure.‡

‡Nitpicking a nitpick, if you use PSP_DLGINDIRECT, then the function to create the dialog is naturally CreateDialogIndirectParam.

Comments (15)
  1. Roger Wilco says:

    I have a psychic debugging question for you. Sometimes (maybe 25% of the time) my computer becomes non-responsive when I switch users on XP. The monitor loses its connection and goes into power save mode, the keyboard and mouse still have power (light up) but do not respond — for example the caps lock key does not toggle the light on the keyboard. I have to cold boot my computer. Any psychic debugging ideas?

    Also, this may be related, when I try to use the guest account explorer never runs.

    Hosed XP installation? Driver issue? Any ideas?

  2. The Notorious O.T. says:

    My brakes are squealing.  Where do you think I should get them fixed?  Any ideas?

  3. Anonymous says:

    Roger Wilco – this is off-topic, so I’ll be brief.  If networking is still fine, the chances are it’s Winlogon/terminal services failing; if networking stops, it’s probably something kernel-side.

    Since Win32k will have to reconnect your session to the console keyboard, video and mouse, you’re probably better off posting this to someone with extensive knowledge of such drivers.

    Alternatively, get a firewire cable and hook up a kernel debugger with a good internet connection – you can learn a lot by stepping through Winlogon’s calls before the crash.  For the explorer failure, trace from userinit.exe.

    [Okay, if you folks want to discuss this further, please take it to a newsgroup or something. -Raymond]
  4. Alex says:

    I ran into a similar problem when working on a wizard for Windows Vista. When launching the app, the wizard would briefly appear and then disappeared from the screen.

    It turned out the associated MUI file (the separate resource file in Vista) wasn’t in the right directory. Windows would try to load the program but it would fail because it couldn’t find the resources.

  5. stop it says:

    This is a blog with clearly specified topics! I don’t get it why people thinks this is a general computer support forum. I find such posts offensing, maybe trolling?

  6. *sigh*

    I wish this had been posted two weeks ago when I was diagnosing the very problem–and fixed it with with the very solution you specified.

  7. AlmostAlive says:

    I read this the other day and it really struck me as odd.  

    “If the property sheet manager tries to create the dialog corresponding to a property sheet page, but the call to CreateDialog fails†, then the property sheet manager deletes that page and tries the next page.”

    Why on earth does the property sheet manager do that?  That seems like the worst possible thing to do.  Would it not be way smarter to simply fail with a reasonable error than cycle through property pages looking for something that works?  That way I might not need psychic debugging.  Isn’t it always better to fail early than fail late?

    [Imagine what the world would be like if that were the case. (Hint: Shell extensions.) -Raymond]
  8. AlmostAlive says:

    “Imagine what the world would be like if that were the case. (Hint: Shell extensions.)”

    I see where you’re coming from but that doesn’t completely invalidate my point.  A buggy shell extension could keep property pages in explorer from showing up at all but then a buggy shell extension could do a lot worse anyway.  At least if it simply fails, the buggy extension might get fixed.  Instead this weird behavior becomes part of the API.

    The Windows API is extremely forgiving of problems in applications.  It seems like a case of short-term gain for long-term problems to me.

    [The buggy shell extension isn’t doing this on purpose. Perhaps the uninstaller ran into a problem and deleted the resource DLL but forgot to delete the registration. Now the user can’t open any property sheets. Assuming the user even knows what vendor’s shell extension’s uninstaller messed up, it was probably a non-reproducible fluke (file in use, power loss at a bad time), which makes a fix less likely. Or worse, it was an overly aggressive virus checker that deleted it. Result: “Windows is a piece of crap. I can’t open any property sheets any more, and reinstalling doesn’t help. I should have bought a Mac.” If a page can’t be created, would you prefer that the property sheet spontaneously dismiss itself and return an error? What should Explorer do if it gets such an error? Tell the user, “Sorry, you lose”? -Raymond]
  9. Cheong says:

    Hmmm… Is there any places that store those silently adopted errors that we can read from… perheps a debugger?

  10. AlmostAlive says:

    "Perhaps the uninstaller ran into a problem and deleted the resource DLL but forgot to delete the registration."

    Shouldn’t that be caught somewhere else entirely as opposed to the property sheet manager?  

    Don’t get me wrong, I fully understand your position.  The solution provided is good for the user: they can see their property sheets even if everything else has gone wrong and nothing has trapped the problem until just that moment.  But that solution is terrible for developers.  Isn’t catching the problem where it occurs is better for everyone than simply ignoring the problem at the lowest level?

    "Assuming the user even knows what vendor’s shell extension’s uninstaller messed up"

    Of course, they’ll never know.  Windows will never know.  The shell extension registration will stay in the registry forever.  The property sheet manager will try and load that property sheet every time for years and years and fail every time.  And ultimately thats the reason some people have to reinstall Windows every few years.

  11. DGmon says:

    2 AlmostAlive:

    with great power comes great responsibility. if the extension is buggy there’s nothing shell can do, but to try and catch.

  12. David Pritchard says:

    Surely Windows could identify the faulting shell extension, look it up on the internet, email the author, inform him or her of the error, help with the debugging process, receive the fixed build and install it?

    Come on Microsoft, you’re not even trying!

  13. Gabe says:

    I second David’s idea of automatically spamming the authors of buggy shell extensions.

  14. Igor says:

    How about this:

    Explorer:

    ‘Shell extension “Yadda, yadda”, from “Unfinished Software, Co” needed to display property page for this type of document has failed to initialize. Would you like Explorer to try loading the offending extension in the future?’

    [[No]] [Yes]

    Or would that be too psychic to implement?

    [You know how shell extensions work. You tell me. -Raymond]

Comments are closed.