gpt4 book ai didi

c++ - 多次调用后 LoadBitmap 失败

转载 作者:行者123 更新时间:2023-11-30 01:42:27 25 4
gpt4 key购买 nike

在这个函数中,在大约 90 次调用之后(它在一个循环中被调用,我的想法是每次加载一个单独的图像,但为了简单起见,我将它保留为一个图像)。全局变量现在更改为局部变量.

   void CDLP_Printer_ControlDlg::DisplayBMPfromSVG(CString& strDsiplayFile)
{
HBITMAP hbmp_temp = (HBITMAP)::LoadImage(0, strDsiplayFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (!hbmp_temp)
{
//hbmp_temp = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));
ActionList.AddString(L"Bitmap Load Failure: GetBMPromSVG");
ActionList.UpdateWindow();
if (!hbmp_temp)
return;
}

CBitmap bmp_temp;
bmp_temp.Attach(hbmp_temp);
mProjectorWindow.m_picControl.ModifyStyle(0xF, SS_BITMAP, SWP_NOSIZE);
mProjectorWindow.m_picControl.SetBitmap(bmp_temp);

return;
}

我希望有人能想出一个想法有什么问题。 GetLastError 返回“8”,这对我来说毫无意义。

最佳答案

Detach 会破坏之前的句柄。

请注意,如果在调用SetBitmap 之后调用Detach,图片控件的位图将被破坏。结果是图片控件被绘制了一次,但不会被重新绘制。例如,如果调整对话框的大小,图片控件将变为空白。

编辑

要销毁旧位图,请调用 Detach,然后调用 DestroyObject。示例

HGDIOBJ hbitmap_detach = m_bitmap.Detach();
if (hbitmap_detach)
DeleteObject(hbitmap_detach);
m_bitmap.Attach(hbitmap);

如果它是一个临时的 CBitmap 那么 DeleteObject 就没有必要了,因为当 CBitmap 发生时 DeleteObject 会被自动调用超出范围。

请注意,如果您在调用 SetBitmap 后销毁位图,图片控件的位图也会被销毁。结果是图片控件被绘制了一次,但不会被重新绘制。例如,如果调整对话框的大小,图片控件将变为空白。

如果您在堆栈上声明一个临时的 CBitmap 并附加位图句柄,也会出现同样的问题。该位图句柄将被破坏,图片控件无法自行重绘。

另外,Windows XP有时会产生重复的位图,同样需要销毁。 SetBitmap 返回前一个位图的句柄。在 Vista+ 中,返回的位图与保存在 m_bitmap 中的位图相同,我们已经用 Detach 销毁了它。但是在 XP 中,如果它是不同的句柄,我们需要销毁这个拷贝。

void CMyDialog::foo()
{
HBITMAP save = m_bitmap;
HBITMAP hbitmap = (HBITMAP)::LoadImage(0, filename,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (hbitmap)
{
HGDIOBJ hbitmap_detach = m_bitmap.Detach();
//Edit ****************************************
//Delete old handle, otherwise program crashes after 10,000 calls
if (hbitmap_detach)
DeleteObject(hbitmap_detach);
//*********************************************
m_bitmap.Attach(hbitmap);

HBITMAP oldbmp = m_picControl.SetBitmap(m_bitmap);

//for Windows XP special case where there might be 2 copies:
if (oldbmp && (oldbmp != save))
DeleteObject(oldbmp);
}
}

此外,SetBitmap 接受HBITMAP 参数并返回HBITMAP,因此您可以完全避免使用CBitmap。以下示例适用于 Vista+

void foo()
{
HBITMAP temp = (HBITMAP)::LoadImage(0,filename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
if (temp)
{
HBITMAP oldbmp = m_picControl.SetBitmap(temp);
if (oldbmp)
DeleteObject(oldbmp);
DeleteObject(temp);
}
}

关于c++ - 多次调用后 LoadBitmap 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39596419/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com