use windows::{
Win32::Foundation::HWND,
Win32::Graphics::Gdi::{GetDC, GetWindowDC, ReleaseDC},
};
pub fn get_window_client_dc(hwnd: HWND) -> Option<windows::Win32::Graphics::Gdi::HDC> {
if hwnd.0.is_null() {
return None;
}
unsafe {
let hdc = GetDC(Some(hwnd));
if hdc.0.is_null() {
None
} else {
Some(hdc)
}
}
}
pub fn get_window_dc(hwnd: HWND) -> Option<windows::Win32::Graphics::Gdi::HDC> {
if hwnd.0.is_null() {
return None;
}
unsafe {
let hdc = GetWindowDC(Some(hwnd));
if hdc.0.is_null() {
None
} else {
Some(hdc)
}
}
}
pub fn get_desktop_dc() -> Option<windows::Win32::Graphics::Gdi::HDC> {
use windows::Win32::UI::WindowsAndMessaging::GetDesktopWindow;
unsafe {
let desktop_hwnd = GetDesktopWindow();
let hdc = GetDC(Some(desktop_hwnd));
if hdc.0.is_null() {
None
} else {
Some(hdc)
}
}
}
pub fn release_dc(hwnd: HWND, hdc: windows::Win32::Graphics::Gdi::HDC) -> bool {
if hwnd.0.is_null() || hdc.0.is_null() {
return false;
}
unsafe {
let result = ReleaseDC(Some(hwnd), hdc);
result == 1
}
}
pub fn release_desktop_dc(hdc: windows::Win32::Graphics::Gdi::HDC) -> bool {
use windows::Win32::UI::WindowsAndMessaging::GetDesktopWindow;
if hdc.0.is_null() {
return false;
}
unsafe {
let desktop_hwnd = GetDesktopWindow();
let result = ReleaseDC(Some(desktop_hwnd), hdc);
result == 1
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::hwnd::get_hwnd_list;
#[test]
fn test_get_window_client_dc() {
let hwnds = get_hwnd_list();
if let Some(&hwnd) = hwnds.first() {
if let Some(hdc) = get_window_client_dc(hwnd) {
println!("Got client DC for window {:?}", hwnd);
assert!(!hdc.0.is_null(), "DC should not be null");
let released = release_dc(hwnd, hdc);
assert!(released, "Should successfully release DC");
}
}
}
#[test]
fn test_get_window_dc() {
let hwnds = get_hwnd_list();
if let Some(&hwnd) = hwnds.first() {
if let Some(hdc) = get_window_dc(hwnd) {
println!("Got window DC for window {:?}", hwnd);
assert!(!hdc.0.is_null(), "DC should not be null");
let released = release_dc(hwnd, hdc);
assert!(released, "Should successfully release DC");
}
}
}
#[test]
fn test_get_desktop_dc() {
if let Some(hdc) = get_desktop_dc() {
println!("Got desktop DC");
assert!(!hdc.0.is_null(), "Desktop DC should not be null");
let released = release_desktop_dc(hdc);
assert!(released, "Should successfully release desktop DC");
}
}
#[test]
fn test_release_invalid_dc() {
let result = release_dc(
HWND::default(),
windows::Win32::Graphics::Gdi::HDC::default(),
);
assert!(!result, "Should fail to release invalid DC");
let result = release_desktop_dc(windows::Win32::Graphics::Gdi::HDC::default());
assert!(!result, "Should fail to release invalid desktop DC");
}
#[test]
fn test_dc_lifecycle() {
let hwnds = get_hwnd_list();
if let Some(&hwnd) = hwnds.first() {
if let Some(hdc) = get_window_client_dc(hwnd) {
println!("Using client DC: {:?}", hdc);
assert!(release_dc(hwnd, hdc));
println!("DC released successfully");
}
if let Some(hdc) = get_window_dc(hwnd) {
println!("Using window DC: {:?}", hdc);
assert!(release_dc(hwnd, hdc));
}
}
if let Some(hdc) = get_desktop_dc() {
println!("Using desktop DC: {:?}", hdc);
assert!(release_desktop_dc(hdc));
}
}
}