Win32 API C ++, идентификатор не получен с WM_COMMAND

Я довольно новый программист Win32 API C ++.

Я только что научился создавать меню и прикреплять к ним экземпляры Window. У меня проблема в том, что мои идентификаторы 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) - оператор переключения сообщений:

...

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;
        }

...

person Community    schedule 07.12.2013    source источник
comment
Вероятно, для краткости стоит удалить из сообщения все сообщения, не относящиеся к меню, в дополнение к демонстрации того, как вы прикрепляете меню к окну. Мне кажется, что код, который вы опубликовали, мне подходит. Возможно, проблема в том, как прикреплено меню.   -  person enhzflep    schedule 07.12.2013


Ответы (1)


Если вы ознакомитесь с документацией WM_COMMAND вы обнаружите, что идентификатор команды составляет 16 бит.

2 ^ 16 = 65536, если не изменяет память.

Таким образом, значение, скажем, 101000, слишком велико.


Кстати, обычно рекомендуется использовать макросы взломщика сообщений из <windowsx.h>, например HANDLE_WM_COMMAND.

Кроме того, для WM_COMMAND обязательно проверьте, является ли это уведомлением дочернего окна или реальным выбором меню.

person Cheers and hth. - Alf    schedule 07.12.2013
comment
Незначительная придирка: идентификаторы находятся в диапазоне от 0 до 65535 (65536 не влезает в 16 бит). Однако это не меняет достоверности анализа. - person IInspectable; 07.12.2013
comment
@IInspectable: Мэр придурок: Альф никогда не говорил, что 65536 - это действительное удостоверение личности. Он сказал, что идентификатор равен 16 битам (правда) и что 2 ^ 16 = 65536 (тоже верно). Однако это не меняет действительности вашей придирки ;-). - person rodrigo; 08.12.2013