Chromium Code Reviews| Index: base/win/scoped_hdc.h |
| =================================================================== |
| --- base/win/scoped_hdc.h (revision 121154) |
| +++ base/win/scoped_hdc.h (working copy) |
| @@ -1,4 +1,4 @@ |
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| @@ -9,70 +9,118 @@ |
| #include <windows.h> |
| #include "base/basictypes.h" |
| -#include "base/logging.h" |
| +#include "base/compiler_specific.h" |
| namespace base { |
| namespace win { |
| -// Like ScopedHandle but for HDC. Only use this on HDCs returned from |
| -// GetDC. |
| -class ScopedGetDC { |
| +// The ScopedGetDC and ScopedCreateDC classes manage the default GDI objects |
| +// that are initially selected into a DC. They help you avoid the following |
| +// common mistake: |
| +// |
| +// HDC hdc = GetDC(NULL); |
| +// SelectObject(hdc, new_bitmap); |
| +// .. drawing code here .. |
| +// ReleaseDC(hdc); <--- error: the DC has a custom object still selected! |
| +// |
| +// This code should be: |
| +// |
| +// HDC hdc = GetDC(NULL); |
| +// HGDIOBJ old_obj = SelectObject(hdc, new_bitmap); |
| +// .. drawing code here .. |
| +// SelectObject(hdc, old_obj); |
| +// ReleaseDC(hdc); <--- ok to release now. |
| +// |
| +// But why work so hard? Use our handy classes: |
| +// |
| +// ScopedGetDC dc(NULL); |
| +// dc.SelectBitmap(hdc, new_bitmap); |
| +// .. drawing here |
| +// .. when dc goes out of scope it will select the original object before |
| +// .. being released. |
| +// |
| +class ScopedDC { |
| public: |
| - explicit ScopedGetDC(HWND hwnd) |
| - : hwnd_(hwnd), |
| - hdc_(GetDC(hwnd)) { |
| - DCHECK(!hwnd_ || IsWindow(hwnd_)); |
| - DCHECK(hdc_); |
| + virtual ~ScopedDC(); |
| + |
| + virtual void DisposeDC(HDC hdc) = 0; |
| + |
| + HDC get() { |
|
Peter Kasting
2012/02/10 19:47:39
Nit: Whole def'n can all be on one line
|
| + return hdc_; |
| } |
| - ~ScopedGetDC() { |
| - if (hdc_) |
| - ReleaseDC(hwnd_, hdc_); |
| + void SelectBitmap(HBITMAP bitmap); |
| + |
|
Peter Kasting
2012/02/10 19:47:39
Nit: I'd remove the newlines between these
|
| + void SelectFont(HFONT font); |
| + |
| + void SelectBrush(HBRUSH brush); |
| + |
| + void SelectPen(HPEN pen); |
| + |
| + void SelectRegion(HRGN region); |
| + |
| + protected: |
| + ScopedDC(HDC hdc); |
| + |
| + void Close(); |
| + |
| + void Reset(HDC hdc); |
| + |
| + private: |
| + void ResetObjects(); |
| + |
| + void Select(HGDIOBJ object, HGDIOBJ* holder); |
| + |
| + HDC hdc_; |
| + HGDIOBJ bitmap_; |
| + HGDIOBJ font_; |
| + HGDIOBJ brush_; |
| + HGDIOBJ pen_; |
| + HGDIOBJ region_; |
| +}; |
|
Peter Kasting
2012/02/10 19:47:39
Nit: DISALLOW_COPY_AND_ASSIGN?
|
| + |
| +// Creates and manages an HDC obtained by GetDC. |
| +class ScopedGetDC : public ScopedDC { |
| + public: |
| + explicit ScopedGetDC(HWND hwnd) : ScopedDC(GetDC(hwnd)), hwnd_(hwnd) { |
| } |
| - operator HDC() { return hdc_; } |
| + virtual ~ScopedGetDC() { |
|
Peter Kasting
2012/02/10 19:47:39
Nit: Never inline virtual functions or other funct
|
| + Close(); |
| + } |
| private: |
| + virtual void DisposeDC(HDC hdc) OVERRIDE { |
| + ReleaseDC(hwnd_, hdc); |
| + } |
| + |
| HWND hwnd_; |
| - HDC hdc_; |
| - |
| DISALLOW_COPY_AND_ASSIGN(ScopedGetDC); |
| }; |
| // Like ScopedHandle but for HDC. Only use this on HDCs returned from |
| // CreateCompatibleDC, CreateDC and CreateIC. |
| -class ScopedCreateDC { |
| +class ScopedCreateDC : public ScopedDC { |
| public: |
| - ScopedCreateDC() : hdc_(NULL) { } |
| - explicit ScopedCreateDC(HDC h) : hdc_(h) { } |
| - |
| - ~ScopedCreateDC() { |
| - Close(); |
| + ScopedCreateDC() : ScopedDC(0) { |
| } |
| - HDC Get() { |
| - return hdc_; |
| + explicit ScopedCreateDC(HDC hdc) : ScopedDC(hdc) { |
| } |
| - void Set(HDC h) { |
| + virtual ~ScopedCreateDC() { |
| Close(); |
| - hdc_ = h; |
| } |
| - operator HDC() { return hdc_; } |
| + void Set(HDC hdc) { |
| + Reset(hdc); |
| + } |
| private: |
| - void Close() { |
| -#ifdef NOGDI |
| - assert(false); |
| -#else |
| - if (hdc_) |
| - DeleteDC(hdc_); |
| -#endif // NOGDI |
| + virtual void DisposeDC(HDC hdc) OVERRIDE { |
| + DeleteDC(hdc); |
| } |
| - HDC hdc_; |
| - |
| DISALLOW_COPY_AND_ASSIGN(ScopedCreateDC); |
| }; |