Advertisement

Win32 - How do I access a bitmap handle from an array of structs?

Started by February 26, 2021 09:45 AM
6 comments, last by Airbatz 3 years, 9 months ago

I've got a struct which contains a HBITMAP and want to be able to access the bitmap by it's handle from the array, but I have not been able to using GetObject in WM_PAINT. The program compiles and runs but won't show the bitmap. Any help is welcome.

I declare the handle to the bitmap at the top of the program and create the struct.

HBITMAP g_hbmChar = NULL;
struct character* current_character;
struct character {

    char name [36];
    char source [36];
    char about [300];
    HBITMAP cBitmap;

    };	

This is the array. I've cut it down for the sake of this example. The last element is supposed to be the bitmap.

struct character characters [13] =
{
    {
       "NAME", "SOURCE", "ABOUT", (HBITMAP)&g_hbmChar
    }

};

I use LoadImage to load the bitmap in WM_CREATE.

g_hbmChar = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDB_CHR1), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);

Contents of WM_PAINT.

RECT rcClient;
PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);
HDC HDCMem = CreateCompatibleDC(hdc);

GetClientRect(hWnd, &rcClient);

SelectObject(HDCMem, current_character->cBitmap);
BitBlt(hdc, 364, 26, 150, 190, HDCMem, 0, 0, SRCCOPY);

SelectObject(HDCMem, HDCMem);
DeleteDC(HDCMem);
EndPaint(hWnd, &ps);

None

// I would have done it this way
characters[x].cBitmap = LoadImage(...IDB_CHRX...);

have fun ?

Advertisement

@ddlox

Thanks, It works like a charm! Can't believe I didn't see it sooner.
I have a question though. In my array, is it at all possible to do something like g_hbmChar instead of (HBITMAP)&g_hbmChar? Regardless, it does what I need it to do now. ?

None

Airbatz said:
In my array, is it at all possible to do something like g_hbmChar instead of (HBITMAP)&g_hbmChar?

no, not possible in the scenario that you originally described;

HBITMAP cBitmap; declares “a variable that will store a copy of a HBITMAP handle”

(HBITMAP)&ghbmChar means “take the memory address of the global variable g_hbmChar cast it to a HBITMAP handle”

so this cast memory address was stored in cBitmap, which means that when ghbmChar was loaded with an image, ghbmChar received a HANDLE therefore a new memory address, but the one stored in cBitmap was still the old one pointing to NULL

Airbatz said:
Can't believe I didn't see it sooner

Ah well, they don't call me the Old Rooster for nothing :-), lol just joking… I made similar mistakes in the past, that's all…

Don't forget to call DeleteObject(characters[x].cBitmap); when you're done with it. If you don't, your process's memory working set will stay high… if you have not heard of “HANDLE leaks” then this is how they happen by not freeing memory held by HANDLEs;

That's it! All the best ?

Ah, That makes sense. I'll keep it in mind for future reference. Handles are all being taken care of in my full code ? Thank you again for your help and explanations!

None

Also, there's a line that pretty surely does nothing useful:

SelectObject( HDCMem, HDCMem );

When you SelectObject something the right thing to do is to restore the previous state of the HDC once you're done.
SelectObject returns the previous object of the type you selected into it. So it becomes:

RECT rcClient;
PAINTSTRUCT ps;

HDC hdc = BeginPaint( hWnd, &ps );
HDC HDCMem = CreateCompatibleDC( hdc );

GetClientRect( hWnd, &rcClient );

HBITMAP origBitmap = (HBITMAP)SelectObject( HDCMem, current_character->cBitmap );
BitBlt(hdc, 364, 26, 150, 190, HDCMem, 0, 0, SRCCOPY);

SelectObject( HDCMem, origBitmap );
DeleteDC( HDCMem );
EndPaint( hWnd, &ps );

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Advertisement

@endurion

Thanks for pointing that out. It has since been fixed. ?

None

This topic is closed to new replies.

Advertisement