Is it a mistake to check a `HWND` against `INVALID_HANDLE_VALUE`?

CreateWindowEx and the similar functions that return a HWND clearly state that an invalid HWND is 0. Anything other might be valid.

Therefore, checking for INVALID_HANDLE_VALUE is 100% wrong, no matter what you might assume.

Making assumptions such as "this will probably never hurt" are very much dangerous and, although at this time valid, in the future you may be used to assume similar features that are not that innocent.


INVALID_HANDLE_VALUE is defined as -1. An invalid HWND is defined as 0. No API will ever return HWND(-1) on failure, so checking for INVALID_HANDLE_VALUE is meaningless, it will never happen.

However, there are some APIs that accept reserved non-zero HWND values as input, and thus cannot be used as valid HWND return values, either:

PeekMessage() and GetMessage():

If hWnd is NULL, (Peek/Get)Message retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed.

If hWnd is -1, (Peek/Get)Message retrieves only messages on the current thread's message queue whose hwnd value is NULL, that is, thread messages as posted by PostMessage (when the hWnd parameter is NULL) or PostThreadMessage.

So there is a logical difference between HWND(0) and HWND(-1). And in fact, because of that difference, a valid HWND will never be -1 because a message loop would never be able to retrieve messages for it.

Also SetWindowPos() has some reserved values as well:

hWndInsertAfter [in, optional]
Type: HWND

A handle to the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values.

HWND_BOTTOM
(HWND)1
Places the window at the bottom of the Z order. If the hWnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.

HWND_NOTOPMOST
(HWND)-2
Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.

HWND_TOP
(HWND)0
Places the window at the top of the Z order.

HWND_TOPMOST
(HWND)-1
Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated.


It is a mistake to compare an HWND against INVALID_HANDLE_VALUE. Although, in practise this is not a mistake that will hurt you.

The only HWND value reserved by CreateWindowEx as being invalid is NULL. Now, it happens to be an implementation detail that INVALID_HANDLE_VALUE cannot ever be a valid HWND, but that is just implementation detail. The function that yields window handles, CreateWindowEx, uses NULL to indicate failure. That's all you need to know.

If you wish to win your argument with your colleague, I suggest you look inside SomeFunctionWhichReturnsAWindow and find out which Win32 API is called to produce the HWND. Then consult the documentation. That will show you that NULL is the reserved invalid value.

For the sake of clarity you absolutely should change the code to test against NULL alone.

Tags:

Windows

C

Winapi