|
/*
** Copyright 2008-2009, Ernest Laurentin (http://www.ernzo.com/)
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** File: PropertyBagImpl.hpp
** Version: 1.0
*/
#ifndef PROPERTYBAGIMPL_HPP
#define PROPERTYBAGIMPL_HPP
#pragma warning(push)
#pragma warning(disable: 4995)
#include <vector>
#include <string>
#pragma warning(pop)
/**
* PropertyParam
*/
struct PropertyParam {
PropertyParam(const std::wstring& name, const std::wstring& value) {
this->name = name;
this->value = value;
}
PropertyParam() { }
std::wstring name;
std::wstring value;
};
typedef std::vector<PropertyParam> PropertyParams;
/**
* PropertyBagImpl
*/
class PropertyBagImpl : public IPropertyBag
#ifndef UNDER_CE
,public IPropertyBag2
#endif
{
public:
PropertyBagImpl()
{
}
HRESULT InitControl(const PropertyParams& props, IUnknown* pControl)
{
HRESULT hr = E_FAIL;
CComQIPtr<IPersistPropertyBag> pPropBag = pControl;
// Windows CE doesn't have IPersistPropertyBag2
#ifndef UNDER_CE
CComQIPtr<IPersistPropertyBag2> pPropBag2 = pControl;
if ( pPropBag != NULL || pPropBag2 != NULL )
{
_props = props;
if (pPropBag2 != NULL) {
pPropBag2->InitNew();
hr = pPropBag2->Load(this, NULL);
} else {
pPropBag->InitNew();
hr = pPropBag->Load(this, NULL);
}
}
#else
if ( pPropBag != NULL )
{
pPropBag->InitNew();
hr = pPropBag->Load(this, NULL);
}
#endif
return hr;
}
void FinalRelease()
{
}
// IPropertyBag
STDMETHOD(Read)(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog* /*pErrorLog*/)
{
ATLENSURE_RETURN_HR( pVar != NULL, E_POINTER);
HRESULT hr = E_INVALIDARG;
size_t i;
for (i = 0; i < _props.size(); ++i) {
if (_wcsicmp(pszPropName, _props[i].name.c_str()) == 0)
break;
}
if ( i < _props.size())
{
hr = S_OK;
switch(pVar->vt)
{
case VT_EMPTY:
case VT_BSTR:
V_VT(pVar)= VT_BSTR;
V_BSTR(pVar) = ::SysAllocString(_props[i].value.c_str());
break;
case VT_BOOL:
V_VT(pVar) = VT_BOOL;
V_BOOL(pVar) = (( _wcsicmp(L"true",_props[i].value.c_str()) == 0 ) ? VARIANT_TRUE : VARIANT_FALSE );
break;
case VT_I2:
case VT_UI2:
{
V_VT(pVar) = pVar->vt;
V_UI2(pVar) = static_cast<unsigned short>( wcstoul(_props[i].value.c_str(), NULL, 0) );
}
break;
case VT_I4:
case VT_UI4:
{
V_VT(pVar) = pVar->vt;
V_UINT(pVar) = static_cast<unsigned int>( wcstoul(_props[i].value.c_str(), NULL, 0) );
}
break;
case VT_R4:
V_VT(pVar) = VT_R4;
V_R4(pVar) = static_cast<float>( wcstod(_props[i].value.c_str(), NULL) );
break;
case VT_R8:
V_VT(pVar) = VT_R8;
V_R8(pVar) = static_cast<double>( wcstod(_props[i].value.c_str(), NULL) );
break;
default:
hr = E_INVALIDARG;
break;
}
}
return hr;
}
STDMETHOD(Write)(LPCOLESTR /*pszPropName*/, VARIANT* /*pVar*/)
{
return E_NOTIMPL;
}
// Windows CE doesn't have IPersistPropertyBag2
#ifndef UNDER_CE
// IPropertyBag2
STDMETHOD(Read)(ULONG /*cProperties*/, PROPBAG2 *pPropBag,
IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
{
ATLENSURE_RETURN_HR( pPropBag != NULL, E_INVALIDARG);
ATLENSURE_RETURN_HR( pvarValue != NULL, E_INVALIDARG);
HRESULT hr = E_INVALIDARG;
for (size_t i = 0; i < _props.size(); ++i)
{
PROPBAG2* p = pPropBag + i;
V_VT(pvarValue) = p->vt;
hr = Read(p->pstrName, pvarValue + i, pErrLog);
if (phrError != NULL ) {
phrError[i] = SUCCEEDED(hr) ? hr : DISP_E_PARAMNOTFOUND;
}
}
return S_OK;
}
STDMETHOD(Write)(ULONG /*cProperties*/, PROPBAG2* /*pPropBag*/, VARIANT* /*pvarValue*/)
{
return E_NOTIMPL;
}
STDMETHOD(CountProperties)(ULONG *pcProperties)
{
*pcProperties = _props.size();
return S_OK;
}
STDMETHOD(GetPropertyInfo)(ULONG iProperty, ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties)
{
ATLENSURE_RETURN_HR( pPropBag != NULL, E_INVALIDARG);
ATLENSURE_RETURN_HR( iProperty >= _props.size(), E_INVALIDARG);
ATLENSURE_RETURN_HR( pcProperties != NULL, E_INVALIDARG);
size_t i;
for (i = iProperty; i < (iProperty + cProperties) && i < _props.size(); ++i)
{
PROPBAG2* p = pPropBag + (i - iProperty);
memset(p, 0, sizeof(PROPBAG2));
p->dwType = PROPBAG2_TYPE_DATA;
p->vt = VT_BSTR;
p->cfType = CF_TEXT;
p->dwHint = iProperty;
p->pstrName = ::SysAllocString(_props[i].name.c_str());
}
*pcProperties = i - iProperty;
return S_OK;
}
STDMETHOD(LoadObject)(LPCOLESTR /*pstrName*/, DWORD /*dwHint*/,
IUnknown* /*pUnkObject*/, IErrorLog* /*pErrLog*/)
{
return E_NOTIMPL;
}
#endif
// IUnknown
STDMETHOD(QueryInterface)(REFIID iid, void** object)
{
HRESULT hr = S_OK;
*object = NULL;
if (iid == IID_IPropertyBag) {
*object = static_cast<IPropertyBag*>(this);
}
#ifndef UNDER_CE
else if (iid == IID_IPropertyBag2) {
*object = static_cast<IPropertyBag2*>(this);
}
#endif
else {
hr = E_NOINTERFACE;
}
if ( SUCCEEDED(hr) ) {
static_cast<IUnknown*>(*object)->AddRef();
}
return hr;
}
private:
PropertyParams _props;
};
#endif //PROPERTYBAGIMPL_HPP
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Ernest is a multi-discipline software engineer.
Skilled at software design and development for all Windows platforms.
-
MCSD (C#, .NET)
Interests: User Interface, GDI/GDI+, Scripting, Android, iOS, Windows Mobile.
Programming Skills: C/C++, C#, Java (Android), VB and ASP.NET.
I hope you will enjoy my contributions.