helper ValueFlow { class RawValue { // Construction public: RawValue() { m_dType = DUIV_UNSET; } RawValue(const RawValue & rvSrc) { // NOTE: This won't work if we have a v-table CopyMemory(this, &rvSrc, sizeof(RawValue)); } RawValue & operator=(const RawValue & rvSrc) { // NOTE: This won't work if we have a v-table CopyMemory(this, &rvSrc, sizeof(RawValue)); return *this; } // Operations: inline int GetType() { return m_dType; } inline int GetInt() { ASSERT(m_dType == DUIV_INT); return m_intVal; } inline bool GetBool() { ASSERT(m_dType == DUIV_BOOL); return m_boolVal; } inline const POINT* GetPoint() { ASSERT(m_dType == DUIV_POINT); return &m_ptVal; } inline const SIZE* GetSize() { ASSERT(m_dType == DUIV_SIZE); return &m_sizeVal; } inline const RECT* GetRect() { ASSERT(m_dType == DUIV_RECT); return &m_rectVal; } inline const DirectUI::Fill* GetFill() { ASSERT(m_dType == DUIV_FILL); return &m_fillVal; } inline void SetInt(int val) { m_dType = DUIV_INT; m_intVal = val; } inline void SetBool(bool val) { m_dType = DUIV_BOOL; m_boolVal = val; } inline void SetPoint(int x, int y) { m_dType = DUIV_POINT; m_ptVal.x = x; m_ptVal.y = y; } inline void SetPoint(const POINT & pt) { m_dType = DUIV_POINT; m_ptVal = pt; } inline void SetSize(int cx, int cy) { m_dType = DUIV_SIZE; m_sizeVal.cx = cx; m_sizeVal.cy = cy; } inline void SetSize(const SIZE & val) { m_dType = DUIV_SIZE; m_sizeVal = val; } inline void SetRect(int left, int top, int right, int bottom) { m_dType = DUIV_RECT; m_rectVal.left = left; m_rectVal.top = top; m_rectVal.right = right; m_rectVal.bottom = bottom; } inline void SetRect(const RECT & rc) { m_dType = DUIV_RECT; m_rectVal = rc; } inline void SetFill(const DirectUI::Fill & clr) { m_dType = DUIV_FILL; m_fillVal = clr; } HRESULT SetValue(DirectUI::Value * pvSrc) { int nNewType = pvSrc->GetType(); switch (nNewType) { case DUIV_INT: m_intVal = pvSrc->GetInt(); break; case DUIV_BOOL: m_boolVal = pvSrc->GetBool(); break; case DUIV_POINT: m_ptVal = *(pvSrc->GetPoint()); break; case DUIV_SIZE: m_sizeVal = *(pvSrc->GetSize()); break; case DUIV_RECT: m_rectVal = *(pvSrc->GetRect()); break; case DUIV_FILL: m_fillVal = *(pvSrc->GetFill()); break; default: ASSERT(0 && "Unknown value type"); return E_INVALIDARG; } m_dType = (short) nNewType; return S_OK; } HRESULT GetValue(DirectUI::Value ** ppvNew) { DirectUI::Value * pvNew = NULL; switch (m_dType) { case DUIV_INT: pvNew = DirectUI::Value::CreateInt(m_intVal); break; case DUIV_BOOL: pvNew = DirectUI::Value::CreateBool(m_boolVal); break; case DUIV_POINT: pvNew = DirectUI::Value::CreatePoint(m_ptVal.x, m_ptVal.y); break; case DUIV_SIZE: pvNew = DirectUI::Value::CreateSize(m_sizeVal.cx, m_sizeVal.cy); break; case DUIV_RECT: pvNew = DirectUI::Value::CreateRect(m_rectVal.left, m_rectVal.top, m_rectVal.right, m_rectVal.bottom); break; case DUIV_FILL: pvNew = DirectUI::Value::CreateFill(m_fillVal); default: ASSERT(0 && "Unknown value type"); return E_INVALIDARG; } *ppvNew = pvNew; return S_OK; } // Data protected: short m_dType; union { int m_intVal; bool m_boolVal; POINT m_ptVal; SIZE m_sizeVal; RECT m_rectVal; DirectUI::Fill m_fillVal; }; }; struct ValueFlowCI : public Flow::FlowCI { DirectUI::PropertyInfo* ppi; }; struct ValueKeyFrame : DUser::KeyFrame { DirectUI::PropertyInfo* ppi; ValueFlow::RawValue rv; }; };