/******************************************************************************* * * (C) COPYRIGHT MICROSOFT CORPORATION, 1998 * * TITLE: VWIASET.H * * VERSION: 1.0 * * AUTHOR: ShaunIv * * DATE: 1/10/2000 * * DESCRIPTION: Encapsulate the differences between LIST and RANGE properties * *******************************************************************************/ #ifndef __VWIASET_H_INCLUDED #define __VWIASET_H_INCLUDED #include #include "pshelper.h" class CValidWiaSettings { private: // // Indices into array for range values // enum { MinValue = 0, MaxValue = 1, StepValue = 2 }; private: CSimpleDynamicArray m_ValueList; LONG m_nInitialValue; LONG m_nType; public: CValidWiaSettings(void) : m_nType(0), m_nInitialValue(0) { } CValidWiaSettings( IUnknown *pUnknown, const PropStorageHelpers::CPropertyId &propertyName ) : m_nType(0), m_nInitialValue(0) { Read( pUnknown, propertyName ); } CValidWiaSettings( const CValidWiaSettings &other ) : m_nType(0), m_nInitialValue(0) { Assign(other); } CValidWiaSettings &operator=( const CValidWiaSettings &other ) { if (&other != this) { Assign(other); } return *this; } CValidWiaSettings &Assign( const CValidWiaSettings &other ) { Destroy(); m_nType = other.Type(); m_ValueList = other.ValueList(); m_nInitialValue = other.InitialValue(); if (!IsValid()) { Destroy(); } return *this; } LONG Type(void) const { return m_nType; } LONG InitialValue(void) const { return m_nInitialValue; } const CSimpleDynamicArray &ValueList(void) const { return m_ValueList; } CSimpleDynamicArray &ValueList(void) { return m_ValueList; } void Destroy(void) { m_nType = 0; m_nInitialValue = 0; m_ValueList.Destroy(); } bool IsValid(void) const { if (IsList()) { return (m_ValueList.Size() != 0); } else if (IsRange()) { return (m_ValueList.Size() == 3); } else return false; } bool Read( IUnknown *pUnknown, const PropStorageHelpers::CPropertyId &propertyName ) { bool bSuccess = false; Destroy(); m_nType = 0; // // If we can't read this value, we're done // if (!PropStorageHelpers::GetProperty( pUnknown, propertyName, m_nInitialValue )) { return false; } ULONG nAccessFlags; if (PropStorageHelpers::GetPropertyAccessFlags( pUnknown, propertyName, nAccessFlags )) { if (nAccessFlags & WIA_PROP_LIST) { if (PropStorageHelpers::GetPropertyList( pUnknown, propertyName, m_ValueList )) { m_nType = WIA_PROP_LIST; bSuccess = (m_ValueList.Size() != 0); } } else if (nAccessFlags & WIA_PROP_RANGE) { PropStorageHelpers::CPropertyRange PropertyRange; if (PropStorageHelpers::GetPropertyRange( pUnknown, propertyName, PropertyRange )) { m_nType = WIA_PROP_RANGE; m_ValueList.Append( PropertyRange.nMin ); m_ValueList.Append( PropertyRange.nMax ); m_ValueList.Append( PropertyRange.nStep ); bSuccess = (m_ValueList.Size() == 3); } } } if (!bSuccess) { Destroy(); } return bSuccess; } bool FindClosestValueByRoundingDown( LONG &nValue ) const { // // Make sure we have a valid item // if (!IsValid()) { return false; } if (IsRange()) { // // Make sure we are in the legal range // nValue = WiaUiUtil::Min( WiaUiUtil::Max( m_ValueList[MinValue], nValue ), m_ValueList[MaxValue] ); // // Divide the difference between nValue and min by nStep, then multiply by nStep to // get rid of the remainder to round down to the nearest value // nValue = m_ValueList[MinValue] + (((nValue - m_ValueList[MinValue]) / m_ValueList[StepValue]) * m_ValueList[StepValue]); return true; } else if (IsList() && m_ValueList.Size()) { // // Assume the list is sorted, so we can take the first item and assume it is the minimum value // LONG nResult = m_ValueList[0]; for (int i=0;i nValue) { break; } nResult = m_ValueList[i]; } nValue = nResult; return true; } return false; } bool FindClosestValue( LONG &nValue ) const { LONG nFloor=nValue; if (FindClosestValueByRoundingDown(nFloor)) { LONG nCeiling=nFloor; if (Increment(nCeiling)) { if (nValue - nFloor < nCeiling - nValue) { nValue = nFloor; return true; } else { nValue = nCeiling; return true; } } } return false; } bool IsLegalValue( LONG nValue ) const { LONG nTestValue = nValue; if (FindClosestValueByRoundingDown(nTestValue)) { return (nTestValue == nValue); } return false; } int FindIndexOfItem( LONG nCurrentValue ) const { if (IsRange()) { // // Make sure we are in the legal range // nCurrentValue = WiaUiUtil::Min( WiaUiUtil::Max( m_ValueList[MinValue], nCurrentValue ), m_ValueList[MaxValue] ); return (nCurrentValue - m_ValueList[MinValue]) / m_ValueList[StepValue]; } else if (IsList() && m_ValueList.Size()) { // // Assume the list is sorted, so we can take the first item and assume it is the minimum value // for (int i=0;i= m_ValueList.Size()) { nIndex = m_ValueList.Size() - 1; } // // Return it // nCurrentValue = m_ValueList[nIndex]; // // Everything is OK // return true; } return false; } bool Decrement( LONG &nCurrentValue ) const { // // Round us off. This will also take care of validation. // if (!FindClosestValueByRoundingDown( nCurrentValue )) { return false; } if (IsRange()) { // // Let FindClosestValueByRoundingDown take care of making sure that we don't go under the minimum // nCurrentValue -= m_ValueList[StepValue]; return FindClosestValueByRoundingDown( nCurrentValue ); } else if (IsList() && m_ValueList.Size()) { int nIndex = FindIndexOfItem( nCurrentValue ); // // Make sure we are in the list // if (nIndex < 0) { return false; } // // Get the previous value // nIndex--; // // Make sure we aren't before the beginning of the list // if (nIndex < 0) { nIndex = 0; } // // Return it // nCurrentValue = m_ValueList[nIndex]; // // Everything is OK // return true; } return false; } LONG GetItemCount(void) const { if (IsList()) { return m_ValueList.Size(); } else if (IsRange()) { // // Calculate the number of steps between the minimum and maximum // return ((m_ValueList[MaxValue] - m_ValueList[MinValue]) / m_ValueList[StepValue]) + 1; } return 0; } bool GetItemAtIndex( int nIndex, LONG &nItem ) const { if (!IsValid()) { return false; } if (IsList() && nIndex >= 0 && nIndex < m_ValueList.Size()) { nItem = m_ValueList[nIndex]; return true; } else if (IsRange() && nIndex < GetItemCount()) { // // Return the minimum + nIndex * stepvalue // nItem = m_ValueList[MinValue] + (m_ValueList[StepValue] * nIndex); return true; } return false; } bool FindIntersection( const CValidWiaSettings &Set1, const CValidWiaSettings &Set2 ) { // // We are modifying ourselves, so clear all of our data // Destroy(); // // If either set is invalid, no intersection // if (!Set1.IsValid() || !Set2.IsValid()) { return false; } // // If either a or b is a set (or both), just add all of the items // that are legal in both to ourself and set the type to a LIST // if (Set1.IsList()) { m_nType = WIA_PROP_LIST; for (int i=0;i