use std::ffi::OsStr;
use std::fmt;
use std::io;
use std::ptr;
use windows_sys::Win32::Foundation::HWND;
use windows_sys::Win32::System::DataExchange::COPYDATASTRUCT;
use windows_sys::Win32::UI::WindowsAndMessaging::FindWindowExW;
use windows_sys::Win32::UI::WindowsAndMessaging::SendMessageW;
use windows_sys::Win32::UI::WindowsAndMessaging::WM_COPYDATA;
use crate::convert::ToWide;
#[derive(Default)]
pub struct FindWindow {
class: Option<Vec<u16>>,
title: Option<Vec<u16>>,
}
impl FindWindow {
#[inline]
pub fn new() -> Self {
Self::default()
}
pub fn class<C>(&mut self, class: C) -> &mut Self
where
C: AsRef<OsStr>,
{
self.class = Some(class.as_ref().to_wide_null());
self
}
pub fn title<T>(&mut self, title: T) -> &mut Self
where
T: AsRef<OsStr>,
{
self.title = Some(title.as_ref().to_wide_null());
self
}
pub fn find(&self) -> io::Result<Option<Window>> {
unsafe {
let hwnd = FindWindowExW(
ptr::null_mut(),
ptr::null_mut(),
self.class.as_ref().map_or(ptr::null(), |c| c.as_ptr()),
self.title.as_ref().map_or(ptr::null(), |c| c.as_ptr()),
);
if hwnd.is_null() {
return Err(io::Error::last_os_error());
}
Ok(Some(Window { hwnd }))
}
}
}
pub struct Window {
hwnd: HWND,
}
impl Window {
pub fn copy_data(&self, ty: usize, bytes: &[u8]) -> io::Result<()> {
unsafe {
let data = COPYDATASTRUCT {
dwData: ty,
cbData: bytes.len() as u32,
lpData: (bytes.as_ptr() as *mut u8).cast(),
};
SendMessageW(self.hwnd, WM_COPYDATA, 0, &data as *const _ as isize);
Ok(())
}
}
}
impl fmt::Debug for Window {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Window").field("hwnd", &self.hwnd).finish()
}
}
unsafe impl Send for Window {}
unsafe impl Sync for Window {}