Home | History | Annotate | Download | only in base
      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