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

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?

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: 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.

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.

HWND can't be used in comparison to INVALID_HANDLE_VALUE as this two are two different things. Most resources, such as a file, etc return HANDLE and must be compared to INVALID_HANDLE_VALUE to ensure the resource is okay for use by any function which depends on it. However, HWND refers to handle for windows GUI objects. So is save to compare HWND values to 0 for invalid return handles rather than using INVALID_HANDLE_VALUE which is also -1.
Furthermore, to more information on the HANDLE type, you can check this StackOverflow previous answers to learn more.
A HANDLE is a context-specific unique identifier. By context-specific,
I mean that a handle obtained from one context cannot necessarily be
used in any other aribtrary context that also works on HANDLEs.
For example, GetModuleHandle returns a unique identifier to a
currently loaded module. The returned handle can be used in other
functions that accept module handles. It cannot be given to functions
that require other types of handles. For example, you couldn't give a
handle returned from GetModuleHandle to HeapDestroy and expect it to
do something sensible.
The HANDLE itself is just an integral type. Usually, but not
necessarily, it is a pointer to some underlying type or memory
location. For example, the HANDLE returned by GetModuleHandle is
actually a pointer to the base virtual memory address of the module.
But there is no rule stating that handles must be pointers. A handle
could also just be a simple integer (which could possibly be used by
some Win32 API as an index into an array).

The question is the windows handle is valid or not, Why not just use IsWindow()?

Related

Why is the windows return code called HRESULT?

The standard return type for functions in Windows C/C++ APIs is called HRESULT.
What does the H mean?
Result handle as stated here at MSDN Error Handling in COM
The documentation only says:
The return value of COM functions and methods is an HRESULT, which is not a handle to an object, but is a 32-bit value with several fields encoded in a single 32-bit ULONG variable.
Which seems to indicate that it stands for "handle", but is misused in this case.
Hex Result.
HRESULT are listed in the form of 0x80070005. They are a number that gets returned by COM\OLE calls to indicate various types of SUCCESS or FAILURE. The code itself is comprised of a bit field structure for those that want to delve into the details.
Details of the bit field structure can be found here at Microsoft Dev Center's topic Structure of COM Error Codes and here at MSDN HRESULT Structure.
The H-prefix in Windows data types generally designates handle types1 (such as HBRUSH or HWND). The documentation seems to be in agreement, sort of:
The HRESULT (for result handle) is a way of returning success, warning, and error values. HRESULTs are really not handles to anything; they are only values with several fields encoded in the value.
In other words: Result handles are really not handles to anything. Clearly, things cannot possibly have been designed to be this confusing. There must be something else going on here.
Luckily, historian Raymond Chen is incessantly conserving this kind of knowledge. In the entry aptly titled Why does HRESULT begin with H when it’s not a handle to anything? he writes:
As I understand it, in the old days it really was a handle to an object that contained rich error information. For example, if the error was a cascade error, it had a link to the previous error. From the result handle, you could extract the full history of the error, from its origination, through all the functions that propagated or transformed it, until it finally reached you.
The document concludes with the following:
The COM team decided that the cost/benefit simply wasn’t worth it, so the HRESULT turned into a simple number. But the name stuck.
In summary: HRESULT values used to be handle types, but aren't handle types any more. The entire information is now encoded in the value itself.
Bonus reading:
Handle types losing their reference semantics over time is not without precedent. What is the difference between HINSTANCE and HMODULE? covers another prominent example.
1 Handle types store values where the actual value isn't meaningful by itself; it serves as a reference to other data that's private to the implementation.

Win32 - A better way to intercept a window before it is created

I am trying to automate an external Windows application. The goal is to make this application start minimized without showing any active window/splash screens and without stealing focus from other applications.
I wrote a little program on C that calls EnumWindows() in a loop and uses ShowWindow() to minimize the required window. It is quite fast and works in 80% of cases. Unfortunately, sometimes the application window is still showing and stealing the focus for a short period of time.
What would be a better (sure) way to intercept the window?
Is using SetWindowsHookEx hooks the only alternative?
Have you tried using the wShowWindow member of the STARTUPINFO structure you pass to CreateProcess() when starting the application? That was designed to do exactly things like this.
If dwFlags specifies STARTF_USESHOWWINDOW, this member can be any of the values that can be specified in the nCmdShow parameter for the ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this member is ignored.
For GUI processes, the first time ShowWindow is called, its nCmdShow parameter is ignored wShowWindow specifies the default value. In subsequent calls to ShowWindow, the wShowWindow member is used if the nCmdShow parameter of ShowWindow is set to SW_SHOWDEFAULT.
For example:
STARTUPINFO si = { sizeof(si) }
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_MINIMIZE;
CreateProcess(..., &si, ...);

Low Level MouseHook not working depending where SetWindowsHookEx is being called

