c++ mingw-64 winapi MENUITEMINFO добавить иконку

247
13 ноября 2021, 08:10

windows 7, mingw-w64 "g++ (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0"

Привет, учу winapi menus, хочу добавить иконку чекбокса(сняты и не снятый флажок) в меню, при компиляции ошибок не выводится, при запуске появляется системный значок чекбокса, вот код:

#include <windows.h>
#include "resources.h"
HWND            g_hWnd;
HINSTANCE       g_hInst;
void funCreateMenu(HWND hWnd){
    HMENU menu          = CreateMenu();
    HMENU sub_menu      = CreateMenu();
    HBITMAP check   = (HBITMAP)LoadImage(g_hInst, MAKEINTRESOURCE(ID_MENU_OPEN_CHECK), IMAGE_BITMAP, SM_CXMENUCHECK, SM_CYMENUCHECK, 0);
    HBITMAP uncheck = (HBITMAP)LoadImage(g_hInst, MAKEINTRESOURCE(ID_MENU_OPEN_UNCHECK), IMAGE_BITMAP, SM_CXMENUCHECK, SM_CYMENUCHECK, 0);
    MENUITEMINFO mii_menu{0};
        mii_menu.cbSize         = sizeof(MENUITEMINFO);
        mii_menu.fMask          = MIIM_FTYPE | MIIM_STRING | MIIM_ID | MIIM_SUBMENU;
        mii_menu.fType          = MFT_STRING;
        mii_menu.dwTypeData     = L"File"; 
        mii_menu.cch            = sizeof(L"File");
        mii_menu.wID            = 1;
        mii_menu.hSubMenu   = sub_menu;
    MENUITEMINFO mii_submenu{0};
        mii_submenu.cbSize          = sizeof(MENUITEMINFO);
        mii_submenu.fMask           = MIIM_FTYPE | MIIM_STRING | MIIM_ID | MIIM_STATE | MIIM_CHECKMARKS;
        mii_submenu.fType           = MFT_STRING;
        mii_submenu.fState          = MFS_CHECKED;
        mii_submenu.dwTypeData      = L"Open"; 
        mii_submenu.cch             = sizeof(L"Open");
        mii_submenu.wID             = 2;
        mii_submenu.hbmpChecked     = check;
        mii_submenu.hbmpUnchecked   = uncheck;
    InsertMenuItem(menu,    0, FALSE, &mii_menu);
    InsertMenuItem(sub_menu,0, FALSE, &mii_submenu);
    SetMenu(hWnd, menu);
};
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg){
        case WM_CREATE:
            funCreateMenu(hWnd);
        break;
        case WM_DESTROY: 
            PostQuitMessage(0); 
        break;
        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
};
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPI, LPWSTR args, int ncmdshow)
{
    g_hInst = hInst;
    LPCWSTR szAppName{L"AppWindows"}, szAppTitle{L"Первая программа!"};
    WNDCLASSEXW wcex{0};
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = (WNDPROC)WndProc;
        wcex.cbClsExtra  = 0;
        wcex.cbWndExtra  = 0;
        wcex.hInstance = hInst;
        wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
        wcex.lpszMenuName = nullptr;
        wcex.lpszClassName = szAppName;
        wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    if(!RegisterClassEx(&wcex))
        return -1;
    g_hWnd = CreateWindowExW(
        (DWORD)0,
        szAppName,
        szAppTitle, 
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0, 0, 640, 400, 
        nullptr, nullptr, hInst, nullptr);
    MSG msg{0};
    while(GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
};

файл resources.h

#define ID_MENU_OPEN_CHECK      1
#define ID_MENU_OPEN_UNCHECK    2

файл resources.rs

#include "resources.h" 
ID_MENU_OPEN_CHECK      BITMAP  DISCARDABLE     "image/check.bmp"
ID_MENU_OPEN_UNCHECK    BITMAP  DISCARDABLE     "image/uncheck.bmp"

в папке image

выбрал размер 72*72 потому что такое значение вывелось при вызове (std::cout << SM_CXMENUCHECK << " " << SM_CYMENUCHECK << std::endl;), компилю следующим образом

windres -o resources.o resources.rs -lunicode
g++ main.cpp resources.o -o main.exe -mwindows -mconsole -municode -lcomctl32

но мои иконки не хочет выводить, что я делаю не так?

Answer 1

SM_CXMENUCHECK SM_CYMENUCHECK - это идентификаторы для получения соответствующих значений из функции GetSystemMetrics. Причем один из низ 71, а второй 72. Соответственно вызовы LoadImage наверное заканчиваются неудачно, а обработка ошибок у вас отсутствует.

READ ALSO
Как из текста извлечь 4-е первых слова

Как из текста извлечь 4-е первых слова

Как из длинной строки извлечь 4-е первых слова?

168
Как правильно удалить объект из массива JS

Как правильно удалить объект из массива JS

У меня есть Reducer, в который диспатчится action с добавлением объекта,

130
Angular: (click) не работает внутри appendTo()

Angular: (click) не работает внутри appendTo()

У меня есть цикл по добавлению кнопок, при нажатии на кнопку, вызывается функция doActionRibb('color') которая меняет цвет элементовВсе прекрасно работало...

243
Индексаторы в JS

Индексаторы в JS

в C# можно определить индексатор для какого то объекта:

122