[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 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 | |||||
[email protected] | 02b2eeb | 2008-11-18 19:08:18 | [diff] [blame] | 5 | #ifndef BASE_SCOPED_HANDLE_WIN_H_ |
6 | #define BASE_SCOPED_HANDLE_WIN_H_ | ||||
[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 7 | |
8 | #include <windows.h> | ||||
9 | |||||
10 | #include "base/basictypes.h" | ||||
11 | #include "base/logging.h" | ||||
12 | |||||
[email protected] | 0c8a9b1e | 2008-12-12 06:24:20 | [diff] [blame] | 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: | ||||
[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 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: | ||||
[email protected] | 0c8a9b1e | 2008-12-12 06:24:20 | [diff] [blame] | 28 | // hfile.Close(); |
[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 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 | |||||
[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 69 | void Close() { |
70 | if (handle_) { | ||||
71 | if (!::CloseHandle(handle_)) { | ||||
72 | NOTREACHED(); | ||||
73 | } | ||||
74 | handle_ = NULL; | ||||
75 | } | ||||
76 | } | ||||
77 | |||||
[email protected] | 0c8a9b1e | 2008-12-12 06:24:20 | [diff] [blame] | 78 | private: |
[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 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() { | ||||
[email protected] | 9257d01 | 2009-01-21 23:48:34 | [diff] [blame] | 133 | #ifdef NOGDI |
134 | assert(false); | ||||
135 | #else | ||||
[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 136 | if (hdc_) |
137 | DeleteDC(hdc_); | ||||
[email protected] | 9257d01 | 2009-01-21 23:48:34 | [diff] [blame] | 138 | #endif // NOGDI |
[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 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 | operator T() { return object_; } | ||||
172 | |||||
173 | private: | ||||
174 | void Close() { | ||||
175 | if (object_) | ||||
176 | DeleteObject(object_); | ||||
177 | } | ||||
178 | |||||
179 | T object_; | ||||
180 | DISALLOW_COPY_AND_ASSIGN(ScopedGDIObject); | ||||
181 | }; | ||||
182 | |||||
183 | // Typedefs for some common use cases. | ||||
184 | typedef ScopedGDIObject<HBITMAP> ScopedBitmap; | ||||
185 | typedef ScopedGDIObject<HRGN> ScopedHRGN; | ||||
186 | typedef ScopedGDIObject<HFONT> ScopedHFONT; | ||||
187 | |||||
188 | |||||
189 | // Like ScopedHandle except for HGLOBAL. | ||||
190 | template<class T> | ||||
191 | class ScopedHGlobal { | ||||
192 | public: | ||||
193 | explicit ScopedHGlobal(HGLOBAL glob) : glob_(glob) { | ||||
194 | data_ = static_cast<T*>(GlobalLock(glob_)); | ||||
195 | } | ||||
196 | ~ScopedHGlobal() { | ||||
197 | GlobalUnlock(glob_); | ||||
198 | } | ||||
199 | |||||
200 | T* get() { return data_; } | ||||
201 | |||||
202 | size_t Size() const { return GlobalSize(glob_); } | ||||
203 | |||||
204 | T* operator->() const { | ||||
205 | assert(data_ != 0); | ||||
206 | return data_; | ||||
207 | } | ||||
208 | |||||
209 | private: | ||||
210 | HGLOBAL glob_; | ||||
211 | |||||
212 | T* data_; | ||||
213 | |||||
214 | DISALLOW_EVIL_CONSTRUCTORS(ScopedHGlobal); | ||||
215 | }; | ||||
216 | |||||
[email protected] | 02b2eeb | 2008-11-18 19:08:18 | [diff] [blame] | 217 | #endif // BASE_SCOPED_HANDLE_WIN_H_ |
[email protected] | 717a63d0 | 2008-11-18 17:47:08 | [diff] [blame] | 218 |