Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a custom-drawn skin for an app, that eliminates the caption/title bar. All of the menu items and system buttons are owner-drawn. Everything works as it should, except one little bug.

When the Maximize button is pressed, and the window maximizes, the code should also change the button bitmap, from the "Maximize" icon, to the "Restore" icon. Yet, I cannot get it to change. Here is the code that handles that button command:

case ID_MENUBAR_MAX: {
                    WINDOWPLACEMENT wp;
                    wp.length = sizeof(WINDOWPLACEMENT);
                    GetWindowPlacement(hwnd, &wp);
                    mII.cbSize = sizeof(MENUITEMINFO);
                    mII.fMask = MIIM_BITMAP;
                    GetMenuItemInfo(hMenu, NUMMI+2, TRUE, &mII);
                    if (wp.showCmd == SW_SHOWNORMAL){    mII.hbmpItem = hMBB.restore;  SendMessage(hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0); }
                    if (wp.showCmd == SW_SHOWMAXIMIZED){ mII.hbmpItem = hMBB.max;      SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);  }
                    SetMenuItemInfo(hMenu, NUMMI+2, TRUE, &mII);
                    DrawMenuBar(hwnd);
                    return 0;
                 }

As I mentioned, everything works as it should. When the button is pressed the window maximizes or normalizes, as it should. I just can't get the bitmap on the button to change along with it. What am I missing? It must be something simple.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
248 views
Welcome To Ask or Share your Answers For Others

1 Answer

It seems that you want to change the bitmap of a button instead of a menu item. You should first specify BS_BITMAP(or BS_ICON) when creating the button, and then send the bitmap to the button handle through the BM_SETIMAGE message, like:

        case ID_MENUBAR_MAX: 
        {
            WINDOWPLACEMENT wp;
            wp.length = sizeof(WINDOWPLACEMENT);
            HWND hMaxButton = (HWND)lParam;
            if (wp.showCmd == SW_SHOWNORMAL) 
            {
                SendMessage(hMaxButton, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hMBB.restore); 
            }
            if (wp.showCmd == SW_SHOWMAXIMIZED) 
            { 
                SendMessage(hMaxButton, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hMBB.max); 
            }

            //DrawMenuBar(hwnd);
            return 0;
        }

EDIT:

I have create an owner-draw menu:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_RBUTTONDOWN:
        OnRightClick(hWnd);
        return TRUE;
    case WM_MEASUREITEM:
        OnMeasureItem(hWnd, (LPMEASUREITEMSTRUCT)lParam);
        return TRUE;
    case WM_DRAWITEM:
        OnDrawItem(hWnd, (LPDRAWITEMSTRUCT)lParam);
        return TRUE;
    ....
    }
}
BOOL WINAPI OnRightClick(HWND hwnd)
{
    HMENU hmenuPopup = CreatePopupMenu();
    MENUITEMINFO mii = { 0 };

    // Add the bitmap menu items to the menu. 
    MYITEM* pMyItem = (MYITEM*)malloc(sizeof(MYITEM));
    //hBitmap1&hBitmap2 have been initialized before
    pMyItem->hBitmap1 = hBitmap1;
    pMyItem->hBitmap2 = hBitmap2;

    mii.cbSize = sizeof(MENUITEMINFO);
    mii.fMask = MIIM_FTYPE | MIIM_DATA;
    mii.fType = MFT_OWNERDRAW;
    mii.dwItemData = (ULONG_PTR)pMyItem;
    InsertMenuItem(hmenuPopup, 0, false, &mii);
    
    RECT rc;
    GetWindowRect(hwnd,&rc);
    TrackPopupMenuEx(hmenuPopup,0,rc.left + 100,rc.top + 100,hwnd,0);

    free(pMyItem);

    return TRUE;
}

VOID WINAPI OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
{
    //lpmis->CtlType = ODT_MENU;
    lpmis->itemWidth = 40;
    lpmis->itemHeight = 40;
}
VOID WINAPI OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis)
{
    MYITEM* pMyItem = (MYITEM*)lpdis->itemData;
    HBITMAP hBitmap;
    static int flag = 0;

    if (lpdis->itemState & ODS_SELECTED)
    {
        flag = !flag;
    }
    if(flag)
        hBitmap = pMyItem->hBitmap1;
    else 
        hBitmap = pMyItem->hBitmap2;

    HDC hdcMem = CreateCompatibleDC(lpdis->hDC);
    HBITMAP oldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);
    BITMAP bitmap;
    GetObject(hBitmap, sizeof(bitmap), &bitmap);
    BitBlt(lpdis->hDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);

    SelectObject(hdcMem, oldBitmap);
    DeleteDC(hdcMem);
}

When the mouse selects the menu, the bitmap of the menu will change.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...