blob: 8ed568da024005608ae703da95da5d7ab3c9f565 [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
5#ifndef BASE_SCOPED_HANDLE_H__
6#define BASE_SCOPED_HANDLE_H__
7
8#include <windows.h>
9
10#include "base/basictypes.h"
cpu@google.com7d7a5282008-08-27 13:03:40 +090011#include "base/logging.h"
initial.commit3f4a7322008-07-27 06:49:38 +090012
13// Used so we always remember to close the handle. Example:
14// ScopedHandle hfile(CreateFile(...));
15// if (!hfile.Get())
16// ...process error
17// ReadFile(hfile.Get(), ...);
18//
19// To sqirrel the handle away somewhere else:
20// secret_handle_ = hfile.Take();
21//
22// To explicitly close the handle:
23// CloseHandle(hfile.Take());
24class ScopedHandle {
25 public:
26 ScopedHandle() : handle_(NULL) {
27 }
28
29 explicit ScopedHandle(HANDLE h) : handle_(NULL) {
30 Set(h);
31 }
32
33 ~ScopedHandle() {
34 Close();
35 }
36
37 // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL
38 // usage for errors.
39 bool IsValid() const {
40 return handle_ != NULL;
41 }
42
43 void Set(HANDLE new_handle) {
44 Close();
45
46 // Windows is inconsistent about invalid handles, so we always use NULL
cpu@google.com7d7a5282008-08-27 13:03:40 +090047 if (new_handle != INVALID_HANDLE_VALUE)
initial.commit3f4a7322008-07-27 06:49:38 +090048 handle_ = new_handle;
49 }
50
51 HANDLE Get() {
52 return handle_;
53 }
54
55 operator HANDLE() { return handle_; }
56
57 HANDLE Take() {
58 // transfers ownership away from this object
59 HANDLE h = handle_;
60 handle_ = NULL;
61 return h;
62 }
63
64 private:
65 void Close() {
66 if (handle_) {
cpu@google.com7d7a5282008-08-27 13:03:40 +090067 if (!::CloseHandle(handle_)) {
68 NOTREACHED();
69 }
initial.commit3f4a7322008-07-27 06:49:38 +090070 handle_ = NULL;
71 }
72 }
73
74 HANDLE handle_;
75 DISALLOW_EVIL_CONSTRUCTORS(ScopedHandle);
76};
77
78// Like ScopedHandle, but for HANDLEs returned from FindFile().
79class ScopedFindFileHandle {
80 public:
81 explicit ScopedFindFileHandle(HANDLE handle) : handle_(handle) {
82 // Windows is inconsistent about invalid handles, so we always use NULL
83 if (handle_ == INVALID_HANDLE_VALUE)
84 handle_ = NULL;
85 }
86
87 ~ScopedFindFileHandle() {
88 if (handle_)
89 FindClose(handle_);
90 }
91
92 // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL
93 // usage for errors.
94 bool IsValid() const { return handle_ != NULL; }
95
96 operator HANDLE() { return handle_; }
97
98 private:
99 HANDLE handle_;
100
101 DISALLOW_EVIL_CONSTRUCTORS(ScopedFindFileHandle);
102};
103
104// Like ScopedHandle but for HDC. Only use this on HDCs returned from
105// CreateCompatibleDC. For an HDC returned by GetDC, use ReleaseDC instead.
106class ScopedHDC {
107 public:
jam@chromium.orgce03ce62008-09-23 07:40:21 +0900108 ScopedHDC() : hdc_(NULL) { }
initial.commit3f4a7322008-07-27 06:49:38 +0900109 explicit ScopedHDC(HDC h) : hdc_(h) { }
110
111 ~ScopedHDC() {
jam@chromium.orgce03ce62008-09-23 07:40:21 +0900112 Close();
113 }
114
jam@chromium.orge2cd5822008-10-01 09:38:11 +0900115 HDC Get() {
116 return hdc_;
117 }
118
jam@chromium.orgce03ce62008-09-23 07:40:21 +0900119 void Set(HDC h) {
120 Close();
121 hdc_ = h;
initial.commit3f4a7322008-07-27 06:49:38 +0900122 }
123
124 operator HDC() { return hdc_; }
125
126 private:
jam@chromium.orgce03ce62008-09-23 07:40:21 +0900127 void Close() {
128 if (hdc_)
129 DeleteDC(hdc_);
130 }
131
initial.commit3f4a7322008-07-27 06:49:38 +0900132 HDC hdc_;
133 DISALLOW_EVIL_CONSTRUCTORS(ScopedHDC);
134};
135
ben@chromium.orgfe675252008-10-14 04:52:38 +0900136// Like ScopedHandle but for GDI objects.
137template<class T>
138class ScopedGDIObject {
initial.commit3f4a7322008-07-27 06:49:38 +0900139 public:
ben@chromium.orgfe675252008-10-14 04:52:38 +0900140 ScopedGDIObject() : object_(NULL) {}
141 explicit ScopedGDIObject(T object) : object_(object) {}
initial.commit3f4a7322008-07-27 06:49:38 +0900142
ben@chromium.orgfe675252008-10-14 04:52:38 +0900143 ~ScopedGDIObject() {
jam@chromium.orgce03ce62008-09-23 07:40:21 +0900144 Close();
145 }
146
ben@chromium.orgfe675252008-10-14 04:52:38 +0900147 T Get() {
148 return object_;
jam@chromium.orge2cd5822008-10-01 09:38:11 +0900149 }
150
ben@chromium.orgfe675252008-10-14 04:52:38 +0900151 void Set(T object) {
152 if (object_ && object != object_)
153 Close();
154 object_ = object;
initial.commit3f4a7322008-07-27 06:49:38 +0900155 }
156
ben@chromium.orgfe675252008-10-14 04:52:38 +0900157 ScopedGDIObject& operator=(T object) {
158 Set(object);
initial.commit3f4a7322008-07-27 06:49:38 +0900159 return *this;
160 }
161
ben@chromium.orgfe675252008-10-14 04:52:38 +0900162 operator T() { return object_; }
163
initial.commit3f4a7322008-07-27 06:49:38 +0900164 private:
ben@chromium.orgfe675252008-10-14 04:52:38 +0900165 void Close() {
166 if (object_)
167 DeleteObject(object_);
168 }
169
170 T object_;
171 DISALLOW_COPY_AND_ASSIGN(ScopedGDIObject);
initial.commit3f4a7322008-07-27 06:49:38 +0900172};
173
ben@chromium.orgfe675252008-10-14 04:52:38 +0900174// Typedefs for some common use cases.
175typedef ScopedGDIObject<HBITMAP> ScopedBitmap;
176typedef ScopedGDIObject<HRGN> ScopedHRGN;
177typedef ScopedGDIObject<HFONT> ScopedHFONT;
178
179
initial.commit3f4a7322008-07-27 06:49:38 +0900180// Like ScopedHandle except for HGLOBAL.
181template<class T>
182class ScopedHGlobal {
183 public:
184 explicit ScopedHGlobal(HGLOBAL glob) : glob_(glob) {
185 data_ = static_cast<T*>(GlobalLock(glob_));
186 }
187 ~ScopedHGlobal() {
188 GlobalUnlock(glob_);
189 }
190
191 T* get() { return data_; }
192
193 size_t Size() const { return GlobalSize(glob_); }
194
195 T* operator->() const {
196 assert(data_ != 0);
197 return data_;
198 }
199
200 private:
201 HGLOBAL glob_;
202
203 T* data_;
204
205 DISALLOW_EVIL_CONSTRUCTORS(ScopedHGlobal);
206};
207
208#endif // BASE_SCOPED_HANDLE_H__
license.botf003cfe2008-08-24 09:55:55 +0900209