Click here to Skip to main content
15,895,746 members
Articles / Mobile Apps / Windows Mobile

ATL Windowless ActiveX Media Container

Rate me:
Please Sign up or sign in to vote.
5.00/5 (20 votes)
5 Mar 2009Apache7 min read 179.6K   8.1K   100  
Full-fledged ATL Windowless ActiveX Container. Ideal for hosting Windows Media Player, Transparent Flash and Silverlight Animations.
/*
** 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.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0


Written By
Software Developer (Senior)
United States United States
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.

Comments and Discussions