windows-nt/Source/XPSP1/NT/printscan/ui/uicommon/proparry.cpp
2020-09-26 16:20:57 +08:00

470 lines
12 KiB
C++

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 1998
*
* TITLE: PROPARRY.CPP
*
* VERSION: 1.0
*
* AUTHOR: ShaunIv
*
* DATE: 5/4/1999
*
* DESCRIPTION: IWiaPropertyStorage cache definitions
*
*******************************************************************************/
#include "precomp.h"
#pragma hdrstop
CPropertyStorageArray::CPropertyStorageArray( const CPropertyStorageArray &other )
: m_nCount(0),
m_ppvPropVariants(NULL),
m_ppsPropSpecs(NULL),
m_pstrPropNames(NULL)
{
Copy(other);
}
CPropertyStorageArray::CPropertyStorageArray(IUnknown *pIUnknown)
: m_nCount(0),
m_ppvPropVariants(NULL),
m_ppsPropSpecs(NULL),
m_pstrPropNames(NULL)
{
Initialize(pIUnknown);
}
CPropertyStorageArray::~CPropertyStorageArray(void)
{
Destroy();
}
bool CPropertyStorageArray::IsValid(void) const
{
// It's OK to have an empty list, but it isn't considered valid
return (m_nCount && m_ppvPropVariants && m_ppsPropSpecs && m_pstrPropNames);
}
HRESULT CPropertyStorageArray::Copy( const CPropertyStorageArray &other )
{
Destroy();
HRESULT hr = S_OK;
if (this != &other)
{
if (other.IsValid())
{
m_nCount = other.Count();
if (m_nCount)
{
if (AllocateData())
{
for (int i=0;i<m_nCount && SUCCEEDED(hr);i++)
{
// Copy propvariant
if (!SUCCEEDED(PropVariantCopy( &m_ppvPropVariants[i], &other.PropVariants()[i])))
{
hr = E_FAIL;
break;
}
// Copy property name
if (other.PropNames() && other.PropNames()[i])
{
m_pstrPropNames[i] = new WCHAR[lstrlenW(other.PropNames()[i])+1];
if (!m_pstrPropNames[i])
{
hr = E_FAIL;
break;
}
lstrcpyW( m_pstrPropNames[i], other.PropNames()[i] );
}
// Copy propspec (propid)
m_ppsPropSpecs[i].propid = other.PropSpecs()[i].propid;
m_ppsPropSpecs[i].ulKind = PRSPEC_PROPID;
}
}
else
{
hr = E_FAIL;
}
}
}
else
{
hr = E_FAIL;
}
}
if (!SUCCEEDED(hr))
Destroy();
return hr;
}
void CPropertyStorageArray::ClearPropVariantArray(void)
{
if (!m_ppvPropVariants || !m_nCount)
return;
for (int i=0;i<m_nCount;i++)
{
PropVariantClear(m_ppvPropVariants+i);
m_ppvPropVariants[i].vt = VT_EMPTY;
}
}
void CPropertyStorageArray::Destroy(void)
{
ClearPropVariantArray();
for (int i=0;i<m_nCount;i++)
{
if (m_pstrPropNames && m_pstrPropNames[i])
delete[] m_pstrPropNames[i];
}
if (m_ppvPropVariants)
delete[] m_ppvPropVariants;
if (m_ppsPropSpecs)
delete[] m_ppsPropSpecs;
if (m_pstrPropNames)
delete[] m_pstrPropNames;
m_ppvPropVariants = NULL;
m_ppsPropSpecs = NULL;
m_pstrPropNames = NULL;
m_nCount = 0;
}
bool CPropertyStorageArray::AllocateData(void)
{
m_ppsPropSpecs = new PROPSPEC[m_nCount];
if (m_ppsPropSpecs)
{
ZeroMemory(m_ppsPropSpecs,m_nCount*sizeof(m_ppsPropSpecs[0]));
}
m_ppvPropVariants = new PROPVARIANT[m_nCount];
if (m_ppvPropVariants)
{
ZeroMemory(m_ppvPropVariants,m_nCount*sizeof(m_ppvPropVariants[0]));
}
m_pstrPropNames = new LPWSTR[m_nCount];
if (m_pstrPropNames)
{
ZeroMemory(m_pstrPropNames,m_nCount*sizeof(m_pstrPropNames[0]));
}
return(m_ppsPropSpecs && m_ppvPropVariants && m_pstrPropNames);
}
CPropertyStorageArray &CPropertyStorageArray::operator=( const CPropertyStorageArray &other )
{
Copy(other);
return(*this);
}
int CPropertyStorageArray::GetPropertyCount( IWiaPropertyStorage *pIWiaPropertyStorage )
{
IEnumSTATPROPSTG *pIEnum = NULL;
HRESULT hr;
int nCount=0;
hr = pIWiaPropertyStorage->Enum(&pIEnum);
if (SUCCEEDED(hr))
{
STATPROPSTG StatPropStg;
ZeroMemory(&StatPropStg,sizeof(StatPropStg));
while ((hr = pIEnum->Next(1,&StatPropStg, NULL)) == S_OK)
{
nCount++;
if (StatPropStg.lpwstrName)
{
CoTaskMemFree(StatPropStg.lpwstrName);
}
ZeroMemory(&StatPropStg,sizeof(StatPropStg));
}
}
return(nCount);
}
HRESULT CPropertyStorageArray::GetPropertyNames( IWiaPropertyStorage *pIWiaPropertyStorage )
{
IEnumSTATPROPSTG *pIEnum = NULL;
HRESULT hr;
int nCurrentIndex=0;
hr = pIWiaPropertyStorage->Enum(&pIEnum);
if (SUCCEEDED(hr))
{
STATPROPSTG StatPropStg;
ZeroMemory(&StatPropStg,sizeof(StatPropStg));
while ((hr = pIEnum->Next(1,&StatPropStg, NULL)) == S_OK)
{
m_ppsPropSpecs[nCurrentIndex].propid = StatPropStg.propid;
m_ppsPropSpecs[nCurrentIndex].ulKind = PRSPEC_PROPID;
if (StatPropStg.lpwstrName)
{
m_pstrPropNames[nCurrentIndex] = new WCHAR[lstrlenW(StatPropStg.lpwstrName)+1];
if (m_pstrPropNames[nCurrentIndex])
{
lstrcpyW( m_pstrPropNames[nCurrentIndex], StatPropStg.lpwstrName );
CoTaskMemFree(StatPropStg.lpwstrName);
}
else
{
hr = E_OUTOFMEMORY;
CoTaskMemFree(StatPropStg.lpwstrName);
break;
}
}
nCurrentIndex++;
}
}
return(hr);
}
HRESULT CPropertyStorageArray::Initialize( IUnknown *pIUnknown )
{
Destroy();
HRESULT hr = E_INVALIDARG;
if (pIUnknown)
{
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
hr = pIUnknown->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
if (SUCCEEDED(hr))
{
m_nCount = GetPropertyCount( pIWiaPropertyStorage );
if (m_nCount)
{
if (AllocateData())
{
hr = GetPropertyNames( pIWiaPropertyStorage );
if (SUCCEEDED(hr))
{
hr = pIWiaPropertyStorage->ReadMultiple( m_nCount, m_ppsPropSpecs, m_ppvPropVariants );
}
}
}
}
}
if (!SUCCEEDED(hr))
{
Destroy();
}
return(hr);
}
HRESULT CPropertyStorageArray::Read( IUnknown *pIUnknown )
{
HRESULT hr = E_FAIL;
if (IsValid())
{
ClearPropVariantArray();
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
hr = pIUnknown->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
if (SUCCEEDED(hr))
{
hr = pIWiaPropertyStorage->ReadMultiple( m_nCount, m_ppsPropSpecs, m_ppvPropVariants );
}
}
return(hr);
}
HRESULT CPropertyStorageArray::Write( IUnknown *pIUnknown )
{
HRESULT hr = E_FAIL;
if (IsValid())
{
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
hr = pIUnknown->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
if (SUCCEEDED(hr))
{
hr = pIWiaPropertyStorage->WriteMultiple( m_nCount, m_ppsPropSpecs, m_ppvPropVariants, WIA_IPA_FIRST);
}
}
return(hr);
}
HRESULT CPropertyStorageArray::Write( IUnknown *pIUnknown, PROPID propId )
{
HRESULT hr = E_FAIL;
if (IsValid())
{
int nIndex = GetIndexFromPropId( propId );
if (nIndex >= 0)
{
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
hr = pIUnknown->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
if (SUCCEEDED(hr))
{
hr = pIWiaPropertyStorage->WriteMultiple( 1, m_ppsPropSpecs+nIndex, m_ppvPropVariants+nIndex, WIA_IPA_FIRST );
}
}
}
return(hr);
}
int CPropertyStorageArray::GetIndexFromPropId( PROPID propId )
{
if (!IsValid())
return -1;
for (int i=0;i<m_nCount;i++)
{
if (m_ppsPropSpecs[i].propid == propId)
return(i);
}
return(-1);
}
PROPVARIANT *CPropertyStorageArray::GetProperty( PROPID propId )
{
int nIndex = GetIndexFromPropId( propId );
if (nIndex < 0)
return(NULL);
return(m_ppvPropVariants+nIndex);
}
bool CPropertyStorageArray::GetProperty( PROPID propId, LONG &nProp )
{
PROPVARIANT *ppvPropValue = GetProperty( propId );
if (!ppvPropValue)
return(false);
if (VT_I4 != ppvPropValue->vt)
return(false);
nProp = ppvPropValue->lVal;
return(TRUE);
}
bool CPropertyStorageArray::GetProperty( PROPID propId, CSimpleStringWide &strProp )
{
PROPVARIANT *ppvPropValue = GetProperty( propId );
if (!ppvPropValue)
return(false);
if (VT_LPWSTR != ppvPropValue->vt && VT_BSTR != ppvPropValue->vt)
return(false);
strProp = ppvPropValue->pwszVal;
return(true);
}
bool CPropertyStorageArray::SetProperty( PROPID propId, PROPVARIANT *pPropVar )
{
PROPVARIANT *ppvPropValue = GetProperty( propId );
if (ppvPropValue)
{
PropVariantClear(ppvPropValue);
return(SUCCEEDED(PropVariantCopy(ppvPropValue,pPropVar)));
}
return(false);
}
bool CPropertyStorageArray::SetProperty( PROPID propId, LONG nProp )
{
PROPVARIANT *ppvPropValue = GetProperty( propId );
if (ppvPropValue)
{
ppvPropValue->vt = VT_I4;
ppvPropValue->lVal = nProp;
return(true);
}
return(false);
}
int CPropertyStorageArray::Count(void) const
{
return(m_nCount);
}
PROPVARIANT *CPropertyStorageArray::PropVariants(void) const
{
return(m_ppvPropVariants);
}
PROPSPEC *CPropertyStorageArray::PropSpecs(void) const
{
return(m_ppsPropSpecs);
}
LPWSTR *CPropertyStorageArray::PropNames(void) const
{
return(m_pstrPropNames);
}
void CPropertyStorageArray::Dump( int nIndex )
{
#if defined(WIA_DEBUG)
WIA_TRACE((TEXT("Dumping IWiaPropertyStorage:")));
int nStart = nIndex < 0 ? 0 : nIndex;
int nCount = nIndex < 0 ? Count() : 1;
for (int i=nStart;i<nCount;i++)
{
PROPVARIANT *pPropVar = GetProperty( m_ppsPropSpecs[i].propid );
if (pPropVar)
{
TCHAR szValue[512] = TEXT("");
switch (m_ppvPropVariants[i].vt)
{
case VT_I4:
wsprintf(szValue,TEXT("%d"),(LONG)m_ppvPropVariants[i].lVal);
break;
case VT_BSTR:
wsprintf(szValue,TEXT("%ws"),m_ppvPropVariants[i].bstrVal);
break;
case VT_VECTOR|VT_I4:
{
for (int j=0;j<(int)m_ppvPropVariants[i].cal.cElems;j++)
{
wsprintf(szValue+lstrlen(szValue),TEXT("%08X"),(LONG)m_ppvPropVariants[i].cal.pElems[j]);
if (j < (int)m_ppvPropVariants[i].cal.cElems-1)
wsprintf(szValue+lstrlen(szValue),TEXT(" "));
}
}
break;
case VT_VECTOR|VT_UI1:
{
for (int j=0;j<(int)m_ppvPropVariants[i].cal.cElems;j++)
{
wsprintf(szValue+lstrlen(szValue),TEXT("%02X"),(LONG)m_ppvPropVariants[i].caub.pElems[j]);
if (j < (int)m_ppvPropVariants[i].cal.cElems-1 && j % 4 == 3)
wsprintf(szValue+lstrlen(szValue),TEXT(" "));
}
}
break;
case VT_LPWSTR:
wsprintf(szValue,TEXT("%ws"),m_ppvPropVariants[i].pwszVal );
break;
default:
wsprintf(szValue,TEXT("Unknown Type %d (08X)"),m_ppvPropVariants[i].vt);
}
WIA_TRACE((TEXT(" [%-3d %ws] = [%s]"), m_ppsPropSpecs[i].propid, m_pstrPropNames[i], szValue));
}
}
#endif // defined(II_DEBUG)
}