Win32 中有许多不同的句柄类型,例如、HWND
等等。我的理解是,我有责任在最后用 来关闭它们。此外,某些句柄类型(例如)具有附加函数(例如),因此我也必须调用它们。HFONT
HIMAGELIST
DeleteObject()
HIMAGELIST
ImageList_Destroy
我想验证一下清理后句柄是否失效。假设我有
HWND hWnd;
HFONT hFont;
HIMAGELIST hImageList;
//...
// On Exit:
case WM_DESTROY:
DeleteObject(hWnd);
DeleteObject(hFont);
ImageList_Destroy(hImageList);
DeleteObject(hImageList);
在VS调试器中,我看到这些删除操作后句柄的值没有变化。删除前后都完全相同:
hWnd 0x00000000e806b2
hFont 0xfffffffe20a140
hImageList 0x000001c76a943e
它应该改变吗?我怎么知道我清理了这些句柄?
就像在指针上使用 一样
delete
,它不会改变指针的值。您可以在调用相应的清理函数后自行将其设置为 nullptr。管理句柄就像在 C++ 中使用
new
和一样delete
——您必须为获取的每个句柄调用正确的清理函数。清理句柄所需调用的具体函数与获取该句柄所用的函数一同记录。清理句柄的具体函数并非由句柄的类型决定,而是由句柄的获取方式决定。某些类型的句柄可能由多个不同的函数返回,并且每个函数可能需要不同的清理函数。这就像您不能使用
free
来清理由 返回的指针一样new
。就像指针一样,您可以使用智能指针来管理句柄,或者您可以像 C 程序员一样,手动管理分配和清理。如果您的句柄在整个应用程序生命周期内都有效,那么您也可以选择成为一名糟糕的程序员,让系统在程序退出时自动清理它们。
DeleteObject 仅适用于 GDI 对象、HFONT、HBITMAP 等。虽然它可以告诉您是否成功,但显然不会给出失败的原因。
HWND 有 DestroyWindow。
请注意,这两个函数都不采用指针到指针的参数类型,因此调用者的值不会改变。
您只需检查相关的 API 即可了解如何释放特定的句柄类型。
例如,我知道有些 API 会返回纯 HANDLE 类型的值(虽然我暂时想不起来了),但它们并没有使用 CloseHandle 作为释放机制。CloseHandle 仅适用于实际的内核句柄(主要是文件,但也包括其他类型的句柄)。