Why does TaskDialog return immediately without showing a dialog?

A customer reported a problem with the Task­Dialog function.

We've encountered a strange behavior in the Task­Dialog function. A user reported that when exiting our application, our program played an error beep that didn't appear to be associated with an error. After investigating, we found that the sound is coming from our application trying to display an error dialog before closing by calling Task­Dialog. The error beep is played but no dialog appears.

Some background on the error condition that we're trying to report: We're calling Create­Window­Ex, and the window procedure creates another window in its WM_CREATE handler. It looks like the original window is destroyed before WM_CREATE is finished, so Create­Window­Ex returns ERROR_INVALID_WINDOW_HANDLE. It's not clear why this is causing Task­Dialog to fail, but this is the only scenario where we see this behavior. All other calls to Task­Dialog work as expected. We know how to fix the original problem with Create­Window­Ex, but we would like to understand what's going on with Task­Dialog in case there's another bug here.

With a little bit of psychic powers, you can solve this customer's problem too.

(If you have a good memory, you may have noticed that it's a variation on a previous puzzle. But I get to keep recycling it because every year, a new batch of developers stumbles across the problem.)

Comments (9)
  1. Anthony Wieser says:

    I don't want to spoil the party with the answer, but looking back on the variation you link to, it's interesting to see that when you click on "the answer is revealed" you get sent to a different page.

    So, here's a new way to get link publicity:  Get Raymond to link to your blog, then when he's not looking, redirect it to what you're trying to sell!

  2. dalek says:

    @Anthony Wieser:

    It seems Adrian McCarthy (the one with the question and the answer for the previous puzzle) had some problems with his blog (not only with his blog :)). Since this post was probably in the queue for a while, the link presumably did work when it was entered. Unfortunatly the wayback machine doesn't seem to have a copy.

  3. Vilx- says:

    I've got only a basic grasp of Win32 programming, but isn't it the same problem? If they couldn't call CreateWindowEx from their WM_CREATE handler (probably because of a bad parent HWND), then why should TaskDialog succeed where they failed? Underneath it still calls the same CreateWindowEx with the same bad parent HWND. And fails.

    The beep though seems to be played before the CreateWindowEx call, so that gets through.

  4. dalek says:

    The were probably trying to use a resource that doesn't exist anymore.

  5. Wizou says:

    Calling TaskDialog with a parent HWND that is invalid..

  6. JonPotter says:

    Or is it that there's no message loop left to drive the TaskDialog, because the program is on the way to exiting?

  7. 640k says:

    This is why you should use MessageBox and NOT TaskDialog.

  8. Miral says:

    @640k: No, the only reason to use MessageBox over TaskDialog is if you still want your app to run on XP or below and you're too lazy to write code that will work properly in both cases.

    MessageBox would have the same problem: invalid parent window handle.

  9. Worf says:

    MessageBOX doesn't need a parent HWND – NULL works just fine.

    It happens when quitting is the problem I'm guessing. PostQuitMessage is not a wrapper around PostMessage(WM_QUIT, …), as nothing generates WM_QUIT. Instead, it sets a flag inside the message queue that causes all sorts of things to happen. One of those is that WM_QUIT is returned on an empty message queue. So right after the window is created and the message loop continues, you get WM_QUIT.

    Spoiler Raymond Post


    At least, that's what I'm guessing based on Raymond's reference.

Comments are closed.