summaryrefslogtreecommitdiffstats
path: root/base/win/scoped_hdc.h
diff options
context:
space:
mode:
authorcpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-14 03:37:14 +0000
committercpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-14 03:37:14 +0000
commit46db9f43fe29b92895d3138a22d3bc042632135a (patch)
tree00d16d75a583afb05e3df73d76ff04b0b5562bb6 /base/win/scoped_hdc.h
parentc6aef90f9f927ac75bb99d6d77782fc33c37769d (diff)
downloadchromium_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.h112
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);
};