// XcpControlHost.cpp : Implementation of CXcpControlHost
#include "stdafx.h"
#include "XcpControlHost.h"
#include "Ocidl.h"
#include "AtlProject_i.h"
#include "atlstr.h"
class CXcpPropertyBag:IPropertyBag
{
public:
CXcpPropertyBag(){m_nRef=0;}
~CXcpPropertyBag(){}
HRESULT _stdcall QueryInterface(REFIID iid, void** ppvObject)
{
return S_OK;
}
ULONG _stdcall AddRef()
{
return ++m_nRef;
}
ULONG _stdcall Release()
{
if(--m_nRef == 0)
delete this;
return m_nRef;
}
ULONG m_nRef;
STDMETHOD (Read)(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)
{
HRESULT hr = E_INVALIDARG;
BSTR bstrValue = NULL;
if (_wcsicmp(pszPropName, L"Source") == 0)
{
bstrValue = SysAllocString(L"SilverlightTestApp.xap");
}
else if (_wcsicmp(pszPropName, L"Background") == 0)
{
bstrValue = SysAllocString(L"Gold");
}
else if (_wcsicmp(pszPropName, L"Windowless") == 0)
{
V_VT(pVar) = VT_BOOL;
V_BOOL(pVar) = VARIANT_FALSE;
hr = S_OK;
}
if (bstrValue != NULL)
{
V_VT(pVar) = VT_BSTR;
V_BSTR(pVar) = bstrValue;
hr = S_OK;
}
return hr;
}
STDMETHOD (Write)(LPCOLESTR pszPropName, VARIANT *pVar)
{
return S_OK;
}
};
// CXcpControlHost
#pragma warning(disable:4061)
#include "stdafx.h"
#include "XcpControlHost.h"
#include "AtlProject_i.h"
HWND CXcpControlHost::hControlWindow = NULL;
IUnknown* CXcpControlHost::pUnKnown = NULL;
XcpControlLib::IXcpControl2* CXcpControlHost::pControl = NULL;
///////////////////////////////////////////////////////////////////////////////
// CXcpControlHost IXcpControlHost Implementation
STDMETHODIMP CXcpControlHost::GetHostOptions(DWORD* pdwOptions)
{
*pdwOptions = XcpHostOption_EnableCrossDomainDownloads|
XcpHostOption_EnableScriptableObjectAccess|XcpHostOption_EnableHtmlDomAccess;
return S_OK;
}
STDMETHODIMP CXcpControlHost::GetCustomAppDomain(IUnknown** ppAppDomain)
{
return S_OK;
}
STDMETHODIMP CXcpControlHost::GetControlVersion(UINT *puMajorVersion, UINT *puMinorVersion)
{
*puMajorVersion = 4;
*puMinorVersion = 50401;
return S_OK;;
}
STDMETHODIMP CXcpControlHost::NotifyLoaded()
{
return S_OK;
}
STDMETHODIMP CXcpControlHost::NotifyError(BSTR bstrError, BSTR bstrSource, long nLine, long nColumn)
{
return S_OK;
}
STDMETHODIMP CXcpControlHost::InvokeHandler(BSTR bstrName, VARIANT varParam1, VARIANT varParam2, VARIANT* pvarResult)
{
return E_NOTIMPL;
}
STDMETHODIMP CXcpControlHost::GetBaseUrl(BSTR* pbstrUrl) {
CAtlString strPath;
TCHAR pBuff[255];
GetCurrentDirectory(255, pBuff);
strPath = pBuff;
strPath += "\\";
*pbstrUrl = SysAllocString(strPath);
//MessageBox(*pbstrUrl, L"GetBaseUrl", 0);
return S_OK;
}
STDMETHODIMP CXcpControlHost::GetNamedSource(BSTR bstrSourceName, BSTR* pbstrSource)
{
return E_NOTIMPL;
}
STDMETHODIMP CXcpControlHost::DownloadUrl(BSTR bstrUrl, IXcpControlDownloadCallback* pCallback, IStream** ppStream)
{
// MessageBox(L"DownloadUrl", L"DownloadUrl", 0);
return S_FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// CXcpControlHost Constructor/Destructor
CXcpControlHost::CXcpControlHost()
{
}
CXcpControlHost::~CXcpControlHost()
{
}
///////////////////////////////////////////////////////////////////////////////
// CXcpControlHost IServiceProvider Implementation
STDMETHODIMP CXcpControlHost::QueryService(REFGUID rsid, REFIID riid, void** ppvObj) {
ATLASSERT(ppvObj != NULL);
if (ppvObj == NULL)
return E_POINTER;
*ppvObj = NULL;
//static const GUID IID_IXcpControlHost =
// { 0x1B36028E, 0xB491, 0x4bb2, { 0x85, 0x84, 0x8A, 0x9E, 0x0A, 0x67, 0x7D, 0x6E }};
HRESULT hr = E_NOINTERFACE;
if ((rsid == IID_IXcpControlHost) && (riid == IID_IXcpControlHost)) {
((IXcpControlHost*)this)->AddRef();
*ppvObj = (IXcpControlHost*)this;
hr = S_OK;
}
if ((rsid == IID_IXcpControlHost2) && (riid == IID_IXcpControlHost2)) {
((IXcpControlHost2*)this)->AddRef();
*ppvObj = (IXcpControlHost2*)this;
hr = S_OK;
}
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// General ActiveX control embedding.
HRESULT CXcpControlHost::CreateXcpControl(HWND hWnd)
{
AtlAxWinInit();
HRESULT hr;
static const GUID IID_IXcpControl =
{ 0x1FB839CC, 0x116C, 0x4C9B, { 0xAE, 0x8E, 0x3D, 0xBB, 0x64, 0x96, 0xE3, 0x26 }};
static const GUID CLSID_XcpControl =
{ 0xDFEAF541, 0xF3E1, 0x4c24, { 0xAC, 0xAC, 0x99, 0xC3, 0x07, 0x15, 0x08, 0x4A }};
static const GUID IID_IXcpControl2 =
{ 0x1c3294f9, 0x891f, 0x49b1, { 0xBB, 0xAE, 0x49, 0x2a, 0x68, 0xBA, 0x10, 0xcc }};
// static const GUID CLSID_XcpControl2 =
// { 0xDFEAF541, 0xF3E1, 0x4c24, { 0xAC, 0xAC, 0x99, 0xC3, 0x07, 0x15, 0x08, 0x4A }};
//static const GUID IID_IXcpControlHost2 =
// { 0xfb3ed7c4, 0x5797, 0x4b44, { 0x86, 0x95, 0x0c, 0x51, 0x2e, 0xa2, 0x7D, 0x8f }};
hr = CoCreateInstance(CLSID_XcpControl, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnKnown);
if (SUCCEEDED(hr))
{
CComPtr<IUnknown> spUnkContainer;
hr = CXcpControlHost::_CreatorClass::CreateInstance(NULL, IID_IUnknown, (void**)&spUnkContainer);
if (SUCCEEDED(hr))
{
CComPtr<IAxWinHostWindow> pAxWindow;
spUnkContainer->QueryInterface(IID_IAxWinHostWindow, (void**)&pAxWindow);
pUnKnown->QueryInterface(IID_IXcpControl2, (void**)&pControl);
hr = pAxWindow->AttachControl(pUnKnown, hWnd);
hControlWindow = hWnd;
IOleInPlaceActiveObject *pObj;
hr = pControl->QueryInterface(IID_IOleInPlaceActiveObject, (void**)&pObj);
}
}
return hr;
}
HRESULT CXcpControlHost::DestroyXcpControl()
{
HRESULT hr = S_OK;
if (pControl)
{
pControl->Release();
}
if (pUnKnown)
{
pUnKnown->Release();
}
return hr;
}
STDMETHODIMP CXcpControlHost::AttachControl(IUnknown* pUnKnown, HWND hWnd) {
ReleaseAll();
HRESULT hr = S_FALSE;
BOOL fReleaseWindowOnFailure = FALSE;
if ((m_hWnd != NULL) && (m_hWnd != hWnd)) {
// Don't release the window if it's the same as the one we already subclass/own
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
ReleaseWindow();
}
if (::IsWindow(hWnd)) {
if (m_hWnd != hWnd) {
// Don't need to subclass the window if we already own it
SubclassWindow(hWnd);
fReleaseWindowOnFailure = TRUE;
}
hr = ActivateXcpControl(pUnKnown);
if (FAILED(hr)) {
ReleaseAll();
if (m_hWnd != NULL) {
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
if (fReleaseWindowOnFailure) {
// We subclassed the window in an attempt to create this control, so we unsubclass on failure
ReleaseWindow();
}
}
}
}
return hr;
}
HRESULT CXcpControlHost::ActivateXcpControl(IUnknown* pUnKnown)
{
if (pUnKnown == NULL)
{
return S_OK;
}
m_spUnknown = pUnKnown;
HRESULT hr = S_OK;
pUnKnown->QueryInterface(__uuidof(IOleObject), (void**)&m_spOleObject);
if (m_spOleObject)
{
m_spOleObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);
if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
{
CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
m_spOleObject->SetClientSite(spClientSite);
}
CComQIPtr<IPersistPropertyBag> pPersist(m_spOleObject);
if (pPersist != NULL)
{
IPropertyBag* pPropBag = (IPropertyBag*)new CXcpPropertyBag();
pPropBag->AddRef();
pPersist->Load((IPropertyBag*)pPropBag, NULL);
pPropBag->Release();
}
if (0 == (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
{
CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
m_spOleObject->SetClientSite(spClientSite);
}
m_dwViewObjectType = 0;
hr = m_spOleObject->QueryInterface(__uuidof(IViewObjectEx), (void**) &m_spViewObject);
if (FAILED(hr))
{
hr = m_spOleObject->QueryInterface(__uuidof(IViewObject2), (void**) &m_spViewObject);
if (SUCCEEDED(hr)) {
m_dwViewObjectType = 3;
}
}
else {
m_dwViewObjectType = 7;
}
if (FAILED(hr))
{
hr = m_spOleObject->QueryInterface(__uuidof(IViewObject), (void**) &m_spViewObject);
if (SUCCEEDED(hr))
m_dwViewObjectType = 1;
}
CComQIPtr<IAdviseSink> spAdviseSink(GetControllingUnknown());
m_spOleObject->Advise(spAdviseSink, &m_dwOleObject);
if (m_spViewObject)
{
m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, spAdviseSink);
}
m_spOleObject->SetHostNames(OLESTR("AXWIN"), NULL);
if ((m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME) == 0)
{
GetClientRect(&m_rcPos);
m_pxSize.cx = m_rcPos.right - m_rcPos.left;
m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;
AtlPixelToHiMetric(&m_pxSize, &m_hmSize);
m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);
m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);
AtlHiMetricToPixel(&m_hmSize, &m_pxSize);
m_rcPos.right = m_rcPos.left + m_pxSize.cx ;
m_rcPos.bottom = m_rcPos.top + m_pxSize.cy ;
CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, m_hWnd, &m_rcPos);
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
}
}
CComPtr<IObjectWithSite> spSite;
pUnKnown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);
if (spSite != NULL)
{
spSite->SetSite(GetControllingUnknown());
}
return hr;
}