Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

windows

winapi

I had a small debate with a fellow programmer. He uses the following idiom in his code:

HWND hWnd = SomeFunctionWhichReturnsAWindow();
if(hWnd != NULL && hWnd != INVALID_HANDLE_VALUE)
{
    // All good
}
else
{
    // Error
}

I told him that in my opinion this is a wrong approach, as the HWND type has nothing to do with the INVALID_HANDLE_VALUE definition, but he's sure that this is good code, as a valid handle can never be equal to INVALID_HANDLE_VALUE, and it's in the mood of "better safe than sorry".

So, is it an acceptable and correct idiom?

like image 681
Paul Avatar asked Oct 10 '14 15:10

Paul


People also ask

How does Hwnd work?

HWND is a special HANDLE which points to a window object. HWND is said to be a pointer to a Window. To get any Window, its Child or Dialog box object, we need to use an HWND object. Communication between two windows is also done using HWND's.

What is Hwnd?

HWND is a "handle to a window" and is part of the Win32 API . HWNDs are essentially pointers (IntPtr) with values that make them (sort of) point to a window-structure data. In general HWNDs are part an example for applying the ADT model. If you want a Control's HWND see Control. Handle property.

What is window handle in C++?

A Windows window is identified by a "window handle" ( HWND ) and is created after the CWnd object is created by a call to the Create member function of class CWnd . The window may be destroyed either by a program call or by a user's action. The window handle is stored in the window object's m_hWnd member variable.


2 Answers

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.

like image 195
David Heffernan Avatar answered Sep 20 '22 15:09

David Heffernan


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.

like image 42
Remy Lebeau Avatar answered Sep 17 '22 15:09

Remy Lebeau