Okay, I am trying to learn Windows programming and there are all sorts of new data types that I am running into and need to learn. I'm trying to understand the point of it all and failing. If there is no point and it's just Microsoft making things difficult for no reason, well I guess that's life and I'll just deal with it. But if there IS a point to these types, I'd like to understand.
For example, pretty much anything starting with a P is a pointer to something, so PINT8
is the same as INT8*
, PINT16
is the same as INT16*
, PUCHAR
is the same as UCHAR*
, etc. Also, everything seems to be capitalized for some reason. int is the same as INT, char is the same as CHAR, long is LONG.
Now there is something called a "handle", which is new to me, which is a void*
or PVOID
. There are a whole bunch of "handles". Regular old "Handle" appears to be a handle to an "Object". Then you get more specific. A handle to a brush is an HBRUSH, and handle to a bitmap is an HBITMAP, a handle to a cursor is an HCURSOR, etc.
However, looking at the typedefs, almost all the handles appear to typedef to HANDLE, which is PVOID, which is void*
. HFILE is an exception. It's an int, so not a pointer at all.
There's also something called LPARAM, which is typedefed to be equivalent to LONG_PTR. I'm seeing types like LPLONG, which is defined as long*
. And I'm seeing PLONG which is also a pointer to a long, or long*
. So LPLONG and PLONG are equivalent? So why have both?
There is also a PHANDLE, which is a pointer to a HANDLE, so if a HANDLE is a void*
, then PHANDLE must be a void**
?
My source is this link. In the comments section, someone opined that some of the "Handle" stuff is obsolete. I've also heard that "handles" are not to be thought of as normal C++ pointers, but are rather things that are not to be dereferenced or used with pointer arithmetic, etc. Thus even though HANDLE is defined as a PVOID, you use PVOID if you're doing the regular C++ stuff and need a void*
pointer (i.e. malloc), but not HANDLE, even though it's defined as the same thing.
It's all quite confusing to me. They have all these typedefs that end up being defined as the same thing, so I'm wondering why bother having them. Clearly it's for the humans READING the code, so I'm wondering whether we're supposed to start writing code like this...
PINT a = new INT[10];
instead of
int* a = new int[10];
which seems rather silly as the former is now completely un-portable for no obvious reason. Just want to know if there is a method to this madness. This "handle" stuff is supposed to make things easier to understand, but it's having the opposite effect.