解説
COMインターフェースを自分で作って使いたいときは、「ATLシンプル オブジェクト」を追加 するなどして作るのが一般的な方法となる。しかし、この場合はWTLのプロジェクトなど、非ATL プロジェクトでは使うのが面倒だ。しかも自動作成されるソースコードは多く、一見無駄に見え る部分が非常に多い。また、作成したCOMインターフェースを常に外部へエクスポートしたいとは限らない。その実 行ファイル内のみで利用したいことも多くある。そのため標準でレジストリに登録をする「ATL シンプル オブジェクト」などの方法は使い勝手が悪い。
ということで、プログラム内で簡単に使えるCOMインターフェースの定義方法を紹介する。こ の方法はかなり邪道なため、かなり文句を言われそうだが...
使用例
CComPtrpTest; pTest = new CComObject ; pTest->DumyMethod(L"あいう"); pTest = NULL;
定義
MIDL_INTERFACE("28932A04-3456-436d-BF58-154F7BD82E8A")
ITest : public IUnknown
{
public:
STDMETHOD (DumyMethod)(BSTR bstrIn) = 0;
};
class ATL_NO_VTABLE CTest :
public CComObjectRootEx,
public ITest
{
public:
CTest()
{
}
BEGIN_COM_MAP(CTest)
COM_INTERFACE_ENTRY(ITest)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
STDMETHOD(DumyMethod)(BSTR bstrIn)
{
//何らかの処理
return S_OK;
}
};
※太字部分のGUIDは定義するインターフェースごとに異なる値をGuidGen.exeで生成して利用する
既存インターフェース派生時の定義
既存のインターフェースから派生させた定義をしたい場合は以下のように する。ここではIOleCommandTarget派生とした。
MIDL_INTERFACE("28932A04-3456-436d-BF58-154F7BD82E8A")
ITest : public IUnknown
{
public:
STDMETHOD (DumyMethod)(BSTR bstrIn) = 0;
};
class ATL_NO_VTABLE CTest :
public CComObjectRootEx,
public IOleCommandTarget,
public ITest
{
public:
CTest()
{
}
BEGIN_COM_MAP(CTest)
COM_INTERFACE_ENTRY(IOleCommandTarget)
COM_INTERFACE_ENTRY(ITest)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
STDMETHOD(DumyMethod)(BSTR bstrIn)
{
//何らかの処理
return S_OK;
}
//IOleCommandTarget
STDMETHOD(Exec)(const GUID *pguidCmdGroup,DWORD nCmdID,DWORD nCmdExecOpt,VARIANTARG *pvaIn,VARIANTARG *pvaOut)
{
return S_OK;
}
STDMETHOD(QueryStatus)(const GUID *pguidCmdGroup,ULONG cCmds,OLECMD *prgCmds,OLECMDTEXT *pCmdText)
{
return S_OK;
}
};
