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?
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.
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.
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.
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.
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: HWNDA 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With