Switch cases not executing.

Heya there,

For some reason the variables don't seem to want to change when I click the menu item. Not sure how to get it working.

At the start of my code I declared this...
1
2
3
int r = 0;
int g = 0;
int b = 0;


My resource.h file...
1
2
3
4
5
#define ID_Menu		100
#define ID_Red		0
#define ID_Green	1
#define ID_Blue		2
#define ID_Exit		3 


Resource.rc file...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "resource.h"

// Menu script
ID_Menu MENU DISCARDABLE
{
    POPUP "File"
    {
        MENUITEM "Exit", ID_Exit
    }
    POPUP "Color"
    {
        MENUITEM "Red", ID_Red
        MENUITEM "Green", ID_Green
        MENUITEM "Blue", ID_Blue
    }
}


Here is the WM_COMMAND I have...
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
case WM_COMMAND:
	{
	switch(LOWORD(wParam))
	{
	case ID_Red:
            {
            r = 250;
            g = 0;
            b = 0;
            } break;

        case ID_Green:
            {
            r = 0;
            g = 250;
            b = 0;
            } break;

        case ID_Blue:
            {
            r = 0;
            g = 0;
            b = 250;
            } break;
	}
} break;


Here is the WM_PAINT...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);

TextOut(hdc,10,10,L"Hello World",11);

HBRUSH blueBrush=CreateSolidBrush(RGB(r,g,b));

RECT rct;

rct.left=30;
rct.right=60;
rct.top=30;
rct.bottom=60;

FillRect(hdc, &rct, blueBrush);

EndPaint(hWnd, &ps);
} break;
You need to invalidate your window after changing color, so it's redrawn with the new color. i.e. InvalidateRect()

If you click on a new color and resize your window, to trigger a redraw, you'll see your internals are all working.

Andy
Last edited on
How would I go about doing that? Sorry, I'm quite new to Win32.
Based on your current code

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
case WM_COMMAND:
    {
    bool inval = false;
    switch(LOWORD(wParam))
    {
        case ID_Red:
            {
            r = 250;
            g = 0;
            b = 0;
            inval = true;
            } break;

        case ID_Green:
            {
            r = 0;
            g = 250;
            b = 0;
            inval = true;
            } break;

        case ID_Blue:
            {
            r = 0;
            g = 0;
            b = 250;
            inval = true;
            } break;
    }
    if(inval)
        InvalidateRect(hWnd, NULL, TRUE);
} break;
Last edited on
That doesn't seem to be working.

gives no errors/warnings and a successful compile.
Hmmm...

Well, along with your resource.h and .rc file, the following .cpp works for me (it's your code fragments plus bits nicked from wizard generated boilerplate for window registration and creation and the message loop)

* * * plus a call to delete the brush created in the WM_PAINT handler * * *

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#define WIN32_LEAN_AND_MEAN
// stops windows.h dragging is loads of unwanted stuff
#include <windows.h>
#include "resource.h"

const WCHAR achTitle      [] = L"Example #1";
const WCHAR achWindowClass[] = L"ExampleNumberOne";

int r = 0;
int g = 0;
int b = 0;

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
                   int nCmdShow)
{
    MyRegisterClass(hInstance);

    if(!InitInstance(hInstance, nCmdShow))
    {
        return FALSE;
    }

    MSG msg = {0};
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch(Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_COMMAND:
        {
            bool inval = false;
            switch(LOWORD(wParam))
            {
            case ID_Exit:
                {
                    DestroyWindow(hWnd);
                }
                break;
            case ID_Red:
                {
                r = 250;
                g = 0;
                b = 0;
                inval = true;
                } break;

            case ID_Green:
                {
                r = 0;
                g = 250;
                b = 0;
                inval = true;
                } break;

            case ID_Blue:
                {
                r = 0;
                g = 0;
                b = 250;
                inval = true;
                } break;
            }

            if(inval)
                InvalidateRect(hWnd, NULL, TRUE);
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            TextOut(hdc,10,10,L"Hello World",11);

            HBRUSH blueBrush=CreateSolidBrush(RGB(r,g,b));

            RECT rct;

            rct.left=30;
            rct.right=60;
            rct.top=30;
            rct.bottom=60;

            FillRect(hdc, &rct, blueBrush);

            DeleteObject(blueBrush); // delete brush!

            EndPaint(hWnd, &ps);
        }
        break;
    default:
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    return 0;
}

ATOM
MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex = {0};

    wcex.cbSize        = sizeof(WNDCLASSEX);
    wcex.style         = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc   = WndProcedure;
    wcex.hInstance     = hInstance;
    wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszClassName = achWindowClass;
    wcex.lpszMenuName  = MAKEINTRESOURCE(ID_Menu);

    return RegisterClassEx(&wcex);
}

BOOL
InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd = CreateWindow(achWindowClass,
                             achTitle,
                             WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT,
                             0,
                             CW_USEDEFAULT,
                             0,
                             NULL,
                             NULL,
                             hInstance,
                             NULL);

    if(NULL == hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

Last edited on
Right so I got it to work, simply by replacing the WM_DESTROY command with WM_QUIT.

However when the colours are selected through the menu, it only seems to redraw part of the rectangle as a colour, the rest of it stays black. As I see that the second value of InvalidateRect() should be set to NULL for the whole area, would be it be better to specify the region with RECT()?
Fixed it.

All that needed to be done was remove the bool inval= = false; and also the
1
2
if(inval)
InvalidateRect(hWnd, NULL, TRUE);


The
InvalidateRect()
works fine on its own within the switch.
Okay, new problem but in the same area. When I add an edit box and the focus is on that...the colour of the rectangle turns from black to green. Have no idea why it is doing this.
Anyone that can help me?
#1 PostQuitMessage() should be called in the WM_DESTROY handler and causes a WM_QUIT to be generated which teminates the message loop.

#2 It would be better to specify the area for InvalidateRect, but it should work OK as-is?

#3 The bool was to stop InvalidateRect from being fired with commands other than those from your color menu items.

And...

#4 Set a breakpoint on one of the lines in the switch condition that sets the color to green and check the call stack to see what's sending the message. And what command it is.

Andy

(I also corrected the code I posted from

PostQuitMessage(WM_QUIT);

to

PostQuitMessage(0);

A previous mis-correction...)
Last edited on
Topic archived. No new replies allowed.