443 lines
13 KiB
C++
443 lines
13 KiB
C++
//***************************************************************************
|
|
// THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright 2003 Microsoft Corporation. All Rights Reserved.
|
|
//***************************************************************************
|
|
|
|
//***************************************************************************
|
|
//
|
|
// File: DataObj.cpp
|
|
//
|
|
// Description: CPropSheetHost implementation.
|
|
//
|
|
//***************************************************************************
|
|
|
|
//***************************************************************************
|
|
// #include statements
|
|
//***************************************************************************
|
|
|
|
#include "stdafx.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IUnknown Implementation
|
|
//
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::QueryInterface
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::QueryInterface(REFIID riid,
|
|
LPVOID *ppReturn)
|
|
{
|
|
if(!ppReturn)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
*ppReturn = NULL;
|
|
|
|
if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDataObject))
|
|
{
|
|
*ppReturn = (IDataObject*)this;
|
|
}
|
|
|
|
if(*ppReturn)
|
|
{
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::AddRef
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP_(DWORD) CPropSheetHost::AddRef()
|
|
{
|
|
return ++m_ObjRefCount;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::Release
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP_(DWORD) CPropSheetHost::Release()
|
|
{
|
|
if(--m_ObjRefCount == 0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
return m_ObjRefCount;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IDataObject Implementation
|
|
//
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::GetData()
|
|
|
|
Retrieves the data and places it in memory that the implementation
|
|
allocates.
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::GetData(FORMATETC *pFormatEtc,
|
|
STGMEDIUM *pStgMedium)
|
|
{
|
|
if(!pFormatEtc || ! pStgMedium)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT hr = DV_E_FORMATETC;
|
|
|
|
if(m_cfDSDispSpecOptions == pFormatEtc->cfFormat)
|
|
{
|
|
hr = _GetDSDispSpecOption(pFormatEtc, pStgMedium);
|
|
}
|
|
else if(m_cfDSObjectNames == pFormatEtc->cfFormat)
|
|
{
|
|
hr = _GetDSObjectNames(pFormatEtc, pStgMedium);
|
|
}
|
|
else if(m_cfDSPropSheetConfig == pFormatEtc->cfFormat)
|
|
{
|
|
hr = _GetDSPropSheetConfig(pFormatEtc, pStgMedium);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::GetDataHere()
|
|
|
|
Retrieves the data and places it in memory that the caller
|
|
allocates.
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::GetDataHere(FORMATETC *pFormatEtc,
|
|
STGMEDIUM *pStgMedium)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::QueryGetData()
|
|
|
|
Determines if the data object can supply the data in the specified
|
|
format. Returns S_OK if it can or one of the DV_E_ values if not. It is
|
|
not necessary to call this before GetData() or GetDataHere().
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::QueryGetData(FORMATETC *pFormatEtc)
|
|
{
|
|
if(this->m_cfDSDispSpecOptions == pFormatEtc->cfFormat)
|
|
{
|
|
return S_OK;
|
|
}
|
|
else if(this->m_cfDSObjectNames == pFormatEtc->cfFormat)
|
|
{
|
|
return S_OK;
|
|
}
|
|
else if(this->m_cfDSPropSheetConfig == pFormatEtc->cfFormat)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
return DV_E_FORMATETC;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::GetCanonicalFormatEtc()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::GetCanonicalFormatEtc(LPFORMATETC pFEIn,
|
|
LPFORMATETC pFEOut)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::EnumFormatEtc()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::EnumFormatEtc(DWORD dwDirection,
|
|
IEnumFORMATETC** ppEFE)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::SetData()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::SetData(LPFORMATETC pFormatEtc,
|
|
LPSTGMEDIUM pStgMedium,
|
|
BOOL fRelease)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::DAdvise()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::DAdvise( LPFORMATETC pFE,
|
|
DWORD advf,
|
|
IAdviseSink *ppAdviseSink,
|
|
LPDWORD pdwConnection)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::DUnadvise()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::DUnadvise(DWORD dwConnection)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CPropSheetHost::EnumDAdvise()
|
|
|
|
**************************************************************************/
|
|
|
|
STDMETHODIMP CPropSheetHost::EnumDAdvise(IEnumSTATDATA** ppEnumAdvise)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
CPropSheetHost::_GetDSDispSpecOption()
|
|
|
|
Get the CFSTR_DSDISPLAYSPECOPTIONS data.
|
|
|
|
***************************************************************************/
|
|
|
|
HRESULT CPropSheetHost::_GetDSDispSpecOption(FORMATETC *pFormatEtc,
|
|
STGMEDIUM *pStgMedium)
|
|
{
|
|
if((m_cfDSDispSpecOptions != pFormatEtc->cfFormat) ||
|
|
!(pFormatEtc->tymed & TYMED_HGLOBAL))
|
|
{
|
|
return DV_E_FORMATETC;
|
|
}
|
|
|
|
HRESULT hr = E_OUTOFMEMORY;
|
|
LPWSTR pwszPrefix = m_pwszPrefix;
|
|
DWORD dwPrefixOffset;
|
|
|
|
// Size of the DSDISPLAYSPECOPTIONS structure.
|
|
DWORD dwBytes = sizeof(DSDISPLAYSPECOPTIONS);
|
|
|
|
// Store the offset to the prefix.
|
|
dwPrefixOffset = dwBytes;
|
|
|
|
// Length of the prefix Unicode string, including the null terminator.
|
|
DWORD strBufferLenInChar = lstrlenW(pwszPrefix) + 1;
|
|
dwBytes += strBufferLenInChar * sizeof(WCHAR);
|
|
|
|
pStgMedium->pUnkForRelease = NULL;
|
|
pStgMedium->tymed = TYMED_HGLOBAL;
|
|
pStgMedium->hGlobal = GlobalAlloc(GPTR, dwBytes);
|
|
if(pStgMedium->hGlobal)
|
|
{
|
|
DSDISPLAYSPECOPTIONS *pDispSpecOptions = (DSDISPLAYSPECOPTIONS*)GlobalLock(pStgMedium->hGlobal);
|
|
if(pDispSpecOptions)
|
|
{
|
|
LPWSTR pwszTemp;
|
|
|
|
pDispSpecOptions->dwSize = sizeof(DSDISPLAYSPECOPTIONS);
|
|
pDispSpecOptions->dwFlags = 0;
|
|
pDispSpecOptions->offsetAttribPrefix = dwPrefixOffset;
|
|
pDispSpecOptions->offsetUserName = 0;
|
|
pDispSpecOptions->offsetPassword = 0;
|
|
pDispSpecOptions->offsetServer = 0;
|
|
pDispSpecOptions->offsetServerConfigPath = 0;
|
|
|
|
// Copy the prefix string.
|
|
pwszTemp = (LPWSTR)((LPBYTE)pDispSpecOptions + dwPrefixOffset);
|
|
wcscpy_s(pwszTemp, strBufferLenInChar, pwszPrefix);
|
|
|
|
GlobalUnlock(pStgMedium->hGlobal);
|
|
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
CPropSheetHost::_GetDSObjectNames()
|
|
|
|
Get the CFSTR_DSOBJECTNAMES data.
|
|
|
|
***************************************************************************/
|
|
|
|
HRESULT CPropSheetHost::_GetDSObjectNames(FORMATETC *pFormatEtc,
|
|
STGMEDIUM *pStgMedium)
|
|
{
|
|
if((m_cfDSObjectNames != pFormatEtc->cfFormat) ||
|
|
!(pFormatEtc->tymed & TYMED_HGLOBAL))
|
|
{
|
|
return DV_E_FORMATETC;
|
|
}
|
|
|
|
HRESULT hr;
|
|
CComBSTR sbstrADsPath;
|
|
|
|
hr = m_spADObject->get_ADsPath(&sbstrADsPath);
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
CComBSTR sbstrClass;
|
|
hr = m_spADObject->get_Class(&sbstrClass);
|
|
if(FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
// Size of the DSOBJECTNAMES structure.
|
|
size_t dwBytes = sizeof(DSOBJECTNAMES);
|
|
|
|
// Store the offset to the name.
|
|
size_t dwNameOffset = dwBytes;
|
|
|
|
// Length of the ADsPath Unicode string, including the null terminator.
|
|
size_t pathBuffLenInChar = sbstrADsPath.Length() + 1;
|
|
dwBytes += pathBuffLenInChar * sizeof(WCHAR);
|
|
|
|
// Store the offset to the class.
|
|
size_t dwClassOffset = dwBytes;
|
|
|
|
// Length of the class Unicode string, including the null terminator.
|
|
size_t classBuffLenInChar = sbstrClass.Length() + 1;
|
|
dwBytes += classBuffLenInChar * sizeof(WCHAR);
|
|
|
|
pStgMedium->pUnkForRelease = NULL;
|
|
pStgMedium->tymed = TYMED_HGLOBAL;
|
|
pStgMedium->hGlobal = GlobalAlloc(GPTR, dwBytes);
|
|
if(pStgMedium->hGlobal)
|
|
{
|
|
DSOBJECTNAMES *pObjectNames = (DSOBJECTNAMES*)GlobalLock(pStgMedium->hGlobal);
|
|
if(pObjectNames)
|
|
{
|
|
LPWSTR pwszTemp;
|
|
|
|
pObjectNames->clsidNamespace = GUID_NULL;
|
|
pObjectNames->cItems = 1;
|
|
pObjectNames->aObjects[0].dwFlags = 0;
|
|
pObjectNames->aObjects[0].dwProviderFlags = DSPROVIDER_ADVANCED;
|
|
pObjectNames->aObjects[0].offsetName = (DWORD)dwNameOffset;
|
|
pObjectNames->aObjects[0].offsetClass = (DWORD)dwClassOffset;
|
|
|
|
// Copy the ADsPath string.
|
|
pwszTemp = (LPWSTR)((LPBYTE)pObjectNames + dwNameOffset);
|
|
wcscpy_s(pwszTemp, pathBuffLenInChar, sbstrADsPath);
|
|
|
|
// Copy the class string.
|
|
pwszTemp = (LPWSTR)((LPBYTE)pObjectNames + dwClassOffset);
|
|
wcscpy_s(pwszTemp, classBuffLenInChar, sbstrClass);
|
|
|
|
GlobalUnlock(pStgMedium->hGlobal);
|
|
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
CPropSheetHost::_GetDSPropSheetConfig()
|
|
|
|
Get the CFSTR_DS_PROPSHEETCONFIG data.
|
|
|
|
***************************************************************************/
|
|
|
|
HRESULT CPropSheetHost::_GetDSPropSheetConfig(FORMATETC *pFormatEtc,
|
|
STGMEDIUM *pStgMedium)
|
|
{
|
|
if((m_cfDSPropSheetConfig != pFormatEtc->cfFormat) ||
|
|
!(pFormatEtc->tymed & TYMED_HGLOBAL))
|
|
{
|
|
return DV_E_FORMATETC;
|
|
}
|
|
|
|
HRESULT hr = E_OUTOFMEMORY;
|
|
|
|
pStgMedium->pUnkForRelease = NULL;
|
|
pStgMedium->tymed = TYMED_HGLOBAL;
|
|
pStgMedium->hGlobal = GlobalAlloc(GPTR, sizeof(PROPSHEETCFG));
|
|
if(pStgMedium->hGlobal)
|
|
{
|
|
PROPSHEETCFG *pPropSheetCfg = (PROPSHEETCFG*)GlobalLock(pStgMedium->hGlobal);
|
|
if(pPropSheetCfg)
|
|
{
|
|
// hwndParentSheet recevies the handle of the window to receive WM_ADSPROP_NOTIFY_CHANGE messages.
|
|
pPropSheetCfg->hwndParentSheet = m_hwndHidden;
|
|
|
|
// hwndParentSheet receives the handle of the window that will receive WM_DSA_SHEET_CREATE_NOTIFY and WM_DSA_SHEET_CLOSE_NOTIFY messages.
|
|
pPropSheetCfg->hwndHidden = m_hwndHidden;
|
|
|
|
// lNotifyHandle is not used.
|
|
pPropSheetCfg->lNotifyHandle = 0;
|
|
|
|
/*
|
|
wParamSheetClose is an identifier that is passed as the wparam in
|
|
the WM_DSA_SHEET_CLOSE_NOTIFY message. If this member is zero, the
|
|
WM_DSA_SHEET_CLOSE_NOTIFY is not posted.
|
|
*/
|
|
pPropSheetCfg->wParamSheetClose = PROP_SHEET_HOST_ID;
|
|
|
|
GlobalUnlock(pStgMedium->hGlobal);
|
|
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|