Я довольно новый программист Win32 API C ++.
Я только что узнал, как создавать меню и прикреплять их к окнам.
Проблема в том, что мои идентификаторы MenuItem не отправляются.
Например:
Мой пункт меню File >> Exit должен отправить Идентификатор ID_FILE_EXIT в WM_COMMAND.
Но где-то на линии мой коммутатор MSG не получает этот идентификатор; т.е. мои пункты меню не работают.
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(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;
}
...
Если вы проверите документация WM_COMMAND
Вы обнаружите, что идентификатор команды составляет 16 бит.
2 ^ 16 = 65536, если память не изменяет
Таким образом, значение, скажем, 101000, слишком велико.
Между прочим, это хорошая идея использовать макросы «Message Cracker» из <windowsx.h>
, такие как HANDLE_WM_COMMAND
,
Также для WM_COMMAND
, не забудьте проверить, является ли это уведомлением дочернего окна или реальным выбором меню.
Других решений пока нет …