how can i update the HBITMAP before return it?

heres my HBITMAP return function:
1
2
3
4
5
6
7
8
9
10
11
operator HBITMAP()
    {
        /*DeleteBitmap(hbmMask);
        hbmMask = CreateCompatibleBitmap(HBitmap, imageweight, imageheight);
        HDC dstdc = CreateCompatibleDC(NULL);
        SelectObject(dstdc,hbmMask);
        BitBlt(dstdc,0,0,imageweight, imageheight, HBitmap,0,0, SRCCOPY);*/
        //DeleteDC(dstdc);
        //HBitmap return me the HDC image
        return hbmMask;//hbmMask it's a global class and private member
    }

how can i update the hbmMask, from HBitmap(have the HDC return operator too), before return the hbmMask?
Last edited on
So what's wrong with the out commented code?

Before you call DeleteDC() you may select that object returned on line 6. I would think (even though it is not documented) that hbmMask will be deleted within DeleteDC() as well.
'So what's wrong with the out commented code?'
by some reason the:
DeleteBitmap(hbmMask);
will affect the other image(my class) instances.
for fix it: every time that i change(add text or shape), i do these:
1
2
DeleteBitmap(hbmMask);
            hbmMask = HBITMAPfromHDC(HBitmap);

let me ask 1 thing:
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
class image
{
private:
    ULONG_PTR m_gdiplusToken;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    BitmapDC HBitmap;
    Image *img=NULL;
    bool isimgused=false;
    bool isGDIPLUSIniciated=false;
    int imageheight=0;
    int imageweight=0;
    int framecount=0;
    int intSelectFrame=0;
    int framedelay=0;
    string strfilename="";
    Gdiplus::Color clrBackColor=Gdiplus::Color::Blue;
    bool blnTransparent=true;
    HPEN imgPen;
    HBRUSH imgBrush;
    CHOOSEFONT chFont;
    HICON hIcon;
    HBITMAP hbmMask;
    int intRotate=0;
//the HBITMAP operator:
public:
operator HBITMAP()
    {
        return hbmMask;
    }

how the hbmMask, if i delete it(like you see on comment code) will be affected on all image instances?
Last edited on
This sounds like undefined behavior due to incorrect use. If used correctly it does not affect other objects.
you have right. or the comment code:
1
2
3
4
5
6
/*DeleteBitmap(hbmMask);
        hbmMask = CreateCompatibleBitmap(HBitmap, imageweight, imageheight);
        HDC dstdc = CreateCompatibleDC(NULL);
        SelectObject(dstdc,hbmMask);
        BitBlt(dstdc,0,0,imageweight, imageheight, HBitmap,0,0, SRCCOPY);*/
        //DeleteDC(dstdc); 

don't update it correctly...
tell me what you think, please
I would suggest the following:
1
2
3
4
5
6
        hbmMask = CreateCompatibleBitmap(HBitmap, imageweight, imageheight);
        HDC dstdc = CreateCompatibleDC(HBitmap); // Note: compatible to the dc in question
        HGDIOBJ hold = SelectObject(dstdc,hbmMask);
        BitBlt(dstdc,0,0,imageweight, imageheight, HBitmap,0,0, SRCCOPY);*/
        SelectObject(dstdc,hold); // Note: you cannot select a bitmap twice into different dc, hence unselect it here
        DeleteDC(dstdc);


I'm not sure whether this is the source of your problems, but not selecting it out of the dc might cause a problem depending on what you're doing with it.

Also: I don't know whether it's a good idea to mix gdi+ and gdi.
Last edited on
now i understand why isn't working.
imagine that the hbmMask is attached to a menu. if i delete the hbmMask, then i will lose it from the menu.
on your code, you don't delete it, but create a new one.. these make a memory leak, because the resource isn't deleted.... instead use the CreateCompatibleBitmap(), is there another function for 'update' the HBITMAP?(like give it a new size for then update the image)
My concern was to show you that you need to deselect the bitmap if you want to use it otherwise. And no, I don't have a clue what you're doing with the objects apart from this small code snippet.

It is actually possible to access the image data directly using CreateDIBSection(...):

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


When you change something it is not automatically updated, you need to call InvalidateRect(...):

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

or something similar.

You cannot change the size of a selected bitmap. You need to deselect it beforehand.
i'm sorry.... i mean selected using the SetMenuItemBitmaps() function.
I would think as long as the bitmap is attached to the menu you cannot change it.

So either

remove it from the menu -> modify -> set it back to the menu

or

new bitmap -> replace old menu bitmap -> delete old bitmap
my best shoot was these: everytime that i add a text, shape, image or change image frame, i use these code:
1
2
DeleteBitmap(hbmMask);
        hbmMask = HBITMAPfromHDC(HBitmap);

heres the function:
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
HBITMAP HBITMAPfromHDC(HDC hdcimage)
{
    //prepare the returnhbitmap for get the size
    HBITMAP returnhbitmap;
    BITMAP structBitmapHeader;
    memset( &structBitmapHeader, 0, sizeof(BITMAP) );
    //DeleteBitmap(returnhbitmap);

    //get the hdc actual size
    returnhbitmap =(HBITMAP) GetCurrentObject(hdcimage, OBJ_BITMAP);
    GetObject(returnhbitmap, sizeof(BITMAP), &structBitmapHeader);

    //create a hdc for select the returnhbitmap
    HDC hMemDC = CreateCompatibleDC(NULL);

    //clean the returnhbitmap before create a new one
    //DeleteBitmap(returnhbitmap);
    returnhbitmap   = CreateCompatibleBitmap(hdcimage, structBitmapHeader.bmWidth,structBitmapHeader.bmHeight);

    //select returnhbitmap to hMemDC
    HBITMAP hBmp2 = (HBITMAP)SelectObject(hMemDC, returnhbitmap);

    //copy the hdcimage to hMemDC
    BitBlt(hMemDC,0,0,structBitmapHeader.bmWidth,structBitmapHeader.bmHeight,hdcimage,0,0,SRCCOPY);

    //unselect the returnhbitmap for return it without problems
    SelectObject(hMemDC, hBmp2);

    //and then delete the DC
    DeleteDC(hMemDC);
    return returnhbitmap;
}

so when i add a new function or some effects, i must add that 2 lines :(
isn't the best, but works fine.
so what is the problem?
is that i can't do it when i return the HBITMAP :(
1
2
3
4
operator HBITMAP()
    {
        return hbmMask;
    }

how can i avoid that problem?
if you need see my entire image class, just tell me ;)
i did some mistakes on my image class, that's why was not correct :(
how can i update a HBITMAP, if was not created :P
so everytime that i change the file name or image size, i recreate the HBITMAP:
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
HBITMAP HBITMAPfromHDC(HDC hdcimage)
{
    //prepare the returnhbitmap for get the size
    HBITMAP returnhbitmap;
    BITMAP structBitmapHeader;
    memset( &structBitmapHeader, 0, sizeof(BITMAP) );
    //DeleteBitmap(returnhbitmap);

    //get the hdc actual size
    returnhbitmap =(HBITMAP) GetCurrentObject(hdcimage, OBJ_BITMAP);
    GetObject(returnhbitmap, sizeof(BITMAP), &structBitmapHeader);

    //create a hdc for select the returnhbitmap
    HDC hMemDC = CreateCompatibleDC(NULL);

    //clean the returnhbitmap before create a new one
    //DeleteBitmap(returnhbitmap);
    returnhbitmap   = CreateCompatibleBitmap(hdcimage, structBitmapHeader.bmWidth,structBitmapHeader.bmHeight);

    //select returnhbitmap to hMemDC
    HBITMAP hBmp2 = (HBITMAP)SelectObject(hMemDC, returnhbitmap);

    //copy the hdcimage to hMemDC
    BitBlt(hMemDC,0,0,structBitmapHeader.bmWidth,structBitmapHeader.bmHeight,hdcimage,0,0,SRCCOPY);

    //unselect the returnhbitmap for return it without problems
    SelectObject(hMemDC, hBmp2);

    //and then delete the DC
    DeleteDC(hMemDC);
    return returnhbitmap;
}
//.......
DeleteBitmap(hbmMask);
        hbmMask = HBITMAPfromHDC(HBitmap);

now i don't need do:
1 - draw the rectangle;
2 - draw the text;
3 - update the hbmMask.
now i can draw what i need without update the hbmMask.
only when i return HBITMAP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void updatereturnbitmap()
    {
        HDC dstdc = CreateCompatibleDC(HBitmap); // Note: compatible to the dc in question
        HGDIOBJ hold = SelectObject(dstdc,hbmMask);
        BitBlt(dstdc,0,0,imageweight, imageheight, HBitmap,0,0, SRCCOPY);
        SelectObject(dstdc,hold); // Note: you cannot select a bitmap twice into different dc, hence unselect it here
        DeleteDC(dstdc);
    }

    operator HBITMAP()
    {
        updatereturnbitmap();
        return hbmMask;
    }

i accept sugestions ;)
thanks for all
Last edited on
Topic archived. No new replies allowed.