#![allow(non_camel_case_types, non_snake_case)]
use crate::co;
use crate::decl::*;
use crate::kernel::privs::*;
use crate::macros::*;
use crate::ole::privs::*;
use crate::oleaut::vts::*;
use crate::prelude::*;
com_interface! { IDispatch: "00020400-0000-0000-c000-000000000046";
}
impl oleaut_IDispatch for IDispatch {}
pub trait oleaut_IDispatch: ole_IUnknown {
#[must_use]
fn GetIDsOfNames(&self, names: &[impl AsRef<str>], lcid: LCID) -> HrResult<Vec<i32>> {
let (_wstrs, pwstrs) = create_wstr_ptr_vecs(names);
let mut ids = vec![0i32; names.len()];
HrRet(unsafe {
(vt::<IDispatchVT>(self).GetIDsOfNames)(
self.ptr(),
pcvoid(&co::IID::default()),
vec_ptr(&pwstrs),
names.len() as _,
lcid.into(),
ids.as_mut_ptr() as _,
)
})
.to_hrresult()
.map(|_| ids)
}
#[must_use]
fn GetTypeInfoCount(&self) -> HrResult<u32> {
let mut count = 0u32;
HrRet(unsafe { (vt::<IDispatchVT>(self).GetTypeInfoCount)(self.ptr(), &mut count) })
.to_hrresult()
.map(|_| count)
}
#[must_use]
fn GetTypeInfo(&self, info_type: u32, lcid: LCID) -> HrResult<ITypeInfo> {
let mut queried = unsafe { ITypeInfo::null() };
HrRet(unsafe {
(vt::<IDispatchVT>(self).GetTypeInfo)(
self.ptr(),
info_type,
lcid.into(),
queried.as_mut(),
)
})
.to_hrresult()
.map(|_| queried)
}
fn Invoke(
&self,
disp_id_member: i32,
lcid: LCID,
flags: co::DISPATCH,
disp_params: &mut DISPPARAMS,
) -> AnyResult<VARIANT> {
let mut remote_res = VARIANT::default();
let mut remote_err = EXCEPINFO::default();
let mut arg_err = 0u32;
match HrRet(unsafe {
(vt::<IDispatchVT>(self).Invoke)(
self.ptr(),
disp_id_member,
pcvoid(&GUID::NULL),
lcid.raw(),
flags.raw(),
pvoid(disp_params),
pvoid(&mut remote_res),
pvoid(&mut remote_err),
&mut arg_err,
)
})
.to_hrresult()
{
Ok(_) => Ok(remote_res),
Err(hr) => match hr {
co::HRESULT::DISP_E_EXCEPTION => Err(Box::new(remote_err)),
_ => Err(hr.into()),
},
}
}
fn invoke_get(&self, property_name: &str, params: &[&Variant]) -> AnyResult<Variant> {
let member_ids = self.GetIDsOfNames(&[property_name], LCID::USER_DEFAULT)?;
let mut vars = params
.iter()
.rev() .map(|param| param.to_raw())
.collect::<HrResult<Vec<_>>>()?;
let mut dp = DISPPARAMS::default();
dp.set_rvarg(Some(&mut vars));
let vari =
self.Invoke(member_ids[0], LCID::USER_DEFAULT, co::DISPATCH::PROPERTYGET, &mut dp)?;
Variant::from_raw(&vari).map_err(|err| err.into())
}
fn invoke_method(&self, method_name: &str, params: &[&Variant]) -> AnyResult<Variant> {
let member_ids = self.GetIDsOfNames(&[method_name], LCID::USER_DEFAULT)?;
let mut vars = params
.iter()
.rev() .map(|param| param.to_raw())
.collect::<HrResult<Vec<_>>>()?;
let mut dp = DISPPARAMS::default();
dp.set_rvarg(Some(&mut vars));
let vari = self.Invoke(member_ids[0], LCID::USER_DEFAULT, co::DISPATCH::METHOD, &mut dp)?;
Variant::from_raw(&vari).map_err(|err| err.into())
}
fn invoke_put(&self, property_name: &str, param: &Variant) -> AnyResult<Variant> {
let member_ids = self.GetIDsOfNames(&[property_name], LCID::USER_DEFAULT)?;
let mut vars = vec![param.to_raw()?]; let mut named_args = vec![co::DISPID::PROPERTYPUT];
let mut dp = DISPPARAMS::default();
dp.set_rvarg(Some(&mut vars));
dp.set_rgdispidNamedArgs(Some(&mut named_args));
let vari =
self.Invoke(member_ids[0], LCID::USER_DEFAULT, co::DISPATCH::PROPERTYPUT, &mut dp)?;
Variant::from_raw(&vari).map_err(|err| err.into())
}
}