What do LRESULT, WPARAM and LPARAM mean?
LPARAM is a typedef for LONG_PTR which is a long (signed 32-bit) on win32 and __int64 (signed 64-bit) on x86_64.
WPARAM is a typedef for UINT_PTR which is an unsigned int (unsigned 32-bit) on win32 and unsigned __int64 (unsigned 64-bit) on x86_64.
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
In c# You can Use IntPtr
See What are the definitions for LPARAM and WPARAM?
That's an example for hungarian notation:
L
in bothLPARAM
andLRESULT
means "long", designating a 32-bitint
w
inWPARAM
means "word" (which used to be 16-bitint
but is now also a 32 bitint
— at least when targeting a 32-bit architecture)
The remainder of the type names / aliases is supposed to hint at their meaning, i.e. LRESULT
containing some kind of result value, LPARAM
and WPARAM
being used for parameter variables.
The actual meaning of the wParam
and lParam
parameters' content depends on the particular message being sent; they are just generic buckets for message parameters. So it's quite likely that you won't be able to circumvent unsafe type casts.
That names came from historical reasons. In the age of WIndows16 bit WPARAM meant Word-Parameter and LPARAM Long-Parameter in an Hungarian Notation sort-of. moving to 32 bit collapsed both to the same size (32bit integers) but left the names unchanged. LRESULT meant long result, and, again name is kept for historical reasons. Another change happen when windows64 bit came out. Please have a look here in MSDN to have a complete list. In details: both LPARAM and LRESULT are a typedef for LONG_PTR, where LONG_PTR is:
#if defined(_WIN64)
typedef __int64 LONG_PTR;
#else
typedef long LONG_PTR;
#endif
WPARAM is a typedef for UINT_PTR, where UINT_PTR is:
#if defined(_WIN64)
typedef unsigned __int64 UINT_PTR;
#else
typedef unsigned int UINT_PTR;
#endif
You can see basically the types eventually pointing to the same size bits: the only real difference is if you are using windows 32 or 64. In term of usage meaning, they are general pourpose parameters you can use depending on what the window procedure needs to do. Typically, since a couple of number is not enought, poiter to complex data structures are used and their values passed as WPARAM or LPARAM, so you cannot assign any particular meaning unless you focalize a context.
That's Charles Simonyi, the former head of the Application Software group at Microsoft, the group that developed Word and Excel. He's the one that set identifier naming standards. Since nobody knows how to pronounce his last name, they picked the country he was born in and called it Hungarian notation. The Windows group adopted it as well, but picked the "bad" kind, System Hungarian. Where the first letter(s) of the identifier is chosen to note the type of the variable. As opposed to the "good" kind, Apps Hungarian, which selects the prefix by the logical type name instead of the physical type name. Simonyi's version.
So it is L as in Long, W as in Word. LPCWSTR is a doozy like that, Long Pointer to Constant Wide String. A clear problem with System Hungarian is that it doesn't work so well anymore when the architecture changes. Originally picked for 16-bit operating systems (L=32-bits, W=16-bits), migrated to 32-bit without changing the name (W=32-bits), we're at 64-bit today (L=W=64-bits).
So ignore these prefixes, they're just an historical accident. You really must pick IntPtr for the LRESULT type, it certainly can be a 64-bit value on the 64-bit version of Windows. Very hard to diagnose problems occur when you don't, a common question here.
Off topic, the fuzzy image you see in the background of the photograph is an interesting tidbit about Simonyi as well. Microsoft shared its great success with its employees and turned many of them into multi-millionaires. What you see in the background is a shot of the space shuttle docked to the International Space Station. Simonyi is one of the seven "space tourists" and bought himself a ticket to ISS. The only one to do so twice, set him back $60 million :)