前回のCreateDispTypeInfoとCreateStdDispatchを使ってみるを書いた後、ATL::IDispatchImplとの組み合わせでも作れるのではないかと思い、やってみることにしました。
#define _ATL_NO_AUTOMATIC_NAMESPACE #include <iostream> #include <windows.h> #include <atlbase.h> #include <atlcom.h> #include <atlutil.h> class Module : public ATL::CAtlExeModuleT<Module> {}; Module module; // ダミー // {34F91FCB-7237-4EA7-B5E5-3FB7FDDD87AC} static constexpr CLSID CLSID_Hoge = { 0x34f91fcb, 0x7237, 0x4ea7, { 0xb5, 0xe5, 0x3f, 0xb7, 0xfd, 0xdd, 0x87, 0xac } }; interface DECLSPEC_UUID("6ae160da-9e37-4f46-83bd-bf166a82f871") IFunc2 : IDispatch { virtual void STDMETHODCALLTYPE Func() = 0; }; class ATL_NO_VTABLE Hoge : public ATL::CComObjectRootEx<ATL::CComMultiThreadModel> , public ATL::CComCoClass<Hoge> , public ATL::IDispatchImpl<IFunc2, &__uuidof(IFunc2)> { public: BEGIN_COM_MAP(Hoge) COM_INTERFACE_ENTRY(IFunc2) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() DECLARE_NO_REGISTRY() static void WINAPI ObjectMain(bool starting) { if (!starting) { _tihclass::Cleanup(reinterpret_cast<DWORD_PTR>(&_tih)); } } HRESULT FinalConstruct() { return InitializeTypeInfo(); } void STDMETHODCALLTYPE Func() override { std::cout << "Hoge::Invoke" << std::endl; } DECLARE_NOT_AGGREGATABLE(Hoge) private: static HRESULT InitializeTypeInfo() { auto& ti = _tih.m_pInfo; if (ti != nullptr) { return S_OK; } static METHODDATA md[] { { const_cast<OLECHAR*>(L"Func"), nullptr, DISPID_VALUE, 7, // 0~2はIUnknownの各メソッド、3~6はIDispatchの各メソッドのため。 CC_STDCALL, 0, DISPATCH_METHOD, VT_EMPTY }, }; static INTERFACEDATA id { md, ARRAYSIZE(md), }; return CreateDispTypeInfo(&id, LOCALE_SYSTEM_DEFAULT, &ti); } }; OBJECT_ENTRY_NON_CREATEABLE_EX_AUTO(CLSID_Hoge, Hoge) int main() { try { ATLENSURE_SUCCEEDED(CoInitializeEx( nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE)); ATL::CComPtr<IDispatch> hoge; ATLENSURE_SUCCEEDED(Hoge::CreateInstance(&hoge)); hoge.Invoke0(static_cast<DISPID>(DISPID_VALUE)); } catch (const ATL::CAtlException& e) { std::clog << std::hex << std::showbase; std::clog << e.m_hr << ' '; std::clog << ATL::AtlGetErrorDescription(e) << std::endl; } CoUninitialize(); } |
コード中に現れるtihclassと_tihは、ATL::IDispatchImpl
のprotectedメンバーです。
後始末をObjectMain関数でやることにしたため、OBJECT_ENTRY_NON_CREATEABLE_EX_AUTOを使用しています。
実験としてやってみたことです。実用性は考えていません。特段、コード量が減るわけでもないので、私は前回の方法でいいやと思いました。
スポンサード リンク |