use std::ffi::c_void;
use std::ops::{Deref, DerefMut};
use winapi::um::wingdi::DeleteObject;
#[derive(Debug)]
pub struct GdiObject<T>(*mut T);
impl<T> GdiObject<T> {
pub fn new() -> GdiObject<T> {
GdiObject(std::ptr::null_mut())
}
pub fn as_raw(&mut self) -> *mut T {
self.0
}
}
impl<T> Default for GdiObject<T> {
fn default() -> GdiObject<T> {
GdiObject::new()
}
}
impl<T> Deref for GdiObject<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.0 }
}
}
impl<T> DerefMut for GdiObject<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.0 }
}
}
impl<T> Drop for GdiObject<T> {
fn drop(&mut self) {
unsafe {
DeleteObject(self.0 as *mut c_void);
}
}
}
pub fn gdi_call<TFunction, T>(function: TFunction) -> Result<GdiObject<T>, std::io::Error>
where
TFunction: FnOnce() -> *mut T,
{
let pointer = function();
if !pointer.is_null() {
Ok(GdiObject(pointer))
} else {
Err(std::io::Error::last_os_error())
}
}