windowswinapiwin32gui

How to Create Win32 API Menu Items with Icons?


I am trying to add an icon to a menu item in a Windows application using the Win32 API, but the icon is not showing up. I have followed the instructions from the Win32 API documentation, but it's still not working. Can anyone help me fix this issue?

HMENU createContextMenu(HWND hwnd, HINSTANCE hInstance) {
    HMENU hMenu = CreatePopupMenu();
    if (hMenu) {
        AppendMenu(hMenu, MF_STRING, IDM_APP_ABOUT, "&About");
        AppendMenu(hMenu, MF_SEPARATOR, (UINT_PTR)-1, NULL);
        AppendMenu(hMenu, MF_STRING, IDM_APP_EXIT, "&Exit");

        // Assuming you have an icon resource named ICON_MENU_EXIT
        HICON hIconExit = LoadIcon(hInstance, MAKEINTRESOURCE(ICON_MENU_EXIT));
        if (hIconExit) {
            MENUITEMINFO menuItemInfo = { sizeof(MENUITEMINFO) };
            menuItemInfo.fMask = MIIM_BITMAP;
            menuItemInfo.hbmpItem = (HBITMAP)CopyImage(hIconExit, IMAGE_ICON, 0, 0, LR_COPYFROMRESOURCE);
            SetMenuItemInfo(hMenu, IDM_APP_EXIT, FALSE, &menuItemInfo);
            DestroyIcon(hIconExit); // Destroy the icon only if setting the image was successful
        }
    }
    return hMenu;
}
case WM_USER_TRAYICON:
        if (lParam == WM_LBUTTONDBLCLK) {
            ShowWindow(hwnd, SW_SHOW);
        } else if (lParam == WM_RBUTTONUP) {
            POINT trayPos;
            GetCursorPos(&trayPos);
            HMENU hMenu = createContextMenu(hwnd,hInstance);
            SetForegroundWindow(hwnd); // Menjamin menu bekerja dengan benar
            UINT clicked = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_NONOTIFY, trayPos.x, trayPos.y, 0, hwnd, NULL);
            if (clicked == IDM_APP_EXIT) {
                PostQuitMessage(0);
            }
            DestroyMenu(hMenu); // Hancurkan menu setelah digunakan
        }
        break;

I have tried to load the icon from a resource using LoadIcon function and set it to the menu item using SetMenuItemInfo or SetMenuItemBitmaps.
I expected the icon to appear next to the menu item 'Exit' when the menu is displayed.
However, despite following the steps outlined in the Win32 API documentation, the icon is still not showing up.


Solution

  • An HICON and an HBITMAP are completely different types. You can't use HICON directly with SetMenuItemInfo() or SetMenuItemBitmaps().

    You will have to either:

    1. change your resource type to BITMAP, and then use LoadBitmap() or LoadImage(IMAGE_BITMAP) to load it as an HBITMAP.

    2. stay with an ICON resource, load it as an HICON as you are, and then either:

      a. copy it to a separate HBITMAP that you can then assign to your menu item. See How to convert HICON to HBITMAP in VC++?

      b. Owner-draw the menu item, handling the WM_DRAWITEM message, so you can draw your HICON onto the HDC of the menu using DrawIcon().