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