If STRICT is not defined, HWND is an alias of void*.
This case, if let's say a HWND type is required as a function parameter, we can easily make a mistake and pass some other handle type (e.g. HBRUSH which is also void*) or any other pointer type.
That leads in run-time errors and program malfunction.
If STRICT is defined, then STRICT type checking is performed.
After preprocessing phase, the above code becomes something like:
typedef struct HWND__ *HWND;
Now, HWND is of type pointer to a structure (HWND__ *) and, if we replace it by mistake with HBRUSH (of type HBRUSH__*) the compiler raises an error, avoiding further run-time troubles. Example
HBRUSH hBrush = ::CreateSolidBrush(RGB(0, 0, 255));
// Stupid but possible mistake
// Error: cannot convert parameter 1 from 'struct HBRUSH__ *' to 'struct HWND__ *'
There is a bunch of other handle types defined in the same manner (HBITMAP, HINSTANCE, etc). See WINDEF.H header file.
In Windows SDK, STRICT is defined by default. If, for some reason you don't want it, you have to add NO_STRICT to preprocessor definitions.
The C standard states the following: if the struct-declaration-list contains no named members, the behavior is undefined, then C compiler from Visual Studio gives an error if we have an empty structure: error C2016: C requires that a struct or union has at least one member.
For this reason, HWND__ and the other similar structures have a dummy member, int unused.