In Win32 there are many different handle types such as HWND
, HFONT
, HIMAGELIST
etc. My understanding is that it's my responsibility to close all of them at the end with DeleteObject()
. Moreover, some handle types like HIMAGELIST
have additional functions like ImageList_Destroy
, so I have to call them as well.
I want to verify that the handles become invalid after I clean them up. Suppose I have
HWND hWnd;
HFONT hFont;
HIMAGELIST hImageList;
//...
// On Exit:
case WM_DESTROY:
DeleteObject(hWnd);
DeleteObject(hFont);
ImageList_Destroy(hImageList);
DeleteObject(hImageList);
In the VS debugger I see that the value of the handles does not change after these deletions. It's exactly the same, both before and after:
hWnd 0x00000000e806b2
hFont 0xfffffffe20a140
hImageList 0x000001c76a943e
Is it supposed to change? How do I know I'm cleaning up these handles?
I see that the value of the handles does not change after these deletions. It's exactly the same, both before and after
Just like if you use delete
on a pointer, it won't change the value of the pointer. You can set it to nullptr by yourself after calling the corresponding cleanup function.
Managing handles is just like using new
and delete
in C++—you must call the correct cleanup function for each handle you acquire.
The specific function you need to call to clean up a handle is documented alongside the function you used to obtain that handle. It's not determined by the handle's type, but by how the handle was obtained. Some types of handles can be returned by multiple different functions, and each may require a different cleanup function. It's like how you can't use free
to clean up a pointer returned by new
.
Just like pointers, you can manage handles using smart pointers, or you can go the C programmer route and manage allocation and cleanup manually. If you have handles that live for the entire lifetime of the application, you could also choose to be a bad programmer and let the system clean them up automatically when the program exits.