diff --git a/src/graphics_capture_api.rs b/src/graphics_capture_api.rs index 3ae24b8..8a084f2 100644 --- a/src/graphics_capture_api.rs +++ b/src/graphics_capture_api.rs @@ -113,7 +113,7 @@ impl GraphicsCaptureApi { // Create Frame Pool trace!("Creating Frame Pool"); let frame_pool = - Direct3D11CaptureFramePool::Create(&direct3d_device, pixel_format, 2, item.Size()?)?; + Direct3D11CaptureFramePool::Create(&direct3d_device, pixel_format, 1, item.Size()?)?; let frame_pool = Arc::new(frame_pool); // Create Capture Session @@ -211,7 +211,7 @@ impl GraphicsCaptureApi { .Recreate( &direct3d_device_recreate.0, pixel_format, - 2, + 1, frame_content_size, ) .unwrap(); diff --git a/src/monitor.rs b/src/monitor.rs index 80c803a..0a7f9e4 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -1,7 +1,7 @@ use std::{mem, num::ParseIntError, ptr, string::FromUtf16Error}; use windows::{ - core::PCWSTR, + core::{HSTRING, PCWSTR}, Graphics::Capture::GraphicsCaptureItem, Win32::{ Devices::Display::{ @@ -14,8 +14,9 @@ use windows::{ }, Foundation::{BOOL, LPARAM, POINT, RECT, TRUE}, Graphics::Gdi::{ - EnumDisplayDevicesW, EnumDisplayMonitors, GetMonitorInfoW, MonitorFromPoint, - DISPLAY_DEVICEW, HDC, HMONITOR, MONITORINFO, MONITORINFOEXW, MONITOR_DEFAULTTOPRIMARY, + EnumDisplayDevicesW, EnumDisplayMonitors, EnumDisplaySettingsW, GetMonitorInfoW, + MonitorFromPoint, DEVMODEW, DISPLAY_DEVICEW, ENUM_CURRENT_SETTINGS, HDC, HMONITOR, + MONITORINFO, MONITORINFOEXW, MONITOR_DEFAULTTONULL, }, System::WinRT::Graphics::Capture::IGraphicsCaptureItemInterop, }, @@ -32,6 +33,8 @@ pub enum Error { IndexIsLowerThanOne, #[error("Failed To Get Monitor Info")] FailedToGetMonitorInfo, + #[error("Failed To Get Monitor ettings")] + FailedToGetMonitorSettings, #[error("Failed To Get Monitor Name")] FailedToGetMonitorName, #[error(transparent)] @@ -52,7 +55,7 @@ impl Monitor { /// Get The Primary Monitor pub fn primary() -> Result { let point = POINT { x: 0, y: 0 }; - let monitor = unsafe { MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY) }; + let monitor = unsafe { MonitorFromPoint(point, MONITOR_DEFAULTTONULL) }; if monitor.is_invalid() { return Err(Error::NotFound); @@ -145,7 +148,7 @@ impl Monitor { .iter() .take_while(|ch| **ch != 0x0000) .copied() - .collect::>(), + .collect::>(), )?; if unsafe { DisplayConfigGetDeviceInfo(&mut source.header) } == 0 @@ -176,7 +179,7 @@ impl Monitor { .iter() .take_while(|ch| **ch != 0x0000) .copied() - .collect::>(), + .collect::>(), )?; return Ok(name); } @@ -216,7 +219,7 @@ impl Monitor { .iter() .take_while(|ch| **ch != 0x0000) .copied() - .collect::>(), + .collect::>(), )?; Ok(device_name) @@ -271,12 +274,75 @@ impl Monitor { .iter() .take_while(|ch| **ch != 0x0000) .copied() - .collect::>(), + .collect::>(), )?; Ok(device_string) } + /// Get Monitor Width + pub fn width(&self) -> Result { + let mut device_mode = DEVMODEW { + dmSize: u16::try_from(mem::size_of::()).unwrap(), + ..DEVMODEW::default() + }; + let name = HSTRING::from(self.device_name()?); + if unsafe { + !EnumDisplaySettingsW( + PCWSTR(name.as_ptr()), + ENUM_CURRENT_SETTINGS, + &mut device_mode, + ) + .as_bool() + } { + return Err(Error::FailedToGetMonitorSettings); + } + + Ok(device_mode.dmPelsWidth) + } + + /// Get Monitor Height + pub fn height(&self) -> Result { + let mut device_mode = DEVMODEW { + dmSize: u16::try_from(mem::size_of::()).unwrap(), + ..DEVMODEW::default() + }; + let name = HSTRING::from(self.device_name()?); + if unsafe { + !EnumDisplaySettingsW( + PCWSTR(name.as_ptr()), + ENUM_CURRENT_SETTINGS, + &mut device_mode, + ) + .as_bool() + } { + return Err(Error::FailedToGetMonitorSettings); + } + + Ok(device_mode.dmPelsHeight) + } + + /// Get Monitor Refresh Rate + pub fn refresh_rate(&self) -> Result { + let mut device_mode = DEVMODEW { + dmSize: u16::try_from(mem::size_of::()).unwrap(), + ..DEVMODEW::default() + }; + let name = HSTRING::from(self.device_name()?); + if unsafe { + !EnumDisplaySettingsW( + PCWSTR(name.as_ptr()), + ENUM_CURRENT_SETTINGS, + &mut device_mode, + ) + .as_bool() + } { + return Err(Error::FailedToGetMonitorSettings); + } + + Ok(device_mode.dmDisplayFrequency) + } + /// Get A List Of All Monitors pub fn enumerate() -> Result, Error> { let mut monitors: Vec = Vec::new(); diff --git a/src/window.rs b/src/window.rs index 67c9408..1307a46 100644 --- a/src/window.rs +++ b/src/window.rs @@ -6,6 +6,7 @@ use windows::{ Graphics::Capture::GraphicsCaptureItem, Win32::{ Foundation::{BOOL, HWND, LPARAM, RECT, TRUE}, + Graphics::Gdi::{MonitorFromWindow, MONITOR_DEFAULTTONULL}, System::{ Threading::GetCurrentProcessId, WinRT::Graphics::Capture::IGraphicsCaptureItemInterop, }, @@ -17,6 +18,8 @@ use windows::{ }, }; +use crate::monitor::Monitor; + /// Used To Handle Window Errors #[derive(thiserror::Error, Debug)] pub enum Error { @@ -99,6 +102,20 @@ impl Window { Ok(name) } + /// Get The Monitor That Has The Largest Area Of Intersection With The Window, None Means Windows Doesn't Intersect With Any Monitor + #[must_use] + pub fn monitor(&self) -> Option { + let window = self.window; + + let monitor = unsafe { MonitorFromWindow(window, MONITOR_DEFAULTTONULL) }; + + if monitor.is_invalid() { + None + } else { + Some(Monitor::from_raw_hmonitor(monitor)) + } + } + /// Check If The Window Is A Valid Window #[must_use] pub fn is_window_valid(window: HWND) -> bool {