2013-09-25 64 views
0

所以,我對WinAPI非常陌生,並且我成功地加載了一個可以用箭頭鍵移動的精靈。我的老師告訴我要對'內存泄漏'非常小心,我不確定如何以正確的方式釋放內存,因爲當我在進行控制檯編程時,C++已經爲我完成了。我運行該程序,並在將角色移動了一段時間之後凍結了我的電腦一分鐘,所以我猜我已經做錯了什麼。你能告訴我如何正確地釋放內存(如果我做錯了),如果我的位圖方法有什麼不好,需要優化?謝謝!這是代碼。C++ WinAPI位圖內存泄漏?

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); 
} 

回答

2

兩件事情是錯誤的:

SelectObject(blockDC, hOld); 

hOld沒有從blockDC來,它來自hdcMem。您甚至沒有保存blockDC的舊位圖。更改爲:

HBITMAP hOld2 = SelectObject(blockDC, bitmap); 
// and 
SelectObject(blockDC, hOld2); 

其次,您並未在任何地方刪除hbmMem。在底部添加:

DeleteObject(hbmMem); 

實際上,第三件事情也是錯誤的 - 您不會檢查您所做的任何API調用中的失敗。你應該檢查像CreateCompatibleDC這樣的東西是否返回NULL,如果是,則中止並清除。

+0

糟糕,我忘了刪除那個,爲它添加了一個刪除,凍結停止了。謝謝您的幫助! –

+0

@TobiasSundell很高興我可以幫忙,隨時接受答案:) –

+0

我有我找到的功能的備份。它包含了很多對失敗的檢查。我刪除了它們,因爲它們的代碼非常大:p –