how can i update the HBITMAP before return it?

Nov 29, 2015 at 9:36pm
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 Nov 29, 2015 at 9:38pm
Nov 30, 2015 at 12:36pm
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.
Nov 30, 2015 at 6:55pm
'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 Nov 30, 2015 at 7:17pm
Dec 1, 2015 at 10:46am
This sounds like undefined behavior due to incorrect use. If used correctly it does not affect other objects.
Dec 1, 2015 at 7:57pm
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
Dec 2, 2015 at 7:45am
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 Dec 2, 2015 at 7:50am
Dec 2, 2015 at 7:26pm
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)
Dec 3, 2015 at 10:42am
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.
Dec 3, 2015 at 9:03pm
i'm sorry.... i mean selected using the SetMenuItemBitmaps() function.
Dec 4, 2015 at 10:37am
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
Dec 4, 2015 at 7:48pm
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?
Dec 4, 2015 at 7:59pm
if you need see my entire image class, just tell me ;)
Dec 5, 2015 at 3:59pm
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 Dec 5, 2015 at 4:00pm
Topic archived. No new replies allowed.