What’s the difference between the wParam of the WM_NOTIFY message and the idFrom in the NMHDR structure?

The WM_NOTIFY message takes the following parameters:

  • wParam = identifier of the control sending the message
  • lParam = pointer to a NMHDR structure
    • hwndFrom = handle of the control sending the message
    • idFrom = identifier of the control sending the message
    • code = notification code
    • other fields depending on the notification code

Notice that the identifier of the control sending the message appears in two places, once in the wParam and again in the idFrom. What's the difference?

There is no difference. It's just a convenience. The same value is passed in both places, and you can check whichever one is easier for you. You might use the wParam because it avoids having to dereference a pointer. You might use the NMHDR because that way you have only one thing to pass to your On­Notify helper function.

Whatever floats your boat.

Passing the same information multiple ways is hardly new. The WM_COMMAND message also passes redundant information: The control identifier is passed in the low word of the wParam, and you can also get it by calling Get­Dlg­Ctrl­ID on the window handle passed in the lParam.

Comments (13)
  1. SI says:

    Its mentioned in the comments to the WM_NOTIFY MSDN page, but the example given passes the hwnd of the control as wParam and not the ID. ( msdn.microsoft.com/…/bb775583%28v=vs.85%29.aspx )

  2. Joker_vD says:

    What if those two values happen to be different?

    [What if the two values in WM_COMMAND happen to be different? -Raymond]
  3. formlesstree4 says:

    @Joker_vD: Then perhaps you've got bigger problems on your hands.

  4. Crescens2k says:

    I have a question about this.

    The documentation for WM_NOTIFY has

    "The identifier of the common control sending the message. This identifier is not guaranteed to be unique. An application should use the hwndFrom or idFrom member of the NMHDR structure (passed as the lParam parameter) to identify the control."

    for wParam.

    To me, this implies that it is possible for wParam and lParam->idFrom to be different, this contradicts what you wrote in this post. Could you please clarify this?

    [The documentation is saying, "It is legal for two different windows to have the same ID, so the wParam may be ambiguous. If you have multiple windows with the same ID, you should use hwndFrom to distinguish them." I don't know why it's talking about idFrom, since that suffers from the same problem as wParam. -Raymond]
  5. Crescens2k says:

    Right, that clarifies everything. Thank you.

  6. Scarlet Manuka says:

    I would suggest that you do one of two things:

    (a) Fix your program so that it doesn't send broken messages, or

    (b) Work out which other program is sending broken messages, and take appropriate action, possibly of a violent nature.

  7. Joker_vD says:

    [What if the two values in WM_COMMAND happen to be different? -Raymond]

    Ummm… that's what *I* was asking? What do I do if I receive a message that says "I came from window HANDLE#2718, and it reports that it, window HANDLE#9001, processed a character key"? Do I just panic and call ExitProcess(), or pick one of those handles arbitrarily or something else?

  8. alegr1 says:

    One could send these messages from their own code, and put inconsistent values in them, accidentally or intentionally. But then it's your own program that has to process these messages, and it's up to you how to proceed.

    You can have two buttons with the same ID. HWND allows you to distinguish between them.

  9. Joker_vD says:

    "But then it's your own program that has to process these messages"

    Huh? Do you imply I can't send messages across processes?

  10. alegr1 says:

    >Huh? Do you imply I can't send messages across processes?

    If you think you need send WM_COMMAND across processes, you want to seek therapy.

    And for obvious reasons, you CANNOT send WM_NOTIFY across processes. See blogs.msdn.com/…/9877791.aspx, if the reason is not obvious to you.

  11. Jonathan says:

    Having something in 2 places (in this case, 2 vars in the API) always causes confusion:

    * Should I check if they're really the same? What if not? Assert?

    * Which one should I use?

    * Why are there 2?

    The best solution would be, of course, to write everything exactly once. Of course, now that the API is public, you can't break it.

  12. 640k says:

    WM_NOTIFY can easily be injected in other processes to fake messages for different, known, windows controls.

    [Not sure what your point is. "WM_ANYTHING can easily be injected into other processes to fake messages for ANYTHING." Why pick on WM_NOTIFY? -Raymond]
  13. Rick C says:

    Raymond, perhaps 640k was disagreeing with alegr1, possibly for the sake of being disagreeable.

Comments are closed.

Skip to main content