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. Chango V. 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. Spire 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. cola says:

    WS_HIDE works.

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

  4. Spire 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. kalleboo 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. Neil says:

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

Comments are closed.