gpt4 book ai didi

winapi - DeleteD 会自动取消选择对象吗?

转载 作者:行者123 更新时间:2023-12-02 04:25:27 25 4
gpt4 key购买 nike

我是否总是需要调用 SelectObject 将原始对象恢复到 DC(并使我的对象可供删除),即使我无论如何都要删除 DC...?

例如

  // Create DC
HBITMAP hBitmap = CreateCompatibleBitmap (hDC, rect.Width(), rect.Height());
HGDIOBJ hOldBitmap = SelectObject(hMemDC, hBitmap);


// ... Do some other stuff with the DC

// DO I NEED THIS LINE HERE???
SelectObject(hMemDC, hOldBitmap);

// Tidy up
DeleteDC(hMemDC);
DeleteObject(hBitmap); // This DOES return TRUE even without the SelectObject line...

“DeleteDC”是否会自动取消选择其中选定的对象,以便在删除 DC 后可以删除它们?

谢谢

最佳答案

我自己对这个问题进行了调查。据他们称,标记的答案至少在这个声明中是不准确的:

A DC ... will accordingly free any current selected objects when it is freed, as it is expecting the original objects.

当您将刚创建的内存位图选择到刚创建的内存DC中时,内存DC不拥有该位图(至少,从内存管理的意义上来说) ) - 它将其标记为“已使用”,因此无法通过 DeleteObject 调用删除它(可能通过增加位图的一种引用计数)。如果您先删除内存 DC - 它不会删除内存位图:GetGuiResources(GR_GDIOBJECTS) 返回的对象计数会减少 1,即仅针对 DC 本身,而不是 2(对于 DC 和位图)。随后的 DeleteObject(hMemBitmap) 调用会相应减少 GDI 对象计数。

关于提到的“默认1x1位图的泄漏”in this comment ,这似乎也是错误的:该位图不是为每个内存 DC 单独创建的。相反,它是 Raymond Chen 很好解释的所谓“库存位图”:根据his "The mysterious stock bitmap" article ,此位图是 GDI 用于各种目的的单例,并且它是唯一可以被选择到多个 DC 中的位图。除了将其选择到 DC 中之外,您无法删除它或以任何方式使用它。尽管 DeleteObject 在此位图句柄上返​​回 TRUE,但它不会影响 GDI 对象计数。在删除该 DC 之前将该位图选择回内存 DC 只是一种好习惯,实际上不是必需的:选择回它会增加其使用引用计数,然后删除 DC 会减少回引用计数,这会导致没有增益(引用值与从内存 DC“取消选择”库存位图后保持相同。

我制作了一个PoC测试程序,并在各个版本的Windows(从WinXP SP3到最新的Win10更新)中进行了检查 - 结果非常一致。

总结一下:

  • 原始问题的答案是“是的,确实如此”

  • //DO I NEED THIS LINE HERE??? 问题的答案是“不,你不需要 - 条件是你确定旧位图的句柄是库存位图的句柄”

关于winapi - DeleteD 会自动取消选择对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27422871/

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