RegisterActiveObject関数は内部でRunning Object Table (ROT)を使っていると、MSDNライブラリにも書かれてあります: Registration Functions (Automation)。
ROTは、モニカーをキーとしてオブジェクトを登録する、つまり連想配列のようなものです。ならば、クラスIDをキーに登録するRegisterActiveObjectはどういうモニカーでROTに登録するのか、ということを知りたくなりました。
調べた結果、クラスIDの文字列のアイテムモニカーであることが分かりました。すなわち、モニカーの文字列表現は"!{XXXXXXXX-……}"
という形式になります。
今回のサンプルプログラムは、RegisterActiveObjectで登録したオブジェクトをIRunningObjectTable::GetObjectで取り出したり、IRunningObjectTable::Registerで登録したオブジェクトをGetActiveObjectで取り出したりするというものです。
#define UNICODE #define _UNICODE #define WIN32_LEAN_AND_MEAN #define _ATL_NO_AUTOMATIC_NAMESPACE #include <iostream> #include <cstdlib> #include <windows.h> #include <atlbase.h> #include <atlcom.h> #include <atlutil.h> // {EECAE0DA-5F2B-48E2-9F22-09A788DA83FE} static const GUID CLSID_Hoge = { 0xeecae0da, 0x5f2b, 0x48e2, { 0x9f, 0x22, 0x9, 0xa7, 0x88, 0xda, 0x83, 0xfe } }; struct Hoge : IUnknown { IFACEMETHOD(QueryInterface)(REFIID riid, void** ppv) override { if (riid == IID_IUnknown) { *ppv = (IUnknown*)this; return S_OK; } return E_NOINTERFACE; } IFACEMETHOD_(DWORD, AddRef)() override { return 1; } IFACEMETHOD_(DWORD, Release)() override { return 1; } }; void ExitIfFailed(_In_ PCWSTR functionName, HRESULT hr) { if (SUCCEEDED(hr)) { return; } std::wclog << functionName << '\n'; std::wclog << std::showbase << std::hex << hr << '\n'; std::wclog << ATL::AtlGetErrorDescription(hr).GetString() << std::endl; std::quick_exit(static_cast<int>(hr)); } int main() { std::wclog.imbue(std::locale("")); auto hrInit = CoInitializeEx( nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); ExitIfFailed(L"CoInitializeEx", hrInit); ATL::CComPtr<IRunningObjectTable> rot; auto hrRot = GetRunningObjectTable(0, &rot); ExitIfFailed(L"GetRunningObjectTable", hrRot); ATL::CComPtr<IMoniker> mk; auto hrMk = CreateItemMoniker( L"!", L"{EECAE0DA-5F2B-48E2-9F22-09A788DA83FE}", &mk); ExitIfFailed(L"CreateItemMoniker", hrMk); std::cout << std::boolalpha; { Hoge obj; DWORD reg; auto hrReg = RegisterActiveObject( &obj, CLSID_Hoge, ACTIVEOBJECT_STRONG, ®); ExitIfFailed(L"RegisterActiveObject", hrReg); ATL::CComPtr<IUnknown> unk; auto hrGet = rot->GetObject(mk, &unk); ExitIfFailed(L"IRunningObjectTable::GetObject", hrGet); std::cout << unk.IsEqualObject(&obj) << std::endl; RevokeActiveObject(reg, nullptr); } { Hoge obj2; DWORD reg; auto hrReg = rot->Register( ROTFLAGS_REGISTRATIONKEEPSALIVE, &obj2, mk, ®); ExitIfFailed(L"RegisterActiveObject", hrReg); ATL::CComPtr<IUnknown> unk; auto hrGet = GetActiveObject(CLSID_Hoge, nullptr, &unk); ExitIfFailed(L"GetActiveObject", hrGet); std::cout << unk.IsEqualObject(&obj2) << std::endl; rot->Revoke(reg); } std::quick_exit(0); } |
クラスモニカーを使っているのかと思っていましたが、その予想は外れてしまいました。
スポンサード リンク |