Not all functions that use HANDLE use CloseHandle() , some use other closing functions. In addition, not all HANDLE values use INVALID_HANDLE_VALUE . Some use NULL instead.
HBITMAP never uses INVALID_HANDLE_VALUE , it always uses NULL . And you should never call DeleteObject() for HBITMAP , which you are not.
So, the short answer is if you are trying to create some sort of general-purpose descriptor management, don't worry. You are probably mistaken. If you select / open a descriptor, you must know the correct way to close it; you cannot guess about it.
If you want descriptors to control yourself, RAII is the best choice. I prefer to use a template class with special features to reduce code duplication for different types of descriptors, for example:
template< class traits > class HandleWrapper { private: traits::HandleType FHandle; public: HandleWrapper() FHandle(traits::InvalidValue) { } HandleWrapper(const traits::HandleType value) FHandle(value) { } ~HandleWrapper() { Close(); } void Close() { if (FHandle != traits::InvalidValue) { traits::Close(FHandle); FHandle = traits::InvalidValue; } } bool operator !() const { return (FHandle == traits:::InvalidValue); } operator bool() const { return (FHandle != traits:::InvalidValue); } operator traits::HandleType() { return FHandle; } };
.
struct KernelHandleTraits { typedef HANDLE HandleType; static const HANDLE InvalidValue = INVALID_HANDLE_VALUE; static void Close(HANDLE value) { CloseHandle(value); } }; HandleWrapper<KernelHandleTraits> hFile(CreateFile(...));
.
struct NullKernelHandleTraits { typedef HANDLE HandleType; static const HANDLE InvalidValue = NULL; static void Close(HANDLE value) { CloseHandle(value); } }; HandleWrapper<NullKernelHandleTraits> hMapping(CreateFileMapping(...));
.
struct FileMapViewTraits { typedef void* HandleType; static const void* InvalidValue = NULL; static void Close(void *value) { UnmapViewOfFile(value); } }; HandleWrapper<FileMapViewTraits> hView(MapViewOfFile(...));
.
struct GDIBitmapHandleTraits { typedef HBITMAP HandleType; static const HBITMAP InvalidValue = NULL; static void Close(HBITMAP value) { DeleteObject(value); } }; HandleWrapper<GDIBitmapTraits> hBmp(CreateBitmap(...));
Etc.
source share