diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-14 03:37:14 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-14 03:37:14 +0000 |
commit | 46db9f43fe29b92895d3138a22d3bc042632135a (patch) | |
tree | 00d16d75a583afb05e3df73d76ff04b0b5562bb6 /base/win/scoped_hdc.h | |
parent | c6aef90f9f927ac75bb99d6d77782fc33c37769d (diff) | |
download | chromium_src-46db9f43fe29b92895d3138a22d3bc042632135a.zip chromium_src-46db9f43fe29b92895d3138a22d3bc042632135a.tar.gz chromium_src-46db9f43fe29b92895d3138a22d3bc042632135a.tar.bz2 |
Make scoped dc objects smarter
So we don't destroy the dc with gdi objects selected.
Also remove implicit conversion to HDC.
BUG=110113,113683
TEST=chrome runs, base unittests green.
Review URL: https://chromiumcodereview.appspot.com/9212020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121840 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/win/scoped_hdc.h')
-rw-r--r-- | base/win/scoped_hdc.h | 112 |
1 files changed, 67 insertions, 45 deletions
diff --git a/base/win/scoped_hdc.h b/base/win/scoped_hdc.h index 9e2ea62..2a93b95 100644 --- a/base/win/scoped_hdc.h +++ b/base/win/scoped_hdc.h @@ -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,69 +9,91 @@ #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() { return hdc_; } - ~ScopedGetDC() { - if (hdc_) - ReleaseDC(hwnd_, hdc_); - } + void SelectBitmap(HBITMAP bitmap); + void SelectFont(HFONT font); + void SelectBrush(HBRUSH brush); + void SelectPen(HPEN pen); + void SelectRegion(HRGN region); - operator HDC() { return hdc_; } + protected: + ScopedDC(HDC hdc); + void Close(); + void Reset(HDC hdc); private: - HWND hwnd_; + void ResetObjects(); + void Select(HGDIOBJ object, HGDIOBJ* holder); + HDC hdc_; + HGDIOBJ bitmap_; + HGDIOBJ font_; + HGDIOBJ brush_; + HGDIOBJ pen_; + HGDIOBJ region_; +}; + +// Creates and manages an HDC obtained by GetDC. +class ScopedGetDC : public ScopedDC { + public: + explicit ScopedGetDC(HWND hwnd); + virtual ~ScopedGetDC(); + private: + virtual void DisposeDC(HDC hdc) OVERRIDE; + + HWND hwnd_; 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(); - } - - HDC Get() { - return hdc_; - } - - void Set(HDC h) { - Close(); - hdc_ = h; - } - - operator HDC() { return hdc_; } + ScopedCreateDC(); + explicit ScopedCreateDC(HDC hdc); + virtual ~ScopedCreateDC(); + void Set(HDC hdc); private: - void Close() { -#ifdef NOGDI - assert(false); -#else - if (hdc_) - DeleteDC(hdc_); -#endif // NOGDI - } - - HDC hdc_; + virtual void DisposeDC(HDC hdc) OVERRIDE; DISALLOW_COPY_AND_ASSIGN(ScopedCreateDC); }; |