Using Menu Resources

I've been slowly working my way through the winforgers tutorial and I think I somewhat understand how to create and use menu resources when the program runs (ie part two of the menu tutorial) but I still can't make part 1 of the menu tutorial actually do anything.

Here is the code so you can see what I'm talking about. I couldn't find a way to spoiler the code. Sorry for its length.

Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <windows.h>
#include <iostream>
#include "resource.h"
const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_LBUTTONDOWN:
        {
            char szFileName[MAX_PATH];
            HINSTANCE hInstance = GetModuleHandle(NULL);

            std::cout << "Button Was Clicked\n\n";

            GetModuleFileName(hInstance, szFileName, MAX_PATH);
            MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_HELP | MB_ICONASTERISK);
        }
        break;
        case WM_CLOSE:
        {
            DestroyWindow(hwnd);
        }
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MYMENU);
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0);


    if(!RegisterClassEx(&wc))
        {
            MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }

    // Step 2: Creating the Window

    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE, //extended windows style
        g_szClassName, //class name of window
        "The title of my window", //the title of the window
        WS_OVERLAPPEDWINDOW, //windows style parameter
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, //default position of the window x, y starting from top left / size of the window x, y
        NULL, NULL, hInstance, NULL); //settings for child windows / buttons

    if(hwnd == NULL)
        {
            MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
    return Msg.wParam;
}


resource.h
1
2
3
4
5
#define IDR_MYMENU 101
#define IDI_MYICON 201

#define ID_FILE_EXIT 9001
#define ID_STUFF_GO 9002 


resource.rc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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

IDI_MYICON ICON "menu_one.ico"


Now, I tried adding a couple of cases to deal with the ID_FILE_EXIT and ID_STUFF_GO to the windows procedure but nothing happens when I select those menu options.

Code I added looked like this

1
2
3
4
5
6
7
8
9
10
        case ID_FILE_EXIT:
        {
            PostMessage(hwnd, WM_CLOSE, 0, 0);//I also tried PostQuitMessage(0);
        }
        break;
        case ID_STUFF_GO:
        {
            std::cout << "Going\n";
        }
        break;


I guess what I'm saying is i'm not quite sure how to use a resource when it's set up this way. Any suggestions for reading or ideas for what I'm doing wrong?
Last edited on
Well, I've managed to make something happen with my menu at least so I think i'm on the right track. Although I'm not sure why this code isn't doing what I want it too.

These are the modifications I've made. I added the switch below to the windows procedure.
I also had to add return DefWindowProc(hwnd, msg, wParam, lParam); to each case because the program would exit as soon as any message got sent to the windows procedure. I think the break; in each case exited out of both the wParam and msg switch and returns 0.

Either way, I still have the same problem though. The menu's still aren't doing what I want them too. If i click the "file > exit" or "stuff > go" options the WM_SYSCOMMAND always switches to the default case which in this setup cout's the wParam value to the console.

I wonder if i need to cast (LOWORD(wParam)) to another data type to make it work correctly.

I'm going to continue reading about this but figured I'd post some progress and maybe somebody would point me the right way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        case WM_SYSCOMMAND:
        switch(LOWORD(wParam))
            {
                case ID_FILE_EXIT:
                {
                    PostMessage(hwnd, WM_CLOSE, 0, 0);
                    return DefWindowProc(hwnd, msg, wParam, lParam);
                }
                break;
                case ID_STUFF_GO:
                {
                    std::cout << "Going\n";
                    return DefWindowProc(hwnd, msg, wParam, lParam);
                }
                break;
                default:
                    std::cout << wParam << "\n";
                    return DefWindowProc(hwnd, msg, wParam, lParam);
                break;
            }
Last edited on
you wan't WM_COMMAND not WM_SYSCOMMAND
Topic archived. No new replies allowed.