cwinapimenuwm-command

Menus in WinAPI: Do I use LPARAM or WPARAM for WM_COMMAND?


I've recently started teaching myself WinAPI, so bear with me here.

Compiler: TDM-GCC 4.9.2
OS: Windows 8.1 64-bit

I've recently learned how to create menus using resources. In regards to that, I've noticed something odd about handling the WM_COMMAND message for menus. The MSDN documentation tells me that if I want to handle a message sent from a menu, the command item ID can be found in the low word of WPARAM; so I assumed that the code in my window procedure would look like this:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, LPARAM lParam, WPARAM wParam)
{
    switch (msg)
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))  //<--
        {
        case /*IDs go here*/:

            break;
        }
        break;

    //...
    }

    return 0;
}

However, I noticed that the command items in the menu weren't working. After some debugging, I figured out that wParam was always 0 and my IDs were actually in lParam! I made the quick change to the following code:

switch (lParam)
{
case /*IDs go here*/:

    break;
}

And it works!

My question: why?
How come the documentation says it's in wParam when for me it's in lParam?

Also, here are my resource.rc and resource.h files in case it helps:

"resource.h":

#define IDR_MYMENU 101

//These are appearing in LPARAM instead of WPARAM
#define ID_FILE_EXIT 9001
#define ID_STUFF_GO  9002

"resource.rc":

#include "resource.h"

IDR_MYMENU MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit", ID_FILE_EXIT
    END

    POPUP "&Stuff"
    BEGIN
        MENUITEM "&Go", ID_STUFF_GO
        MENUITEM "G&o somewhere else", 0, GRAYED
    END
END



Edit 7/23/15:
SOLVED. My window procedure had the wrong signature. Can't believe it was something so trivial! Thanks, cremno!


Solution

  • The WPARAM and LPARAM parameter are not in the correct order in your code:

    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, LPARAM lParam, WPARAM wParam)
    

    From the WindowProc callback function MSDN documentation:

    LRESULT CALLBACK WindowProc(
      _In_ HWND   hwnd,
      _In_ UINT   uMsg,
      _In_ WPARAM wParam,
      _In_ LPARAM lParam
    );
    

    Just swap them to fix your code:

    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)