任何人都有這個問題,無論如何我沒有找到答案。代碼很簡單:CreateIconFromResource在被調用數千次後返回NULL和UI崩潰
void CbDlg::OnBnClickedOk()
{
for(int i=0; i<1000; i++)
{
HRSRC hRes = ::FindResource(NULL, MAKEINTRESOURCE(IDR_MAINFRAME), RT_GROUP_ICON);
HGLOBAL hResLoad = ::LoadResource(NULL, hRes);
BYTE* pIconBytes = (BYTE*)::LockResource(hResLoad);
int nId = ::LookupIconIdFromDirectory(pIconBytes, TRUE);
hRes = ::FindResource(NULL, MAKEINTRESOURCE(nId), RT_ICON);
DWORD read = ::SizeofResource(NULL ,hRes);
hResLoad = ::LoadResource(NULL, hRes);
pIconBytes = (BYTE*)::LockResource(hResLoad);
if(pIconBytes != NULL)
{
HICON hIcon = ::CreateIconFromResource(pIconBytes, read, TRUE, 0x00030000);
DWORD e = ::GetLastError();
if(hIcon != NULL)
{
::DestroyIcon(hIcon);
}
}
}
}
如果我點擊確定按鈕四次(在我的電腦),CreateIconFromResource開始返回NULL(它之前的工作很好,我甚至可以畫出來的圖標)。至於GetLastError,無論CreateIconFromResource是否返回NULL,它總是返回6。
當這個問題發生時,如果我拖動標題欄移動,UI崩潰,請參閱圖片。
當然,您可以理解這段代碼只是一個演示,我的真實業務需要像這樣調用CreateIconFromResource幾千次。根據Hans的建議,我繼續跟蹤Handles/USER Objects/GDI對象,發現USER對象增長1000,而GDI對象增長2000對每次點擊OK按鈕(手柄沒有增長),並且當問題發生時GDI對象是9999。但是當我完成使用時,如何正確釋放它們?我一次沒有使用太多,但需要加載,釋放,再次加載,再次釋放......就像這個演示。作爲MSDN文檔,我爲每個HICON調用了DestroyIcon。我還需要做什麼,最終釋放USER/GDI對象?
您可能泄漏手柄,當您泄漏10,000個手錶時,節目結束。 –
@Hans,謝謝你的建議,我發現它是USER/GDI對象泄漏的,但我仍然有問題,在我的文章中更新。 – zhiyazw