how refresh\update a menu and how change draw an image transparent on menu?

i'm working with animation images on menu. i change the image with:
SetMenuItemBitmaps(hMenu,ID,MF_BYCOMMAND,(HBITMAP)hBmp ,(HBITMAP)hBmp);
- why, when the image is showed, i can see background color diferent from menu backcolor?

heres my actual code for menu refresh, when the popup menu is showed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void Refresh()
    {
        //getting the HMENU from menu bar or menu item
        HMENU hMenu = NULL;
        if(primeiromenu)
            hMenu = mnuBar;
        else
            hMenu = MenuHandle;
            
        //change the menu state
        //for update the image
        bool IsHighlith=false;        
        if(GetMenuState(hMenu,ID,MF_BYCOMMAND)==MF_HILITE)
            IsHighlith=true;
        MENUITEMINFO  s={0};
        s.cbSize=sizeof(MENUITEMINFO );
        s.fMask=MIIM_STATE;
        GetMenuItemInfo (hMenu,ID, FALSE, &s);
        if(IsHighlith==true)
            s.fState|=MFS_HILITE;
        else
            s.fState|=MFS_UNHILITE;
        SetMenuItemInfo (hMenu,ID, FALSE, &s);

        if(IsHighlith==true)
        {
            s={0};
            s.fMask=MIIM_STATE;
            GetMenuItemInfo (hMenu,ID, FALSE, &s);
            s.fState|=MFS_HILITE;
            SetMenuItemInfo (hMenu,ID, FALSE, &s);
        }
    }

i just change the menu state sometimes, after change the image, for show me the new image.
doing in these way, i get flickers. can anyone advice me for update the popup menu without get flickers?
Last edited on
- why, when the image is showed, i can see background color diferent from menu backcolor?

Read this:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms647998%28v=vs.85%29.aspx

MSDN wrote:
The selected and clear bitmaps should be monochrome. The system uses the Boolean AND operator to combine bitmaps with the menu so that the white part becomes transparent and the black part becomes the menu-item color. If you use color bitmaps, the results may be undesirable.

i did in diferent way:
1 - i fixed the image Backcolor property;
2 - on my Menu class i have an image object. i copy the image into Menu class image object and then i change it's backcolor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
void bitmap(image imgImage)
    {
        //assignment imgImage to imgMenu
        imgMenu=imgImage;
        //change the image backcolor for menu backcolor
        imgMenu.Backcolor=GetSysColor(COLOR_MENU);

        //deleting the GDI objects before change them
        SelectObject(hMemDC, hBmp2);
        DeleteDC(hMemDC);
        DeleteBitmap(hBmp);

        //do a double buffer from imgMenu and draw it's image
        BITMAP bm;
        hMemDC = CreateCompatibleDC((HDC)imgMenu);

        GetObject((HBITMAP) imgMenu,sizeof(bm),&bm);
        hBmp   = CreateCompatibleBitmap((HDC)imgMenu, bm.bmWidth,bm.bmHeight);

        hBmp2 = (HBITMAP)SelectObject(hMemDC, hBmp);
        //BitBlt(hMemDC,0,0,imgMenu.width(),imgMenu.height(),imgMenu,0,0,SRCCOPY);
        TransparentBlt(hMemDC,0,0,imgMenu.width(),imgMenu.height(),imgMenu,0,0,imgMenu.width(),imgMenu.height(),imgMenu.Backcolor);
        //change the image on menus
        SetMenuItemBitmaps(MenuHandle,ID,MF_BYCOMMAND,(HBITMAP)hBmp ,(HBITMAP)hBmp);

        //delete the GDI objects... except the hBmp for not lose the image
        SelectObject(hMemDC, hBmp2);
        DeleteDC(hMemDC);

        //my own timer for do the animation
        tmrimgmenu.Interval=imgMenu.FrameDelay;
        tmrimgmenu.timerprocedure=[this]()
        {
            //change imgMenu frame
            intFrame++;
            if(intFrame==imgMenu.FrameCount)
                intFrame=0;
            imgMenu.SelectFrame=intFrame;

            //delete the GDI objects
            //the hBmp will be updated, so we must delete it
            SelectObject(hMemDC, hBmp2);
            DeleteDC(hMemDC);
            DeleteBitmap(hBmp);

            //do a double buffering from imgMenu and draw it's image
            BITMAP bm;
            hMemDC = CreateCompatibleDC((HDC)imgMenu);

            GetObject((HBITMAP) imgMenu,sizeof(bm),&bm);
            hBmp   = CreateCompatibleBitmap((HDC)imgMenu, bm.bmWidth,bm.bmHeight);

            hBmp2 = (HBITMAP)SelectObject(hMemDC, hBmp);
            //RECT f={0,0,imgMenu.width(),imgMenu.height()};
            //FillRect(hMemDC,&f,GetSysColor(COLOR_MENU));
            BitBlt(hMemDC,0,0,imgMenu.width(),imgMenu.height(),imgMenu,0,0,SRCCOPY);

            //change the menu image
            SetMenuItemBitmaps(MenuHandle,ID,MF_BYCOMMAND,(HBITMAP)hBmp ,(HBITMAP)hBmp);

            //delete the GDI objects
            //the hBmp can't be delete, only, before be updated for don't lose them image
            SelectObject(hMemDC, hBmp2);
            DeleteDC(hMemDC);

            //refresh the menu
            //just change the menu state and put on original state
            Refresh();
        };
        //start the timer
        tmrimgmenu.Start();
    }

it's very commented, but if is confused, please tell me.
thanks for all.
please try give me more information off-topic: like we know, after create GDI objects, we must delete them for avoid memory leaks. when i execute my application, on Task Manager i see 2 things:
- the GDI objects are increasing and the uncreasing. normal, because we create objects and then we destroy them;
- affter some time, the memory can increasing.. why? the program don't clean the memory correctly or theres anothing that i don't know?(the increasing is very slow, but don't stops.. takes some time for increasing again.)
It's hard to tell where the problem is.

What happens to hBmp created on line 51 when the timer is not longer triggered?
if the timer isn't executed, that line is never used. but the line 18 do the job too..
(maybe i need create a new thread for these especific problem.)
thanks for all
No, I mean when the timer is acutally executed but the last time. hBmp is created but not(?) freed. So each time the timer is started you will have one leaking hBmp.
not in these case. i had changed very the code. the problem isn't with hBmp. before i use it, i delete it.
my problem, memory leak, is from another code that i have.
but i will find it.. thanks for all
Topic archived. No new replies allowed.