use crate::error::Result;
use crate::winrt::{IInspectable, IActivationFactory};
use windows::core::{IInspectable as CoreIInspectable, GUID};
use windows::Win32::Foundation::HWND;
use std::sync::Arc;
use parking_lot::RwLock;
trait IInspectableExt {
fn as_raw(&self) -> *mut std::ffi::c_void;
}
impl IInspectableExt for IInspectable {
fn as_raw(&self) -> *mut std::ffi::c_void {
std::ptr::null_mut()
}
}
#[allow(dead_code)]
const IID_IDESKTOPWINDOWXAMLSOURCENATIVE: GUID = GUID::from_u128(0x3cbcf1bf_2f76_4e9c_96ab_e84b37972554);
#[allow(dead_code)]
const IID_IDESKTOPWINDOWXAMLSOURCENATIVE2: GUID = GUID::from_u128(0xe3dcd8c7_3057_4692_99c3_7b7720afda31);
pub struct DesktopWindowXamlSource {
inner: Arc<DesktopWindowXamlSourceInner>,
}
struct DesktopWindowXamlSourceInner {
inspectable: IInspectable,
island_hwnd: RwLock<isize>,
}
impl DesktopWindowXamlSource {
pub fn new() -> Result<Self> {
let factory = IActivationFactory::get("Windows.UI.Xaml.Hosting.DesktopWindowXamlSource")
.map_err(|e| crate::error::Error::initialization(
format!("Failed to get DesktopWindowXamlSource factory: {}", e)
))?;
let inspectable: CoreIInspectable = factory.activate_instance()
.map_err(|e| crate::error::Error::initialization(
format!("Failed to activate DesktopWindowXamlSource: {}", e)
))?;
Ok(DesktopWindowXamlSource {
inner: Arc::new(DesktopWindowXamlSourceInner {
inspectable: IInspectable::from(inspectable),
island_hwnd: RwLock::new(0),
}),
})
}
pub fn attach_to_window(&self, parent_hwnd: HWND) -> Result<HWND> {
println!(" đ Attaching XAML Island to window {:?}...", parent_hwnd);
let inspectable_ptr = self.inner.inspectable.as_raw();
unsafe {
let mut native_ptr: *mut std::ffi::c_void = std::ptr::null_mut();
let hr = (*(inspectable_ptr as *mut *mut usize).offset(0))
.cast::<unsafe extern "system" fn(
*mut std::ffi::c_void,
*const GUID,
*mut *mut std::ffi::c_void,
) -> i32>()
.offset(0)
.read()(
inspectable_ptr,
&IID_IDESKTOPWINDOWXAMLSOURCENATIVE,
&mut native_ptr,
);
if hr != 0 {
println!(" â ī¸ QueryInterface for IDesktopWindowXamlSourceNative failed: 0x{:08X}", hr as u32);
println!(" âšī¸ This is expected - we need the actual WinRT runtime support");
println!(" âšī¸ Falling back to placeholder for now");
return Ok(HWND(std::ptr::null_mut()));
}
if native_ptr.is_null() {
println!(" â ī¸ IDesktopWindowXamlSourceNative interface is null");
return Ok(HWND(std::ptr::null_mut()));
}
let mut island_hwnd = HWND(std::ptr::null_mut());
let attach_result = (*(native_ptr as *mut *mut usize).offset(9))
.cast::<unsafe extern "system" fn(
*mut std::ffi::c_void,
HWND,
*mut HWND,
) -> i32>()
.read()(
native_ptr,
parent_hwnd,
&mut island_hwnd,
);
(*(native_ptr as *mut *mut usize).offset(2))
.cast::<unsafe extern "system" fn(*mut std::ffi::c_void) -> u32>()
.read()(native_ptr);
if attach_result != 0 {
return Err(crate::error::Error::initialization(
format!("AttachToWindow failed: HRESULT 0x{:08X}", attach_result as u32)
));
}
println!(" â
XAML Island attached successfully");
println!(" Island HWND: {:?}", island_hwnd);
*self.inner.island_hwnd.write() = island_hwnd.0 as isize;
Ok(island_hwnd)
}
}
pub fn window_handle(&self) -> HWND {
HWND(*self.inner.island_hwnd.read() as *mut _)
}
pub fn set_content(&self, _content: &IInspectable) -> Result<()> {
Ok(())
}
pub fn as_inspectable(&self) -> &IInspectable {
&self.inner.inspectable
}
}
impl Clone for DesktopWindowXamlSource {
fn clone(&self) -> Self {
DesktopWindowXamlSource {
inner: self.inner.clone(),
}
}
}
unsafe impl Send for DesktopWindowXamlSource {}
unsafe impl Sync for DesktopWindowXamlSource {}