WPARAM and LPARAM parameters
When sending messages, WPARAM
and LPARAM
parameters have specific interpretations depending on the message. You need to pass those parameters in the way that the message that you are sending expects them to be passed. If you are defining your own message (perhaps via an offset from WM_USER
, WM_APP
, or RegisterWindowMessage
), then you obviously have a bit more latitude.
In the days of 16-bit Windows, a WPARAM
was a 16-bit word, while LPARAM
was a 32-bit long. These distinctions went away in Win32; they both became 32-bit values.
According to this, LPARAM
is defined as LONG_PTR
, which in 64-bit Windows is a signed, 64-bit value. WPARAM
is defined as UINT_PTR
, which in 64-bit Windows is an unsigned, 64-bit value. If you are defining your own message, you might want to assign its parameters accordingly.
╔════════════════╦══════════════════╦═══════════════╗
║ ║ WPARAM ║ LPARAM ║
║ ╟──────────────────╫───────────────╢
║ OS ║ handles, numbers ║ pointers ║
╠════════════════╬══════════════════╬═══════════════╣
║ 16-bit Windows ║ 16-bit unsigned ║ 32-bit signed ║
║ 32-bit Windows ║ 32-bit unsigned ║ 32-bit signed ║
║ 64-bit Windows ║ 64-bit unsigned ║ 64-bit signed ║
╚════════════════╩══════════════════╩═══════════════╝
The history of its definition has changed over the years.
WINDOWS.H (Windows 2.03 SDK, c. 1988)
/* Message structure */
typedef struct tagMSG {
HWND hwnd;
WORD message;
WORD wParam;
LONG lParam;
DWORD time;
POINT pt;
} MSG;
WinDefs.h (c. 1999)
/* Types use for passing & returning polymorphic values */
typedef UINT WPARAM;
typedef LONG LPARAM;
typedef LONG LRESULT;
WinDef.h (c. 2005)
/* Types use for passing & returning polymorphic values */
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
typedef LONG_PTR LRESULT;
Bonus Reading
- What do the letters W and L stand for in WPARAM and LPARAM? archive(
W
is for unsigned 16-bitWORD
, andL
is for signed 32-bitLONG
) - What happens to WPARAM, LPARAM, and LRESULT when they travel between 32-bit and 64-bit windows? archive(the unsigned is zero-extended, the signed is sign-extended)