When is a window visible yet not visible?


Today, a quick puzzler.

Consider the following code fragment:

 ShowWindow(hwnd, SW_SHOWNORMAL);
 assert(IsWindowVisible(hwnd));

We just showed the window, certainly it is visible, right? Yet the assertion can fire (even in the absence of multi-threading). Why?

Answer below - stop reading if you want to try to solve it yourself.

Take a look at the IsWindowVisible function.

If the specified window, its parent window, its parent's parent window, and so forth, have the WS_VISIBLE style, the return value is nonzero. Otherwise, the return value is zero.

The WS_VISIBLE style indicates that this window is visible in its parent. But the parent itself might not be visible, in which case IsWindowVisible returns FALSE.

[Raymond is currently on vacation; this message was pre-recorded.]

Comments (6)
  1. Anonymous says:

    Yeah, I was trapped by this once. The design makes sense, but the function name is definitely misleading. And it’s so easy to use (you’d think) that you’ll never want to read its documentation.

    //

  2. J. Edward Sanchez says:

    It’s not the name of the IsWindowVisible() function that’s misleading; if anything, it’s the name of the WS_VISIBLE style bit.

    Maybe it should’ve been called WS_NOTEXPLICITLYHIDDEN, or something equally cumbersome. Then again, maybe not.

    A small improvement to that would be to reverse the logic of the flag and call it WS_EXPLICITLYHIDDEN.

  3. Anonymous says:

    WS_HIDE works.

    Maybe IsWindowVisible should have two arguments — one a boolean controlling this behavior. Everyone pays attention to the arguments.

  4. J. Edward Sanchez says:

    Calling it WS_HIDE would have the same problem as calling it WS_VISIBLE: Not having the WS_HIDE bit set might imply to some people that the window is visible, when it actually might be hidden due to its parent having WS_HIDE set.

    Adding a second parameter to IsWindowVisible() is a much better idea. While we’re at it, we might as well add the ability to determine if a window is completely obscured by other windows, or offscreen, or visible on a specific monitor. Hey, sounds like a job for IsWindowVisibleEx().

  5. Anonymous says:

    Alternative answer: When it’s offscreen, or overlapped by another window. Sure, it’s visible to according to the OS, but the user wouldn’t agree!

  6. Anonymous says:

    Maybe a window’s DC’s clip rect will be empty if it’s completely obscured or offscreen?

Comments are closed.