Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

881 lines
24 KiB

#include "stdafx.h"
#include "Ctrl.h"
#include "Flow.h"
#if ENABLE_MSGTABLE_API
PRID DuAlphaFlow::s_pridAlpha = 0;
PRID DuScaleFlow::s_pridScale = 0;
PRID DuRectFlow::s_pridRect = 0;
PRID DuRotateFlow::s_pridRotate = 0;
static const GUID guidAlphaFlow = { 0x41a2e2f2, 0xf262, 0x41ae, { 0x89, 0xda, 0xb7, 0x9c, 0x8f, 0xf5, 0x94, 0xbb } }; // {41A2E2F2-F262-41ae-89DA-B79C8FF594BB}
static const GUID guidScaleFlow = { 0xa5b1df84, 0xb9c0, 0x4305, { 0xb9, 0x3a, 0x5b, 0x80, 0x31, 0x86, 0x70, 0x69 } }; // {A5B1DF84-B9C0-4305-B93A-5B8031867069}
static const GUID guidRectFlow = { 0x8e41c241, 0x3cdf, 0x432e, { 0xa1, 0xae, 0xf, 0x7b, 0x59, 0xdc, 0x82, 0xb } }; // {8E41C241-3CDF-432e-A1AE-0F7B59DC820B}
static const GUID guidRotateFlow = { 0x78f16dd5, 0xa198, 0x4cd2, { 0xb1, 0x78, 0x31, 0x61, 0x3e, 0x32, 0x12, 0x54 } }; // {78F16DD5-A198-4cd2-B178-31613E321254}
/***************************************************************************\
*****************************************************************************
*
* Public API
*
*****************************************************************************
\***************************************************************************/
//------------------------------------------------------------------------------
PRID
DUserGetAlphaPRID()
{
return DuAlphaFlow::s_pridAlpha;
}
//------------------------------------------------------------------------------
PRID
DUserGetRectPRID()
{
return DuRectFlow::s_pridRect;
}
//------------------------------------------------------------------------------
PRID
DUserGetRotatePRID()
{
return DuRotateFlow::s_pridRotate;
}
//------------------------------------------------------------------------------
PRID
DUserGetScalePRID()
{
return DuScaleFlow::s_pridScale;
}
/***************************************************************************\
*****************************************************************************
*
* class DuFlow
*
*****************************************************************************
\***************************************************************************/
//------------------------------------------------------------------------------
HRESULT
DuFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
{
UNREFERENCED_PARAMETER(pmsg);
return E_NOTIMPL;
}
//------------------------------------------------------------------------------
HRESULT
DuFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
{
UNREFERENCED_PARAMETER(pmsg);
PromptInvalid("Derived Flow must override");
return E_NOTIMPL;
}
//------------------------------------------------------------------------------
HRESULT
DuFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
{
UNREFERENCED_PARAMETER(pmsg);
PromptInvalid("Derived Flow must override");
return E_NOTIMPL;
}
//------------------------------------------------------------------------------
HRESULT
DuFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
{
UNREFERENCED_PARAMETER(pmsg);
return E_NOTIMPL;
}
/***************************************************************************\
*****************************************************************************
*
* class DuAlphaFlow
*
*****************************************************************************
\***************************************************************************/
//------------------------------------------------------------------------------
HRESULT
DuAlphaFlow::InitClass()
{
s_pridAlpha = RegisterGadgetProperty(&guidAlphaFlow);
return s_pridAlpha != 0 ? S_OK : (HRESULT) GetLastError();
}
//------------------------------------------------------------------------------
HRESULT
DuAlphaFlow::PostBuild(
IN DUser::Gadget::ConstructInfo * pci)
{
//
// Get the information from the Gadget
//
Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
Visual * pgvSubject = pDesc->pgvSubject;
if (pgvSubject != NULL) {
//
// Given a subject, so setup from current attributes
//
UINT nStyle = 0;
pgvSubject->GetStyle(&nStyle);
if (!TestFlag(nStyle, GS_OPAQUE)) {
PromptInvalid("AlphaFlow requires GS_OPAQUE");
return E_INVALIDARG;
}
float flAlpha = 1.0f;
if (TestFlag(nStyle, GS_BUFFERED)) {
//
// Gadget is already buffered, so use it current alpha value.
//
BUFFER_INFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.cbSize = sizeof(bi);
bi.nMask = GBIM_ALPHA;
HRESULT hr = pgvSubject->GetBufferInfo(&bi);
if (SUCCEEDED(hr)) {
flAlpha = ((float) bi.bAlpha) / 255.0f;
}
}
m_flStart = flAlpha;
m_flEnd = flAlpha;
} else {
//
// No subject, so use some reasonable defaults
//
m_flStart = 1.0f;
m_flEnd = 1.0f;
}
#if DEBUG_TRACECREATION
Trace("DuAlphaFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
#endif // DEBUG_TRACECREATION
return S_OK;
}
//------------------------------------------------------------------------------
HRESULT
DuAlphaFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
{
if (pmsg->pkf->cbSize != sizeof(AlphaFlow::AlphaKeyFrame)) {
PromptInvalid("Incorrect keyframe size");
return E_INVALIDARG;
}
AlphaFlow::AlphaKeyFrame * pkfA = static_cast<AlphaFlow::AlphaKeyFrame *>(pmsg->pkf);
switch (pmsg->time)
{
case Flow::tBegin:
pkfA->flAlpha = m_flStart;
return S_OK;
case Flow::tEnd:
pkfA->flAlpha = m_flEnd;
return S_OK;
default:
PromptInvalid("Invalid time");
return E_INVALIDARG;
}
}
//------------------------------------------------------------------------------
HRESULT
DuAlphaFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
{
if (pmsg->pkf->cbSize != sizeof(AlphaFlow::AlphaKeyFrame)) {
PromptInvalid("Incorrect keyframe size");
return E_INVALIDARG;
}
const AlphaFlow::AlphaKeyFrame * pkfA = static_cast<const AlphaFlow::AlphaKeyFrame *>(pmsg->pkf);
float flAlpha = BoxAlpha(pkfA->flAlpha);
switch (pmsg->time)
{
case Flow::tBegin:
m_flStart = flAlpha;
return S_OK;
case Flow::tEnd:
m_flEnd = flAlpha;
return S_OK;
default:
PromptInvalid("Invalid time");
return E_INVALIDARG;
}
}
//------------------------------------------------------------------------------
HRESULT
DuAlphaFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
{
float flResult = 0.0f;
pmsg->pipol->Compute(pmsg->flProgress, m_flStart, m_flEnd, &flResult);
SetVisualAlpha(pmsg->pgvSubject, flResult);
return S_OK;
}
//------------------------------------------------------------------------------
HRESULT
DuAlphaFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
{
SetVisualAlpha(pmsg->pgvSubject, m_flStart);
return S_OK;
}
//------------------------------------------------------------------------------
void
DuAlphaFlow::SetVisualAlpha(Visual * pgvSubject, float flAlpha)
{
AssertMsg((flAlpha <= 1.0f) && (flAlpha >= 0.0f), "Ensure valid alpha");
//
// Setup Buffer state
//
BOOL fNewBuffered = (flAlpha * 255.0f) <= 245;
UINT nStyle = 0;
VerifyHR(pgvSubject->GetStyle(&nStyle));
BOOL fOldBuffered = TestFlag(nStyle, GS_BUFFERED);
if ((!fOldBuffered) != (!fNewBuffered)) {
pgvSubject->SetStyle(fNewBuffered ? GS_BUFFERED : 0, GS_BUFFERED);
}
//
// Set Alpha level
//
if (fNewBuffered) {
BYTE bAlpha;
if (flAlpha < 0.0f) {
bAlpha = (BYTE) 0;
} else if (flAlpha > 1.0f) {
bAlpha = (BYTE) 255;
} else {
bAlpha = (BYTE) (flAlpha * 255.0f);
}
BUFFER_INFO bi;
bi.cbSize = sizeof(bi);
bi.nMask = GBIM_ALPHA;
bi.bAlpha = bAlpha;
pgvSubject->SetBufferInfo(&bi);
}
pgvSubject->Invalidate();
}
/***************************************************************************\
*****************************************************************************
*
* class DuRectFlow
*
*****************************************************************************
\***************************************************************************/
//------------------------------------------------------------------------------
HRESULT
DuRectFlow::InitClass()
{
s_pridRect = RegisterGadgetProperty(&guidRectFlow);
return s_pridRect != 0 ? S_OK : (HRESULT) GetLastError();
}
//------------------------------------------------------------------------------
HRESULT
DuRectFlow::PostBuild(
IN DUser::Gadget::ConstructInfo * pci)
{
//
// Get the information from the Gadget
//
Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
Visual * pgvSubject = pDesc->pgvSubject;
if (pgvSubject != NULL) {
//
// Given a subject, so setup from current attributes
//
RECT rcGadget;
HRESULT hr = pgvSubject->GetRect(SGR_PARENT, &rcGadget);
if (FAILED(hr)) {
return hr;
}
m_ptStart.x = rcGadget.left;
m_ptStart.y = rcGadget.top;
m_sizeStart.cx = rcGadget.right - rcGadget.left;
m_sizeStart.cy = rcGadget.bottom - rcGadget.top;
m_ptEnd = m_ptStart;
m_sizeEnd = m_sizeStart;
m_nChangeFlags = 0;
} else {
//
// No subject, so use some reasonable defaults
//
AssertMsg((m_ptEnd.x == 0) && (m_ptEnd.y == 0) &&
(m_sizeEnd.cx == 0) && (m_sizeEnd.cy == 0) && (m_nChangeFlags == 0),
"Ensure zero-init");
}
#if DEBUG_TRACECREATION
Trace("DuRectFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
#endif // DEBUG_TRACECREATION
return S_OK;
}
//------------------------------------------------------------------------------
HRESULT
DuRectFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
{
if (pmsg->pkf->cbSize != sizeof(RectFlow::RectKeyFrame)) {
PromptInvalid("Incorrect keyframe size");
return E_INVALIDARG;
}
RectFlow::RectKeyFrame * pkfR = static_cast<RectFlow::RectKeyFrame *>(pmsg->pkf);
switch (pmsg->time)
{
case Flow::tBegin:
pkfR->rcPxl.left = m_ptStart.x;
pkfR->rcPxl.top = m_ptStart.y;
pkfR->rcPxl.right = m_ptStart.x + m_sizeStart.cx;
pkfR->rcPxl.bottom = m_ptStart.y + m_sizeStart.cy;
pkfR->nChangeFlags = m_nChangeFlags;
return S_OK;
case Flow::tEnd:
pkfR->rcPxl.left = m_ptEnd.x;
pkfR->rcPxl.top = m_ptEnd.y;
pkfR->rcPxl.right = m_ptEnd.x + m_sizeEnd.cx;
pkfR->rcPxl.bottom = m_ptEnd.y + m_sizeEnd.cy;
pkfR->nChangeFlags = 0;
return S_OK;
default:
PromptInvalid("Invalid time");
return E_INVALIDARG;
}
}
//------------------------------------------------------------------------------
HRESULT
DuRectFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
{
if (pmsg->pkf->cbSize != sizeof(RectFlow::RectKeyFrame)) {
PromptInvalid("Incorrect keyframe size");
return E_INVALIDARG;
}
const RectFlow::RectKeyFrame * pkfR = static_cast<const RectFlow::RectKeyFrame *>(pmsg->pkf);
if ((pkfR->nChangeFlags & SGR_VALID_SET) != pkfR->nChangeFlags) {
PromptInvalid("Invalid change flags");
return E_INVALIDARG;
}
switch (pmsg->time)
{
case Flow::tBegin:
m_ptStart.x = pkfR->rcPxl.left;
m_ptStart.y = pkfR->rcPxl.top;
m_sizeStart.cx = pkfR->rcPxl.right - pkfR->rcPxl.left;
m_sizeStart.cy = pkfR->rcPxl.bottom - pkfR->rcPxl.top;
m_nChangeFlags = pkfR->nChangeFlags;
return S_OK;
case Flow::tEnd:
m_ptEnd.x = pkfR->rcPxl.left;
m_ptEnd.y = pkfR->rcPxl.top;
m_sizeEnd.cx = pkfR->rcPxl.right - pkfR->rcPxl.left;
m_sizeEnd.cy = pkfR->rcPxl.bottom - pkfR->rcPxl.top;
m_nChangeFlags = pkfR->nChangeFlags;
return S_OK;
default:
PromptInvalid("Invalid time");
return E_INVALIDARG;
}
}
//------------------------------------------------------------------------------
HRESULT
DuRectFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
{
if (m_nChangeFlags != 0) {
pmsg->pgvSubject->SetRect(m_nChangeFlags, m_ptStart.x, m_ptStart.y, m_sizeStart.cx, m_sizeStart.cy);
}
return S_OK;
}
//------------------------------------------------------------------------------
HRESULT
DuRectFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
{
if (m_nChangeFlags != 0) {
POINT ptNew;
SIZE sizeNew;
ptNew.x = Compute(pmsg->pipol, pmsg->flProgress, m_ptStart.x, m_ptEnd.x);
ptNew.y = Compute(pmsg->pipol, pmsg->flProgress, m_ptStart.y, m_ptEnd.y);
sizeNew.cx = Compute(pmsg->pipol, pmsg->flProgress, m_sizeStart.cx, m_sizeEnd.cx);
sizeNew.cy = Compute(pmsg->pipol, pmsg->flProgress, m_sizeStart.cy, m_sizeEnd.cy);
pmsg->pgvSubject->SetRect(m_nChangeFlags, ptNew.x, ptNew.y, sizeNew.cx, sizeNew.cy);
}
return S_OK;
}
/***************************************************************************\
*****************************************************************************
*
* class DuRotateFlow
*
*****************************************************************************
\***************************************************************************/
//------------------------------------------------------------------------------
HRESULT
DuRotateFlow::InitClass()
{
s_pridRotate = RegisterGadgetProperty(&guidRotateFlow);
return s_pridRotate != 0 ? S_OK : (HRESULT) GetLastError();
}
//------------------------------------------------------------------------------
HRESULT
DuRotateFlow::PostBuild(
IN DUser::Gadget::ConstructInfo * pci)
{
//
// Get the information from the Gadget
//
Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
Visual * pgvSubject = pDesc->pgvSubject;
if (pgvSubject != NULL) {
//
// Given a subject, so setup from current attributes
//
float flRotation;
HRESULT hr = pgvSubject->GetRotation(&flRotation);
if (FAILED(hr)) {
return hr;
}
m_flRawStart = flRotation;
m_flRawEnd = flRotation;
m_flActualStart = flRotation;
m_flActualEnd = flRotation;
} else {
//
// No subject, so use some reasonable defaults
//
AssertMsg((m_flRawStart == 0.0f) && (m_flRawEnd == 0.0f),
"Ensure zero-init");
}
m_nDir = RotateFlow::dMin;
MarkDirty();
#if DEBUG_TRACECREATION
Trace("DuRotateFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
#endif // DEBUG_TRACECREATION
return S_OK;
}
//------------------------------------------------------------------------------
HRESULT
DuRotateFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
{
if (pmsg->pkf->cbSize != sizeof(RotateFlow::RotateKeyFrame)) {
PromptInvalid("Incorrect keyframe size");
return E_INVALIDARG;
}
RotateFlow::RotateKeyFrame * pkfR = static_cast<RotateFlow::RotateKeyFrame *>(pmsg->pkf);
switch (pmsg->time)
{
case Flow::tBegin:
pkfR->flRotation = m_flRawStart;
pkfR->nDir = m_nDir;
return S_OK;
case Flow::tEnd:
pkfR->flRotation = m_flRawEnd;
pkfR->nDir = m_nDir;
return S_OK;
default:
PromptInvalid("Invalid time");
return E_INVALIDARG;
}
}
//------------------------------------------------------------------------------
HRESULT
DuRotateFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
{
if (pmsg->pkf->cbSize != sizeof(RotateFlow::RotateKeyFrame)) {
PromptInvalid("Incorrect keyframe size");
return E_INVALIDARG;
}
const RotateFlow::RotateKeyFrame * pkfR = static_cast<const RotateFlow::RotateKeyFrame *>(pmsg->pkf);
switch (pmsg->time)
{
case Flow::tBegin:
m_flRawStart = pkfR->flRotation;
m_nDir = pkfR->nDir;
MarkDirty();
return S_OK;
case Flow::tEnd:
m_flRawEnd = pkfR->flRotation;
m_nDir = pkfR->nDir;
MarkDirty();
return S_OK;
default:
PromptInvalid("Invalid time");
return E_INVALIDARG;
}
}
//------------------------------------------------------------------------------
HRESULT
DuRotateFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
{
ComputeAngles();
pmsg->pgvSubject->SetRotation(m_flActualStart);
return S_OK;
}
//------------------------------------------------------------------------------
HRESULT
DuRotateFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
{
ComputeAngles();
pmsg->pgvSubject->SetRotation(Compute(pmsg->pipol, pmsg->flProgress, m_flActualStart, m_flActualEnd));
return S_OK;
}
/***************************************************************************\
*
* DuRotateFlow::ComputeAngles
*
* ComputeAngles() updates the angles to conform to the desired direction.
* This is lazily computed, allowing the application to specify the angles
* and direction in any order, then snapping the angles when actually needed.
*
\***************************************************************************/
void
DuRotateFlow::ComputeAngles()
{
if (!m_fDirty) {
return;
}
//
// Adjust the starting and ending angles so that we "move" in the correct
// direction. We do this by adding or subtracting full rotations depending
// on the "move" we are trying to accomplish.
//
m_flActualStart = m_flRawStart;
m_flActualEnd = m_flRawEnd;
switch (m_nDir)
{
case RotateFlow::dShort:
if (m_flActualStart < m_flActualEnd) {
while ((m_flActualEnd - m_flActualStart) > (float) PI) {
m_flActualStart += (float) (2 * PI);
}
} else {
while ((m_flActualStart - m_flActualEnd) > (float) PI) {
m_flActualStart -= (float) (2 * PI);
}
}
break;
case RotateFlow::dLong:
if (m_flActualStart < m_flActualEnd) {
while ((m_flActualStart - m_flActualEnd) < (float) PI) {
m_flActualEnd -= (float) (2 * PI);
}
} else {
while ((m_flActualEnd - m_flActualStart) < (float) PI) {
m_flActualEnd += (float) (2 * PI);
}
}
break;
case RotateFlow::dCW:
while (m_flActualStart > m_flActualEnd) {
m_flActualEnd += (float) (2 * PI);
}
break;
case RotateFlow::dCCW:
while (m_flActualStart < m_flActualEnd) {
m_flActualStart += (float) (2 * PI);
}
break;
}
m_fDirty = FALSE;
}
/***************************************************************************\
*****************************************************************************
*
* class DuScaleFlow
*
*****************************************************************************
\***************************************************************************/
//------------------------------------------------------------------------------
HRESULT
DuScaleFlow::InitClass()
{
s_pridScale = RegisterGadgetProperty(&guidScaleFlow);
return s_pridScale != 0 ? S_OK : (HRESULT) GetLastError();
}
//------------------------------------------------------------------------------
HRESULT
DuScaleFlow::PostBuild(
IN DUser::Gadget::ConstructInfo * pci)
{
//
// Get the information from the Gadget
//
Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
Visual * pgvSubject = pDesc->pgvSubject;
if (pgvSubject != NULL) {
//
// Given a subject, so setup from current attributes
//
float flX, flY;
HRESULT hr = pgvSubject->GetScale(&flX, &flY);
if (FAILED(hr)) {
return hr;
}
m_flStart = flX;
m_flEnd = flX;
} else {
//
// No subject, so use some reasonable defaults
//
m_flStart = 1.0f;
m_flEnd = 1.0f;
}
#if DEBUG_TRACECREATION
Trace("DuScaleFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
#endif // DEBUG_TRACECREATION
return S_OK;
}
//------------------------------------------------------------------------------
HRESULT
DuScaleFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
{
if (pmsg->pkf->cbSize != sizeof(ScaleFlow::ScaleKeyFrame)) {
PromptInvalid("Incorrect keyframe size");
return E_INVALIDARG;
}
ScaleFlow::ScaleKeyFrame * pkfS = static_cast<ScaleFlow::ScaleKeyFrame *>(pmsg->pkf);
switch (pmsg->time)
{
case Flow::tBegin:
pkfS->flScale = m_flStart;
return S_OK;
case Flow::tEnd:
pkfS->flScale = m_flEnd;
return S_OK;
default:
PromptInvalid("Invalid time");
return E_INVALIDARG;
}
}
//------------------------------------------------------------------------------
HRESULT
DuScaleFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
{
if (pmsg->pkf->cbSize != sizeof(ScaleFlow::ScaleKeyFrame)) {
PromptInvalid("Incorrect keyframe size");
return E_INVALIDARG;
}
const ScaleFlow::ScaleKeyFrame * pkfS = static_cast<const ScaleFlow::ScaleKeyFrame *>(pmsg->pkf);
switch (pmsg->time)
{
case Flow::tBegin:
m_flStart = pkfS->flScale;
return S_OK;
case Flow::tEnd:
m_flEnd = pkfS->flScale;
return S_OK;
default:
PromptInvalid("Invalid time");
return E_INVALIDARG;
}
}
//------------------------------------------------------------------------------
HRESULT
DuScaleFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
{
pmsg->pgvSubject->SetScale(m_flStart, m_flStart);
return S_OK;
}
//------------------------------------------------------------------------------
HRESULT
DuScaleFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
{
float flx = Compute(pmsg->pipol, pmsg->flProgress, m_flStart, m_flEnd);
float fly = flx;
pmsg->pgvSubject->SetScale(flx, fly);
return S_OK;
}
#else // ENABLE_MSGTABLE_API
/***************************************************************************\
*****************************************************************************
*
* Public API
*
*****************************************************************************
\***************************************************************************/
//------------------------------------------------------------------------------
PRID
DUserGetAlphaPRID()
{
PromptInvalid("Not implemented without MsgTable support");
return 0;
}
//------------------------------------------------------------------------------
PRID
DUserGetRectPRID()
{
PromptInvalid("Not implemented without MsgTable support");
return 0;
}
//------------------------------------------------------------------------------
PRID
DUserGetRotatePRID()
{
PromptInvalid("Not implemented without MsgTable support");
return 0;
}
//------------------------------------------------------------------------------
PRID
DUserGetScalePRID()
{
PromptInvalid("Not implemented without MsgTable support");
return 0;
}
#endif // ENABLE_MSGTABLE_API