Date

IPropertyBag とは、任意の文字列(キー)と、 VARIANT 型とを結びつけて、読み書きする COM インターフェイスである。

Windows Mobile で DirectShow によるカメラアプリを作る際に、 IPropertyBag を自前で実装する必要がある。

このページでは IPropertyBag のサンプルコードを掲載しておく。

なお、マイクロソフトからサンプルコードが提供されているが、こちらは STL を使ったコード量が少ない実装。

実装するメソッドは 2 つ。

1
HRESULT Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorlog* pErrorLog );

pszPropName にキーとなるプロパティの名前、 pVar にキーに対応するプロパティの値を VARIANT 型で返す。

IErrorLog の引数は無視して構わない。単にカメラアプリを作る時は不要。

戻り値は 引数 pszPropName で指定されたプロパティの名前を持つ値が見つからないときは E_INVALIDARG, 成功したときは S_OK である。

1
HRESULT Write(LPCOLESTR pszPropName, VARIANT* pVar );

pszPropName にキーとなるプロパティの名前、 pVar にキーに対応するプロパティの値が入ってくる。こちら側で対応付けされて記憶するように実装する。

サンプルコード

```c++ propertybag.h

pragma once

include

class CPropertyBag : public IPropertyBag { public: CPropertyBag() : m_RefCount(1) { } ~CPropertyBag() { } ULONG STDMETHODCALLTYPE AddRef() { return InterlockedIncrement((LONG )&m_RefCount); } ULONG STDMETHODCALLTYPE Release() { ASSERT(m_RefCount != 0xFFFFFFFF); ULONG ret = InterlockedDecrement((LONG )&m_RefCount); if(!ret) delete this; return ret; } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ppv) { if(!ppv) return E_POINTER; if(riid == IID_IPropertyBag) { ppv = dynamic_cast(this); } else { ppv=NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } HRESULT STDMETHODCALLTYPE Read(LPCOLESTR pszPropName, VARIANT pVar, IErrorLog pErrorLog) { _bstr_t arg(pszPropName); if(m_Props.find(arg)==m_Props.end()){ return E_INVALIDARG; // does not exist. } return VariantCopy(pVar, &m_Props[arg]); } HRESULT STDMETHODCALLTYPE Write(LPCOLESTR pszPropName, VARIANT pVar) { m_Props.insert(std::map<_bstr_t, _variant_t>::value_type(_bstr_t(pszPropName),_variant_t(pVar, true))); return S_OK; } private: ULONG m_RefCount; std::map<_bstr_t, _variant_t> m_Props; }; ```

この手の実装は STL の std::map を使うとてっとり早く作れます。直接 VARIANT を扱うとメモリ管理をしなければいけないので_variant_tのお世話になっています。


Comments

comments powered by Disqus