diff options
Diffstat (limited to 'toolkit/crashreporter/client/app/src/ui/windows/gdi.rs')
-rw-r--r-- | toolkit/crashreporter/client/app/src/ui/windows/gdi.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/toolkit/crashreporter/client/app/src/ui/windows/gdi.rs b/toolkit/crashreporter/client/app/src/ui/windows/gdi.rs new file mode 100644 index 0000000000..89828987bc --- /dev/null +++ b/toolkit/crashreporter/client/app/src/ui/windows/gdi.rs @@ -0,0 +1,43 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! GDI helpers. + +use windows_sys::Win32::{ + Foundation::HWND, + Graphics::Gdi::{self, GDI_ERROR, HDC, HGDIOBJ}, +}; + +/// A GDI drawing context. +pub struct DC { + hwnd: HWND, + hdc: HDC, +} + +impl DC { + /// Create a new DC. + pub fn new(hwnd: HWND) -> Option<Self> { + let hdc = unsafe { Gdi::GetDC(hwnd) }; + (hdc != 0).then_some(DC { hwnd, hdc }) + } + + /// Call the given function with a gdi object selected. + pub fn with_object_selected<R>(&self, object: HGDIOBJ, f: impl FnOnce(HDC) -> R) -> Option<R> { + let old_object = unsafe { Gdi::SelectObject(self.hdc, object) }; + if old_object == 0 || old_object == GDI_ERROR as isize { + return None; + } + let ret = f(self.hdc); + // The prior object must be selected before releasing the DC. Ignore errors; this is + // best-effort. + unsafe { Gdi::SelectObject(self.hdc, old_object) }; + Some(ret) + } +} + +impl Drop for DC { + fn drop(&mut self) { + unsafe { Gdi::ReleaseDC(self.hwnd, self.hdc) }; + } +} |