Reputation: 117
So, I'm very new to WinAPI and I've succeeded in loading a sprite which I can move with the arrow keys. My teacher told me to be very careful with 'memory leaks' and I'm not sure how to free memory the right way because C++ has done it for me when I was doing console programming. I ran the program and it froze my computer for a minute after moving the character for a while so I guess I've done something wrong. Can you tell me how to properly free memory (if I've done it wrong) and if there's anything bad with my bitmap method that needs optimising? Thanks! Here's the code.
void LoadAndBlitBitmap(LPCSTR szFileName, HWND hwnd, HDC winDC, int xPos, int yPos)
{
//DEFINITIONS
/*TransparentBlt(destDC, destXpos, destYpos, sizeX, sizeY, srcDC, 0, 0, sizeX, sizeY, RGB(a, b, c)) = TRANSPARENT BITMAP BLIT. Ex. RGB(255, 255, 255) if background is white*/
/*BitBlt(destDC, destXpos, destYpos, sizeX, sizeY, srcDC, 0, 0, SRCCOPY); = SOLID BITMAP BLIT WITH NO TRANSPARENCY*/
//END DEFINITIONS
//-----Get the size of the window---------
RECT rect;
int win_width = 0;
int win_height = 0;
if(GetWindowRect(hwnd, &rect))
{
win_width = rect.right - rect.left; //Subtracting the right coordinate with the left gives the width
win_height = rect.bottom - rect.top; //Subtracting the bottom coordinate with the top gives the height
}
//----------------------------------------
HDC hdcMem = CreateCompatibleDC(winDC); //Create the DC that will hold the off-screen printing. (Double Buffering "Anti-Flicker" Method)
HBITMAP hbmMem = CreateCompatibleBitmap(winDC, win_width, win_height); //Create the bitmap with the size of the window
HANDLE hOld = SelectObject(hdcMem, hbmMem); //Set the paintable bitmap to the off-screen DC
//Draw to the off-screen DC
HBITMAP bitmap = (HBITMAP)LoadImage(NULL, szFileName, IMAGE_BITMAP, 69, 69, LR_LOADFROMFILE); //Load the .bmp from a file
HDC blockDC = CreateCompatibleDC(NULL); //Create a DC to hold the .bmp
SelectObject(blockDC, bitmap); //Select the .bmp to the DC
TransparentBlt(hdcMem, xPos, yPos, 69, 69, blockDC, 0, 0, 69, 69, RGB(255, 255, 255)); //Blit the .bmp to the DC*/
//Transfer off-screen DC to the screen
BitBlt(winDC, 0, 0, win_width, win_height, hdcMem, 0, 0, SRCCOPY);
// Uninitialize and deallocate resources
SelectObject(hdcMem, hOld);
DeleteDC(hdcMem);
SelectObject(blockDC, hOld);
DeleteDC(blockDC);
DeleteObject(bitmap);
}
Upvotes: 0
Views: 918
Reputation: 37132
Two things are wrong:
SelectObject(blockDC, hOld);
hOld
did not come from blockDC
, it came from hdcMem
. You are not even saving the old bitmap from blockDC
. Change to:
HBITMAP hOld2 = SelectObject(blockDC, bitmap);
// and
SelectObject(blockDC, hOld2);
Secondly, you are not deleting hbmMem
anywhere. At the bottom, add:
DeleteObject(hbmMem);
Actually, a third thing is wrong too - you're not checking for failure in any of the API calls you make. You should check if things like CreateCompatibleDC
return NULL, and abort and cleanup if so.
Upvotes: 2