【问题标题】:Win32 API C++, Identifier not Received with WM_COMMANDWin32 API C++,未使用 WM_COMMAND 接收标识符
【发布时间】:2013-12-07 13:57:25
【问题描述】:

我是一个相当新的 Win32 API C++ 程序员。

我刚刚学会了如何创建菜单并附加它们 Window 实例。 我遇到的问题是,我的 MenuItem 标识符似乎没有发送。

例如: 我的菜单项 File>>Exit 应该在 WM_COMMAND 中发送标识符 ID_FILE_EXIT。 但是在某个地方,我的 MSG 开关没有收到该标识符;即我的菜单项不起作用。

资源.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 语句:

...

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

...

【问题讨论】:

  • 为了简洁起见,可能值得从您的帖子中删除所有非菜单消息案例,除了显示您如何将菜单附加到窗口。到目前为止,您发布的代码对我来说似乎很好。可能是菜单的附加方式有问题。

标签: c++ winapi menuitem identifier wm-command


【解决方案1】:

如果您查看the documention of WM_COMMAND,您会发现命令 id 是 16 位。

2^16 = 65536,如果没记错的话。

因此,例如 101000 的值有点太大了。


顺便说一句,使用&lt;windowsx.h&gt; 中的“消息破解器”宏通常是个好主意,例如HANDLE_WM_COMMAND

另外,对于WM_COMMAND,一定要检查它是子窗口通知还是真正的菜单选择。

【讨论】:

  • 次要吹毛求疵:ID 在 0 到 65535 的范围内(65536 不适合 16 位)。不过,这不会改变分析的有效性。
  • @IInspectable:挑剔市长:Alf 从未说过 65536 是有效 ID。他说 ID 是 16 位(真)并且 2^16=65536(也是真的)。不过,这不会改变您挑剔的有效性;-)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多