Как идентифицировать меню AppendMenu MF_POPUP в WindowProcedure?

Я путаюсь.

MF_POPUP
0x00000010L

Указывает, что элемент меню открывает раскрывающееся меню или подменю. uIDNewItem параметр указывает дескриптор раскрывающегося меню или подменю. Этот флаг используется для добавления имени меню в строку меню или меню. элемент, который открывает подменю в раскрывающемся меню, подменю или ярлыке меню.

(https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-appendmenua)

Да, но как нам теперь указать uID Меню и обратиться к нему в WindowProcedure,
если параметр uIDNewItem теперь является дескриптором раскрывающегося меню или подменю.

Всплывающее меню обрабатывается системой за вас. Ваша оконная процедура должна быть задействована. Когда пользователь выбирает пункт меню из всплывающего меню, оконная процедура получает соответствующее сообщение WM_COMMAND.

IInspectable 14.12.2020 12:24

Вы не будете получать сообщения WM_COMMAND для пункта меню MF_POPUP, поэтому вам не нужно искать идентификатор. Однако вместо этого вы можете получать сообщения WM_MENUCOMMAND и WM_MENUCHAR, что даст вам HMENU подменю.

Remy Lebeau 14.12.2020 20:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
357
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это простой пример кода, на который вы можете ссылаться,

#include <Windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;

#define EXIT_ID 1
#define SUB_ID 2

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message)
    {
    case WM_CREATE:
    {
        HMENU hMenubar = CreateMenu();
        HMENU hFileMenu = CreateMenu(); //file is a regular menu.. Exit is a regular sub-menu..
        HMENU hDisplayMenu = CreatePopupMenu(); //display is a popup-menu because it has children.

        AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFileMenu, "File");
        AppendMenu(hFileMenu, MF_STRING | MF_POPUP, (UINT_PTR)hDisplayMenu, "Display"); 
        AppendMenu(hDisplayMenu, MF_STRING, SUB_ID, "Sub");
        AppendMenu(hFileMenu, MF_STRING, EXIT_ID, "Exit"); 
        SetMenu(hwnd, hMenubar);
    }
    break;
    case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case SUB_ID:
            MessageBox(hwnd, "You click Sub menu", " ", MB_OK);
            break;
        case EXIT_ID:
            DestroyWindow(hwnd);
            break;
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
        }
    }
    break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        // TODO: Add any drawing code that uses hdc here...
        EndPaint(hwnd, &ps);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;   
};

HINSTANCE hinst;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
    HWND hwnd;

    hinst = GetModuleHandle(NULL);
    // create a window class:
    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hinst;
    wc.lpszClassName = "win32";

    // register class with operating system:
    RegisterClass(&wc);
    // create and show window:
    hwnd = CreateWindow("win32", "My program", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 0, 0, 1000, 800, NULL, NULL, hinst, NULL);
    if (hwnd == NULL) {
        return 0;
    }
    ShowWindow(hwnd, SW_SHOW);
    MSG msg = {};

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

}

Отлаживать:

EXIT_ID и SUB_ID — идентификатор подменю. Вам нужно определить их вручную.

#define EXIT_ID 1
#define SUB_ID 2

Обновлено:

Вы можете использовать WM_MENUSELECT, чтобы получить дескриптор меню, по которому щелкнули, и сравнить их меню.

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

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HMENU hMenubar;
    switch (message)
    {
    case WM_CREATE:
    {
        hMenubar = CreateMenu();
        HMENU hFileMenu = CreateMenu(); //file is a regular menu.. Exit is a regular sub-menu..        
        
        AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFileMenu, L"File");
        SetMenu(hWnd, hMenubar);
    }
    break;
    case WM_MENUSELECT:
    {
        HMENU hmenu = (HMENU)lParam;     
        if (hmenu == hMenubar)
        {
            MessageBox(hWnd, L"You click main menu", L" ", MB_OK);
        }
  
    }
    break;
    ...

Так,

Вопрос в основном касается самого меню «Файл»: как мы можем обрабатывать и реагировать на нажатие кнопки меню «Файл», точно так же, как пункты меню и подменю в вашем примере.

user3789797 15.12.2020 08:51

@user3789797 user3789797 Извините, я неправильно понимаю, что вы имеете в виду. Как сказано в документе, если для параметра uFlags установлено значение MF_POPUP, дескриптор раскрывающегося меню или подменю. Другими словами, вы не можете установить UID отдельно в стиле MF_POPUP. Я хочу знать, почему вам нужно отдельно обрабатывать нажатие кнопки FILE.

Strive Sun 15.12.2020 09:19

Это больше личное упражнение на последовательность в дизайне программирования win32. Чтобы иметь ответ под поясом, если когда-нибудь понадобится. Это действительно не здорово и не полезно иметь вопросы без ответов в затылке. Хотя это может помочь с некоторыми идеями в будущем, такими как лучшая поддержка Drag N Drop в некоторых приложениях или уникальный пользовательский интерфейс, который более очевиден. Обработка зависания и временного вспомогательного всплывающего окна - также может использоваться с этим видом обработки меню. Вкратце: множество применений, которые могут быть практичными и действительно полезными.

user3789797 15.12.2020 09:48

Другие вопросы по теме