1use super::*;
9use crate::attributes;
10use crate::raw::RawComPtr;
11
12#[com_interface(
13 com_iid = "00000001-0000-0000-C000-000000000046",
14 raw_iid = "11111112-0000-0000-C000-000000000046"
15)]
16pub trait IClassFactory
17{
18 unsafe fn create_instance(&self, outer: RawComPtr, riid: REFIID) -> ComResult<RawComPtr>;
22
23 fn lock_server(&self, lock: bool) -> ComResult<()>;
24}
25
26#[doc(hidden)]
27#[com_class(IClassFactory)]
28pub struct ClassFactory<T: Default + intercom::attributes::ComClass>
29{
30 phantom: std::marker::PhantomData<T>,
31}
32
33impl<T: Default + attributes::ComClass> IClassFactory for ClassFactory<T>
34{
35 unsafe fn create_instance(&self, _outer: RawComPtr, riid: REFIID) -> ComResult<RawComPtr>
36 {
37 let instance = ComBox::new(T::default());
38 let mut out = std::ptr::null_mut();
39 let hr = ComBoxData::query_interface(instance.as_ref(), riid, &mut out);
40 if hr == raw::S_OK {
41 Ok(out)
42 } else {
43 Err(ComError::from(hr))
44 }
45 }
46
47 fn lock_server(&self, lock: bool) -> ComResult<()>
48 {
49 unsafe {
50 if lock {
51 ComBoxData::add_ref(ComBoxData::of(self));
52 } else {
53 ComBoxData::release(
54 ComBoxData::of(self) as *const ComBoxData<Self> as *mut ComBoxData<Self>
55 );
56 }
57 }
58 Ok(())
59 }
60}
61
62impl<T: Default + attributes::ComClass> ClassFactory<T>
63{
64 pub unsafe fn create(riid: intercom::REFIID, out: *mut RawComPtr)
68 -> crate::error::raw::HRESULT
69 {
70 let factory = Self {
71 phantom: std::marker::PhantomData,
72 };
73
74 intercom::ComBoxData::query_interface(intercom::ComBox::new(factory).as_mut(), riid, out)
75 }
76}