1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_SCOPED_HANDLE_WIN_H_ 6 #define BASE_SCOPED_HANDLE_WIN_H_ 7 8 #include <windows.h> 9 10 #include "base/basictypes.h" 11 #include "base/logging.h" 12 13 // Used so we always remember to close the handle. 14 // The class interface matches that of ScopedStdioHandle in addition to an 15 // IsValid() method since invalid handles on windows can be either NULL or 16 // INVALID_HANDLE_VALUE (-1). 17 // 18 // Example: 19 // ScopedHandle hfile(CreateFile(...)); 20 // if (!hfile.Get()) 21 // ...process error 22 // ReadFile(hfile.Get(), ...); 23 // 24 // To sqirrel the handle away somewhere else: 25 // secret_handle_ = hfile.Take(); 26 // 27 // To explicitly close the handle: 28 // hfile.Close(); 29 class ScopedHandle { 30 public: 31 ScopedHandle() : handle_(NULL) { 32 } 33 34 explicit ScopedHandle(HANDLE h) : handle_(NULL) { 35 Set(h); 36 } 37 38 ~ScopedHandle() { 39 Close(); 40 } 41 42 // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL 43 // usage for errors. 44 bool IsValid() const { 45 return handle_ != NULL; 46 } 47 48 void Set(HANDLE new_handle) { 49 Close(); 50 51 // Windows is inconsistent about invalid handles, so we always use NULL 52 if (new_handle != INVALID_HANDLE_VALUE) 53 handle_ = new_handle; 54 } 55 56 HANDLE Get() { 57 return handle_; 58 } 59 60 operator HANDLE() { return handle_; } 61 62 HANDLE Take() { 63 // transfers ownership away from this object 64 HANDLE h = handle_; 65 handle_ = NULL; 66 return h; 67 } 68 69 void Close() { 70 if (handle_) { 71 if (!::CloseHandle(handle_)) { 72 NOTREACHED(); 73 } 74 handle_ = NULL; 75 } 76 } 77 78 private: 79 HANDLE handle_; 80 DISALLOW_EVIL_CONSTRUCTORS(ScopedHandle); 81 }; 82 83 // Like ScopedHandle, but for HANDLEs returned from FindFile(). 84 class ScopedFindFileHandle { 85 public: 86 explicit ScopedFindFileHandle(HANDLE handle) : handle_(handle) { 87 // Windows is inconsistent about invalid handles, so we always use NULL 88 if (handle_ == INVALID_HANDLE_VALUE) 89 handle_ = NULL; 90 } 91 92 ~ScopedFindFileHandle() { 93 if (handle_) 94 FindClose(handle_); 95 } 96 97 // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL 98 // usage for errors. 99 bool IsValid() const { return handle_ != NULL; } 100 101 operator HANDLE() { return handle_; } 102 103 private: 104 HANDLE handle_; 105 106 DISALLOW_EVIL_CONSTRUCTORS(ScopedFindFileHandle); 107 }; 108 109 // Like ScopedHandle but for HDC. Only use this on HDCs returned from 110 // CreateCompatibleDC. For an HDC returned by GetDC, use ReleaseDC instead. 111 class ScopedHDC { 112 public: 113 ScopedHDC() : hdc_(NULL) { } 114 explicit ScopedHDC(HDC h) : hdc_(h) { } 115 116 ~ScopedHDC() { 117 Close(); 118 } 119 120 HDC Get() { 121 return hdc_; 122 } 123 124 void Set(HDC h) { 125 Close(); 126 hdc_ = h; 127 } 128 129 operator HDC() { return hdc_; } 130 131 private: 132 void Close() { 133 #ifdef NOGDI 134 assert(false); 135 #else 136 if (hdc_) 137 DeleteDC(hdc_); 138 #endif // NOGDI 139 } 140 141 HDC hdc_; 142 DISALLOW_EVIL_CONSTRUCTORS(ScopedHDC); 143 }; 144 145 // Like ScopedHandle but for GDI objects. 146 template<class T> 147 class ScopedGDIObject { 148 public: 149 ScopedGDIObject() : object_(NULL) {} 150 explicit ScopedGDIObject(T object) : object_(object) {} 151 152 ~ScopedGDIObject() { 153 Close(); 154 } 155 156 T Get() { 157 return object_; 158 } 159 160 void Set(T object) { 161 if (object_ && object != object_) 162 Close(); 163 object_ = object; 164 } 165 166 ScopedGDIObject& operator=(T object) { 167 Set(object); 168 return *this; 169 } 170 171 T release() { 172 T object = object_; 173 object_ = NULL; 174 return object; 175 } 176 177 operator T() { return object_; } 178 179 private: 180 void Close() { 181 if (object_) 182 DeleteObject(object_); 183 } 184 185 T object_; 186 DISALLOW_COPY_AND_ASSIGN(ScopedGDIObject); 187 }; 188 189 // Typedefs for some common use cases. 190 typedef ScopedGDIObject<HBITMAP> ScopedBitmap; 191 typedef ScopedGDIObject<HRGN> ScopedRegion; 192 typedef ScopedGDIObject<HFONT> ScopedHFONT; 193 194 195 // Like ScopedHandle except for HGLOBAL. 196 template<class T> 197 class ScopedHGlobal { 198 public: 199 explicit ScopedHGlobal(HGLOBAL glob) : glob_(glob) { 200 data_ = static_cast<T*>(GlobalLock(glob_)); 201 } 202 ~ScopedHGlobal() { 203 GlobalUnlock(glob_); 204 } 205 206 T* get() { return data_; } 207 208 size_t Size() const { return GlobalSize(glob_); } 209 210 T* operator->() const { 211 assert(data_ != 0); 212 return data_; 213 } 214 215 private: 216 HGLOBAL glob_; 217 218 T* data_; 219 220 DISALLOW_EVIL_CONSTRUCTORS(ScopedHGlobal); 221 }; 222 223 #endif // BASE_SCOPED_HANDLE_WIN_H_ 224