use com::interfaces::IUnknown;
use com::sys::{HRESULT, S_OK};
use std::sync::{Arc, Mutex};
com::interfaces! {
#[uuid("DA66D884-6DA8-410E-9630-8C48F8B3A40E")]
pub unsafe interface ICoreWebView2Environment : IUnknown {}
#[uuid("8B4F98CE-DB0D-4E71-85FD-C4C4EF1F2630")]
pub unsafe interface ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler : IUnknown {
unsafe fn invoke(
&self,
result: HRESULT,
created_environment: ICoreWebView2Environment
) -> HRESULT;
}
}
com::class! {
pub class CreateCoreWebView2EnvironmentCompletedHandler : ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler {
destination: Arc<Mutex<Option<ICoreWebView2Environment>>>,
}
impl ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler for CreateCoreWebView2EnvironmentCompletedHandler {
fn invoke(
&self,
result: HRESULT,
created_environment: ICoreWebView2Environment
) -> HRESULT
{
if result == S_OK {
self.destination.lock().unwrap().replace(created_environment);
}
result
}
}
}
#[allow(non_snake_case)]
unsafe fn CreateCoreWebView2Environment(
_environment_created_handler: ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler,
) {
panic!("Called stub function. Uncomment out the extern function from WebViewLoader dll.\n\nNote: this only works on Windows.")
}
pub struct Environment {
#[allow(unused)]
raw: ICoreWebView2Environment,
}
impl Environment {
pub fn create() -> Environment {
#[cfg(windows)]
com::runtime::init_apartment(com::runtime::ApartmentType::SingleThreaded)
.expect("Failed to initialize COM.");
let environment = Arc::new(Mutex::new(None));
let handler_class =
CreateCoreWebView2EnvironmentCompletedHandler::allocate(environment.clone());
let handler_interface = handler_class
.query_interface::<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>()
.unwrap();
unsafe {
CreateCoreWebView2Environment(handler_interface);
}
drop(handler_class);
Environment {
raw: Arc::try_unwrap(environment) .unwrap() .into_inner() .unwrap() .unwrap(), }
}
}
fn main() {
let _environment = Environment::create();
}