I'm a fairly new Win32 API C++ programmer.
I've just learned how to create menus and attach them Window instances. The trouble I'm having is, my MenuItem Identifiers don't seem to be sending.
For Example: My menu item File>>Exit is supposed to send the Identifier ID_FILE_EXIT in WM_COMMAND. But somewhere along the line, my MSG switch isn't receiving that identifier; ie my menu items don't work.
resouce.h:
// resources.h
#ifndef RESOURCE_H
#define RESOURCE_H
// Main Window: Menu ID
#define IDR_MAIN_MENU 101
// Main Window: Menu: Command IDs
#define ID_FILE_EXIT 101101
#define ID_PRIMITIVE_LINE 101201
#define ID_PRIMITIVE_RECTANGLE 101202
#define ID_PRIMITIVE_ELLIPSE 101203
#define ID_PENCOLOUR_BLACK 101301
#define ID_PENCOLOUR_WHITE 101302
#define ID_PENCOLOUR_RED 101303
#define ID_PENCOLOUR_GREEN 101304
#define ID_PENCOLOUR_BLUE 101305
#define ID_BRUSHCOLOUR_BLACK 101401
#define ID_BRUSHCOLOUR_WHITE 101402
#define ID_BRUSHCOLOUR_RED 101403
#define ID_BRUSHCOLOUR_GREEN 101404
#define ID_BRUSHCOLOUR_BLUE 101405
#define ID_PENSTYLE_SOLID 101501
#define ID_PENSTYLE_NULL 101502
#define ID_PENSTYLE_DOTTED 101503
#define ID_PENSTYLE_DASHED 101504
#define ID_BRUSHSTYLE_SOLID 101601
#define ID_BRUSHSTYLE_NULL 101602
#define ID_BRUSHSTYLE_DIAGONAL 101603
#define ID_BRUSHSTYLE_CROSS 101604
#endif // RESOURCE_H
resource.rc:
// resouce.rc
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"
IDR_MAIN_MENU MENU
{
popup "File"
{
MENUITEM "Exit", ID_FILE_EXIT
}
popup "Primitive"
{
MENUITEM "Line", ID_PRIMITIVE_LINE
MENUITEM "Rectangle", ID_PRIMITIVE_RECTANGLE
MENUITEM "Ellipse", ID_PRIMITIVE_ELLIPSE
}
popup "Pen Colour"
{
MENUITEM "Black", ID_PENCOLOUR_BLACK
MENUITEM "White", ID_PENCOLOUR_WHITE
MENUITEM "Red", ID_PENCOLOUR_RED
MENUITEM "Green", ID_PENCOLOUR_GREEN
MENUITEM "Blue", ID_PENCOLOUR_BLUE
}
popup "Brush Colour"
{
MENUITEM "Black", ID_BRUSHCOLOUR_BLACK
MENUITEM "White", ID_BRUSHCOLOUR_WHITE
MENUITEM "Red", ID_BRUSHCOLOUR_RED
MENUITEM "Green", ID_BRUSHCOLOUR_GREEN
MENUITEM "Blue", ID_BRUSHCOLOUR_BLUE
}
popup "PenStyle"
{
MENUITEM "Solid", ID_PENSTYLE_SOLID
MENUITEM "Dotted", ID_PENSTYLE_DOTTED
MENUITEM "Dashed", ID_PENSTYLE_DASHED
}
popup "Brush Style"
{
MENUITEM "Solid", ID_BRUSHSTYLE_SOLID
MENUITEM "Null", ID_BRUSHSTYLE_NULL
MENUITEM "Diagonal", ID_BRUSHSTYLE_DIAGONAL
MENUITEM "Cross", ID_BRUSHSTYLE_CROSS
}
}
main.cpp(extract) - msg switch statement:
...
switch(msg)
{
case WM_CREATE:
CheckMenuItem(ghMainMenu, ID_PRIMITIVE_LINE, MF_CHECKED);
CheckMenuItem(ghMainMenu, ID_PENCOLOUR_BLACK, MF_CHECKED);
CheckMenuItem(ghMainMenu, ID_BRUSHCOLOUR_BLACK, MF_CHECKED);
CheckMenuItem(ghMainMenu, ID_PENSTYLE_SOLID, MF_CHECKED);
CheckMenuItem(ghMainMenu, ID_BRUSHSTYLE_SOLID, MF_CHECKED);
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
{
//=====================================
// File Menu
//=====================================
case ID_FILE_EXIT:
DestroyWindow(ghMainWnd);
return 0;
//=====================================
// Primitive Types (Shape Types)
//=====================================
case ID_PRIMITIVE_LINE:
CheckMenuItem(ghMainMenu, ID_PRIMITIVE_LINE, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPrimSel, MF_UNCHECKED);
gCurrPrimSel = ID_PRIMITIVE_LINE;
return 0;
case ID_PRIMITIVE_RECTANGLE:
CheckMenuItem(ghMainMenu, ID_PRIMITIVE_RECTANGLE, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPrimSel, MF_UNCHECKED);
gCurrPrimSel = ID_PRIMITIVE_RECTANGLE;
return 0;
case ID_PRIMITIVE_ELLIPSE:
CheckMenuItem(ghMainMenu, ID_PRIMITIVE_ELLIPSE, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPrimSel, MF_UNCHECKED);
gCurrPrimSel = ID_PRIMITIVE_ELLIPSE;
return 0;
//=====================================
// Pen Colours
//=====================================
case ID_PENCOLOUR_BLACK:
CheckMenuItem(ghMainMenu, ID_PENCOLOUR_BLACK, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPenColSel, MF_UNCHECKED);
gCurrPenColSel = ID_PENCOLOUR_BLACK;
gLogPen.lopnColor = BLACK;
return 0;
case ID_PENCOLOUR_WHITE:
CheckMenuItem(ghMainMenu, ID_PENCOLOUR_WHITE, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPenColSel, MF_UNCHECKED);
gCurrPenColSel = ID_PENCOLOUR_WHITE;
gLogPen.lopnColor = BLACK;
return 0;
case ID_PENCOLOUR_RED:
CheckMenuItem(ghMainMenu, ID_PENCOLOUR_RED, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPenColSel, MF_UNCHECKED);
gCurrPenColSel = ID_PENCOLOUR_RED;
gLogPen.lopnColor = BLACK;
return 0;
case ID_PENCOLOUR_GREEN:
CheckMenuItem(ghMainMenu, ID_PENCOLOUR_GREEN, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPenColSel, MF_UNCHECKED);
gCurrPenColSel = ID_PENCOLOUR_GREEN;
gLogPen.lopnColor = GREEN;
return 0;
case ID_PENCOLOUR_BLUE:
CheckMenuItem(ghMainMenu, ID_PENCOLOUR_BLUE, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPenColSel, MF_UNCHECKED);
gCurrPenColSel = ID_PENCOLOUR_BLUE;
gLogPen.lopnColor = BLUE;
return 0;
//=====================================
// Brush Colours
//=====================================
case ID_BRUSHCOLOUR_BLACK:
CheckMenuItem(ghMainMenu, ID_BRUSHCOLOUR_BLACK, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrBrushColSel, MF_UNCHECKED);
gCurrBrushColSel = ID_BRUSHCOLOUR_BLACK;
gLogBrush.lbColor = BLACK;
return 0;
case ID_BRUSHCOLOUR_WHITE:
CheckMenuItem(ghMainMenu, ID_BRUSHCOLOUR_WHITE, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrBrushColSel, MF_UNCHECKED);
gCurrBrushColSel = ID_BRUSHCOLOUR_WHITE;
gLogBrush.lbColor = WHITE;
return 0;
case ID_BRUSHCOLOUR_RED:
CheckMenuItem(ghMainMenu, ID_BRUSHCOLOUR_RED, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrBrushColSel, MF_UNCHECKED);
gCurrBrushColSel = ID_BRUSHCOLOUR_RED;
gLogBrush.lbColor = RED;
return 0;
case ID_BRUSHCOLOUR_GREEN:
CheckMenuItem(ghMainMenu, ID_BRUSHCOLOUR_GREEN, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrBrushColSel, MF_UNCHECKED);
gCurrBrushColSel = ID_BRUSHCOLOUR_GREEN;
gLogBrush.lbColor = GREEN;
return 0;
case ID_BRUSHCOLOUR_BLUE:
CheckMenuItem(ghMainMenu, ID_BRUSHCOLOUR_BLUE, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrBrushColSel, MF_UNCHECKED);
gCurrBrushColSel = ID_BRUSHCOLOUR_BLUE;
gLogBrush.lbColor = BLUE;
return 0;
//=====================================
// Pen Styles
//=====================================
case ID_PENSTYLE_SOLID:
CheckMenuItem(ghMainMenu, ID_PENSTYLE_SOLID, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPenStyleSel, MF_UNCHECKED);
gCurrPenStyleSel = ID_PENSTYLE_SOLID;
gLogPen.lopnStyle = PS_SOLID;
return 0;
case ID_PENSTYLE_DOTTED:
CheckMenuItem(ghMainMenu, ID_PENSTYLE_DOTTED, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPenStyleSel, MF_UNCHECKED);
gCurrPenStyleSel = ID_PENSTYLE_DOTTED;
gLogPen.lopnStyle = PS_DOT;
return 0;
case ID_PENSTYLE_DASHED:
CheckMenuItem(ghMainMenu, ID_PENSTYLE_DASHED, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrPenStyleSel, MF_UNCHECKED);
gCurrPenStyleSel = ID_PENSTYLE_DASHED;
gLogPen.lopnStyle = PS_DASH;
return 0;
//=====================================
// Brush Styles
//=====================================
case ID_BRUSHSTYLE_SOLID:
CheckMenuItem(ghMainMenu, ID_BRUSHSTYLE_SOLID, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrBrushStyleSel, MF_UNCHECKED);
gCurrBrushStyleSel = ID_BRUSHSTYLE_SOLID;
gLogBrush.lbStyle = BS_SOLID;
return 0;
case ID_BRUSHSTYLE_NULL:
CheckMenuItem(ghMainMenu, ID_BRUSHSTYLE_NULL, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrBrushStyleSel, MF_UNCHECKED);
gCurrBrushStyleSel = ID_BRUSHSTYLE_NULL;
gLogBrush.lbStyle = BS_NULL;
return 0;
case ID_BRUSHSTYLE_DIAGONAL:
CheckMenuItem(ghMainMenu, ID_BRUSHSTYLE_DIAGONAL, MF_CHECKED);
CheckMenuItem(ghMainMenu, gCurrBrushStyleSel, MF_UNCHECKED);
gCurrBrushStyleSel = ID_BRUSHSTYLE_DIAGONAL;
gLogBrush.lbStyle = BS_HATCHED;
gLogBrush.lbHatch = HS_CROSS;
return 0;
}
...
If you check out the documention of WM_COMMAND
you find that the command id is 16 bits.
2^16 = 65536, if memory serves.
Thus, a value of, say, 101000, is a bit too large.
By the way, it's generally a good idea to use the "message cracker" macros from <windowsx.h>
, such as HANDLE_WM_COMMAND
.
Also, for WM_COMMAND
, be sure to check whether it's a child window notification or a real menu selection.