WPARAM and LPARAM parameters

56,607

Solution 1

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.

Solution 2

╔════════════════╦══════════════════╦═══════════════╗
║                ║ 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

Solution 3

It's message-specific. You can use this list of system-defined message categories as reference. Select a group, then a message from the group to see what the message specifies you should pass as WPARAM/LPARAM.

Raymond Chen explains why we have two params.

Solution 4

Yes, the order matters. WPARAM sent/posted in one side winds up WPARAM on the other end; likewise for LPARAM.

If you have your own custom messages you can use WPARAM and LPARAM for anything you want. (There may be some common conventions though.)

Solution 5

Yes, it does. I once passed them in swapped order and the function I call fails. Nevertheless, you should consult MSDN when in doubt. I never program in Win64 though, so I don't whether there are differences between Win32 and Win64 regarding WPARAM/LPARAM behavior.

Share:
56,607
Adrian
Author by

Adrian

Updated on August 07, 2021

Comments

  • Adrian
    Adrian almost 3 years

    When passing a value to a function that takes both a WPARAM and a LPARAM parameter, does it matter on which of them I pass it? Someone told me that if I use Windows x64 I should use WPARAM; is this true?

  • Ivandro Jao
    Ivandro Jao over 7 years
    Thanks, really helped :)
  • daramarak
    daramarak over 6 years
    Unless I am misreading your table there, you say that an LPARAM cannot hold a pointer in 64-bit windows, is that correct?
  • mistertodd
    mistertodd over 6 years
    @daramarak I must have gotten that wrong. I swore at the time that it was the case. I remember thinking that 64-bit was like 16-bit world - where there's a size difference between WPARAM and LPARAM. But i'm going back through header files and i cannot for the life of me find it now. So i guess i was crazy.