I'm writing a dll in which a function is used to call :
mouseHook = SetWindowsHookEx(
WH_MOUSE_LL,
MouseHookProc,
0, // tried too with (HINSTANCE) inj_hModule, which is hModule from DllMain
0);
When I put this in DllMain, or in the dll's WndProc (the one working with the messages, for instance in case WM_CREATE: or whatever ), it is working OK.
But I need to put it in a separate function, so I can hook when I call it. When I do it, GetLastError says that it succeeded, but the hook isn't working, MouseHookProc is just never called (I put some trace in it to check).
I also tried with other hInstance values for the 3rd parameter, no success either...
Searching for a solution, I read that low level hooks must be set globally, I must confess that I'm not sure to fully understand that as I think it may be the problem, is some regular function not global and wndproc functions global ??? Not sure.
It is quite frustrating as it works ok when I call it at init, if I don't find a solution quickly maybe I'll dispatch some custom message so I can SetWindowsHookEx when I want but it will still be in the wndproc...
Thanks for helping me and Merry Christmas everyone !!!

how to get CREATESTRUCT of a window?

I am trying to make a windows GUI application.
I declared some static variables in my window procedure function and initialized it in the WM_CREATE whose lParam is a pointer to the CREATESTRUCT. However, since these values are static, I can only make one instance of my window; if I make more the previous instances' data will be changed to the new datas.
Is there a way to access the CREATESTRUCT of a window after the WM_CREATE message so that I can solve this problem?
Save a pointer to a user-defined structure in WM_CREATE using either SetWindowLongPtr or SetProp, and retrieve it with the matching functions.
e.g.
case WM_CREATE:
SetWindowLongPtr(hWnd, GWLP_USERDATA, ((LPCREATESTRUCT)lParam)->lpCreateParams);
break;
case <other messages>:
MyData* pData = (MyData*)GetWindowLongPtr(hWnd, GWLP_USERDATA).
Some will argue that you shouldn't use GWLP_USERDATA and instead should reserve storage space in your window class; this is up to you. Using SetProp/GetProp is also a valid alternative.

getting the HWND for my own application in C

since I couldn't find an answer to this question I researched a bit further into the MSDN and I found isChild(). It might give me the answer to that other question.
Now, in order to use isChild() I need to pass the HWND of the parent application that I want to check, in this case my own application.
How do I get the HWND of my own application?
I don't know the title since it changes constantly so I can't use FindWindow().
Thanks
Edit:
Since it's not clear, I'll add more information:
I am not creating a window. I don't have access to the creation of a window. My code is a piece of code that gets compiled together with whatever application the other programmer is coding and I have no access to how the window is created, the title or any other information.
So, how do I get the HWND to the "WINDOW" of the application I am running?
Your application doesn't have a HWND. The window does. An application may have no windows or it may have many, so there is no general function to "Get the application's HWND".
The obvious solution is just to hold on to the handle when you get it. When you create the window, a HWND is returned. Store that.
Use GetTopWindow() and GetNextWindow() to walk through windows z-order.
However, don't think it is necessary, but you can use GetCurrentProcessId() and
GetWindowThreadProcessId(), may be something like following will help you:
HWND FindMyTopMostWindow()
{
DWORD dwProcID = GetCurrentProcessId();
HWND hWnd = GetTopWindow(GetDesktopWindow());
while(hWnd)
{
DWORD dwWndProcID = 0;
GetWindowThreadProcessId(hWnd, &dwWndProcID);
if(dwWndProcID == dwProcID)
return hWnd;
hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
}
return NULL;
}
Can't you just hold onto the handle returned from CreateWindow? If not, why not?
Presumably your code gets called by main application code, otherwise what use is it? In which case I acnnot see why your code's API cannot include some way of informing you of the handle of the application's main window.
As others have already pointed out
In general, an application can have zero or multiple top-level windows.
If you're creating the window yourself you can just remember the HWND somewhere.
But maybe your code is in a DLL, so you didn't actually create the top-level window yourself. So what to do?
I would suggest the following:
Use EnumWindows to enumerate all top-level windows.
Use GetWindowLongPtr to get the HINSTANCE for each top-level window. Compare this against the HINSTANCE of the application, which you can get using GetModuleHandle(NULL). If they're identical, you've found your main window.
Edit: Here is some code. Turns out you also have to use IsWindowVisible because there seem to be quite a few invisible "helper" windows.
HWND hwndMain;
BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam)
{
HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL);
if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst &&
IsWindowVisible(hwnd))
{
hwndMain=hwnd;
return FALSE;
}
else
return TRUE;
}
Then in the place you want to find the window:
hwndMain=NULL;
EnumWindows(EnumWindowProc, 0);
And after this, hwndMain should contain the handle of the window, or NULL if none exists.
Using EnumWindows is a bit burdensome but is recommended over calling GetWindow in a loop because, as MSDN notes: "An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed."
You can inject a DLL in a thread who appeal user32.dll
http://msdn.microsoft.com/en-us/library/ms821625.aspx
This is old for me, but IIRC you should receive the HWND as a parameter in the window proc. You can save it in a global variable somewhere in the beginning.
What about your windows class name?
Is it always different on window creation?
If not you could still you FindWindow().

Resources