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

  1. #include "stdafx.h"
  2. #include "Ctrl.h"
  3. #include "Flow.h"
  4. #if ENABLE_MSGTABLE_API
  5. PRID DuAlphaFlow::s_pridAlpha = 0;
  6. PRID DuScaleFlow::s_pridScale = 0;
  7. PRID DuRectFlow::s_pridRect = 0;
  8. PRID DuRotateFlow::s_pridRotate = 0;
  9. static const GUID guidAlphaFlow = { 0x41a2e2f2, 0xf262, 0x41ae, { 0x89, 0xda, 0xb7, 0x9c, 0x8f, 0xf5, 0x94, 0xbb } }; // {41A2E2F2-F262-41ae-89DA-B79C8FF594BB}
  10. static const GUID guidScaleFlow = { 0xa5b1df84, 0xb9c0, 0x4305, { 0xb9, 0x3a, 0x5b, 0x80, 0x31, 0x86, 0x70, 0x69 } }; // {A5B1DF84-B9C0-4305-B93A-5B8031867069}
  11. static const GUID guidRectFlow = { 0x8e41c241, 0x3cdf, 0x432e, { 0xa1, 0xae, 0xf, 0x7b, 0x59, 0xdc, 0x82, 0xb } }; // {8E41C241-3CDF-432e-A1AE-0F7B59DC820B}
  12. static const GUID guidRotateFlow = { 0x78f16dd5, 0xa198, 0x4cd2, { 0xb1, 0x78, 0x31, 0x61, 0x3e, 0x32, 0x12, 0x54 } }; // {78F16DD5-A198-4cd2-B178-31613E321254}
  13. /***************************************************************************\
  14. *****************************************************************************
  15. *
  16. * Public API
  17. *
  18. *****************************************************************************
  19. \***************************************************************************/
  20. //------------------------------------------------------------------------------
  21. PRID
  22. DUserGetAlphaPRID()
  23. {
  24. return DuAlphaFlow::s_pridAlpha;
  25. }
  26. //------------------------------------------------------------------------------
  27. PRID
  28. DUserGetRectPRID()
  29. {
  30. return DuRectFlow::s_pridRect;
  31. }
  32. //------------------------------------------------------------------------------
  33. PRID
  34. DUserGetRotatePRID()
  35. {
  36. return DuRotateFlow::s_pridRotate;
  37. }
  38. //------------------------------------------------------------------------------
  39. PRID
  40. DUserGetScalePRID()
  41. {
  42. return DuScaleFlow::s_pridScale;
  43. }
  44. /***************************************************************************\
  45. *****************************************************************************
  46. *
  47. * class DuFlow
  48. *
  49. *****************************************************************************
  50. \***************************************************************************/
  51. //------------------------------------------------------------------------------
  52. HRESULT
  53. DuFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
  54. {
  55. UNREFERENCED_PARAMETER(pmsg);
  56. return E_NOTIMPL;
  57. }
  58. //------------------------------------------------------------------------------
  59. HRESULT
  60. DuFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
  61. {
  62. UNREFERENCED_PARAMETER(pmsg);
  63. PromptInvalid("Derived Flow must override");
  64. return E_NOTIMPL;
  65. }
  66. //------------------------------------------------------------------------------
  67. HRESULT
  68. DuFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
  69. {
  70. UNREFERENCED_PARAMETER(pmsg);
  71. PromptInvalid("Derived Flow must override");
  72. return E_NOTIMPL;
  73. }
  74. //------------------------------------------------------------------------------
  75. HRESULT
  76. DuFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
  77. {
  78. UNREFERENCED_PARAMETER(pmsg);
  79. return E_NOTIMPL;
  80. }
  81. /***************************************************************************\
  82. *****************************************************************************
  83. *
  84. * class DuAlphaFlow
  85. *
  86. *****************************************************************************
  87. \***************************************************************************/
  88. //------------------------------------------------------------------------------
  89. HRESULT
  90. DuAlphaFlow::InitClass()
  91. {
  92. s_pridAlpha = RegisterGadgetProperty(&guidAlphaFlow);
  93. return s_pridAlpha != 0 ? S_OK : (HRESULT) GetLastError();
  94. }
  95. //------------------------------------------------------------------------------
  96. HRESULT
  97. DuAlphaFlow::PostBuild(
  98. IN DUser::Gadget::ConstructInfo * pci)
  99. {
  100. //
  101. // Get the information from the Gadget
  102. //
  103. Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
  104. Visual * pgvSubject = pDesc->pgvSubject;
  105. if (pgvSubject != NULL) {
  106. //
  107. // Given a subject, so setup from current attributes
  108. //
  109. UINT nStyle = 0;
  110. pgvSubject->GetStyle(&nStyle);
  111. if (!TestFlag(nStyle, GS_OPAQUE)) {
  112. PromptInvalid("AlphaFlow requires GS_OPAQUE");
  113. return E_INVALIDARG;
  114. }
  115. float flAlpha = 1.0f;
  116. if (TestFlag(nStyle, GS_BUFFERED)) {
  117. //
  118. // Gadget is already buffered, so use it current alpha value.
  119. //
  120. BUFFER_INFO bi;
  121. ZeroMemory(&bi, sizeof(bi));
  122. bi.cbSize = sizeof(bi);
  123. bi.nMask = GBIM_ALPHA;
  124. HRESULT hr = pgvSubject->GetBufferInfo(&bi);
  125. if (SUCCEEDED(hr)) {
  126. flAlpha = ((float) bi.bAlpha) / 255.0f;
  127. }
  128. }
  129. m_flStart = flAlpha;
  130. m_flEnd = flAlpha;
  131. } else {
  132. //
  133. // No subject, so use some reasonable defaults
  134. //
  135. m_flStart = 1.0f;
  136. m_flEnd = 1.0f;
  137. }
  138. #if DEBUG_TRACECREATION
  139. Trace("DuAlphaFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
  140. #endif // DEBUG_TRACECREATION
  141. return S_OK;
  142. }
  143. //------------------------------------------------------------------------------
  144. HRESULT
  145. DuAlphaFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
  146. {
  147. if (pmsg->pkf->cbSize != sizeof(AlphaFlow::AlphaKeyFrame)) {
  148. PromptInvalid("Incorrect keyframe size");
  149. return E_INVALIDARG;
  150. }
  151. AlphaFlow::AlphaKeyFrame * pkfA = static_cast<AlphaFlow::AlphaKeyFrame *>(pmsg->pkf);
  152. switch (pmsg->time)
  153. {
  154. case Flow::tBegin:
  155. pkfA->flAlpha = m_flStart;
  156. return S_OK;
  157. case Flow::tEnd:
  158. pkfA->flAlpha = m_flEnd;
  159. return S_OK;
  160. default:
  161. PromptInvalid("Invalid time");
  162. return E_INVALIDARG;
  163. }
  164. }
  165. //------------------------------------------------------------------------------
  166. HRESULT
  167. DuAlphaFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
  168. {
  169. if (pmsg->pkf->cbSize != sizeof(AlphaFlow::AlphaKeyFrame)) {
  170. PromptInvalid("Incorrect keyframe size");
  171. return E_INVALIDARG;
  172. }
  173. const AlphaFlow::AlphaKeyFrame * pkfA = static_cast<const AlphaFlow::AlphaKeyFrame *>(pmsg->pkf);
  174. float flAlpha = BoxAlpha(pkfA->flAlpha);
  175. switch (pmsg->time)
  176. {
  177. case Flow::tBegin:
  178. m_flStart = flAlpha;
  179. return S_OK;
  180. case Flow::tEnd:
  181. m_flEnd = flAlpha;
  182. return S_OK;
  183. default:
  184. PromptInvalid("Invalid time");
  185. return E_INVALIDARG;
  186. }
  187. }
  188. //------------------------------------------------------------------------------
  189. HRESULT
  190. DuAlphaFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
  191. {
  192. float flResult = 0.0f;
  193. pmsg->pipol->Compute(pmsg->flProgress, m_flStart, m_flEnd, &flResult);
  194. SetVisualAlpha(pmsg->pgvSubject, flResult);
  195. return S_OK;
  196. }
  197. //------------------------------------------------------------------------------
  198. HRESULT
  199. DuAlphaFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
  200. {
  201. SetVisualAlpha(pmsg->pgvSubject, m_flStart);
  202. return S_OK;
  203. }
  204. //------------------------------------------------------------------------------
  205. void
  206. DuAlphaFlow::SetVisualAlpha(Visual * pgvSubject, float flAlpha)
  207. {
  208. AssertMsg((flAlpha <= 1.0f) && (flAlpha >= 0.0f), "Ensure valid alpha");
  209. //
  210. // Setup Buffer state
  211. //
  212. BOOL fNewBuffered = (flAlpha * 255.0f) <= 245;
  213. UINT nStyle = 0;
  214. VerifyHR(pgvSubject->GetStyle(&nStyle));
  215. BOOL fOldBuffered = TestFlag(nStyle, GS_BUFFERED);
  216. if ((!fOldBuffered) != (!fNewBuffered)) {
  217. pgvSubject->SetStyle(fNewBuffered ? GS_BUFFERED : 0, GS_BUFFERED);
  218. }
  219. //
  220. // Set Alpha level
  221. //
  222. if (fNewBuffered) {
  223. BYTE bAlpha;
  224. if (flAlpha < 0.0f) {
  225. bAlpha = (BYTE) 0;
  226. } else if (flAlpha > 1.0f) {
  227. bAlpha = (BYTE) 255;
  228. } else {
  229. bAlpha = (BYTE) (flAlpha * 255.0f);
  230. }
  231. BUFFER_INFO bi;
  232. bi.cbSize = sizeof(bi);
  233. bi.nMask = GBIM_ALPHA;
  234. bi.bAlpha = bAlpha;
  235. pgvSubject->SetBufferInfo(&bi);
  236. }
  237. pgvSubject->Invalidate();
  238. }
  239. /***************************************************************************\
  240. *****************************************************************************
  241. *
  242. * class DuRectFlow
  243. *
  244. *****************************************************************************
  245. \***************************************************************************/
  246. //------------------------------------------------------------------------------
  247. HRESULT
  248. DuRectFlow::InitClass()
  249. {
  250. s_pridRect = RegisterGadgetProperty(&guidRectFlow);
  251. return s_pridRect != 0 ? S_OK : (HRESULT) GetLastError();
  252. }
  253. //------------------------------------------------------------------------------
  254. HRESULT
  255. DuRectFlow::PostBuild(
  256. IN DUser::Gadget::ConstructInfo * pci)
  257. {
  258. //
  259. // Get the information from the Gadget
  260. //
  261. Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
  262. Visual * pgvSubject = pDesc->pgvSubject;
  263. if (pgvSubject != NULL) {
  264. //
  265. // Given a subject, so setup from current attributes
  266. //
  267. RECT rcGadget;
  268. HRESULT hr = pgvSubject->GetRect(SGR_PARENT, &rcGadget);
  269. if (FAILED(hr)) {
  270. return hr;
  271. }
  272. m_ptStart.x = rcGadget.left;
  273. m_ptStart.y = rcGadget.top;
  274. m_sizeStart.cx = rcGadget.right - rcGadget.left;
  275. m_sizeStart.cy = rcGadget.bottom - rcGadget.top;
  276. m_ptEnd = m_ptStart;
  277. m_sizeEnd = m_sizeStart;
  278. m_nChangeFlags = 0;
  279. } else {
  280. //
  281. // No subject, so use some reasonable defaults
  282. //
  283. AssertMsg((m_ptEnd.x == 0) && (m_ptEnd.y == 0) &&
  284. (m_sizeEnd.cx == 0) && (m_sizeEnd.cy == 0) && (m_nChangeFlags == 0),
  285. "Ensure zero-init");
  286. }
  287. #if DEBUG_TRACECREATION
  288. Trace("DuRectFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
  289. #endif // DEBUG_TRACECREATION
  290. return S_OK;
  291. }
  292. //------------------------------------------------------------------------------
  293. HRESULT
  294. DuRectFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
  295. {
  296. if (pmsg->pkf->cbSize != sizeof(RectFlow::RectKeyFrame)) {
  297. PromptInvalid("Incorrect keyframe size");
  298. return E_INVALIDARG;
  299. }
  300. RectFlow::RectKeyFrame * pkfR = static_cast<RectFlow::RectKeyFrame *>(pmsg->pkf);
  301. switch (pmsg->time)
  302. {
  303. case Flow::tBegin:
  304. pkfR->rcPxl.left = m_ptStart.x;
  305. pkfR->rcPxl.top = m_ptStart.y;
  306. pkfR->rcPxl.right = m_ptStart.x + m_sizeStart.cx;
  307. pkfR->rcPxl.bottom = m_ptStart.y + m_sizeStart.cy;
  308. pkfR->nChangeFlags = m_nChangeFlags;
  309. return S_OK;
  310. case Flow::tEnd:
  311. pkfR->rcPxl.left = m_ptEnd.x;
  312. pkfR->rcPxl.top = m_ptEnd.y;
  313. pkfR->rcPxl.right = m_ptEnd.x + m_sizeEnd.cx;
  314. pkfR->rcPxl.bottom = m_ptEnd.y + m_sizeEnd.cy;
  315. pkfR->nChangeFlags = 0;
  316. return S_OK;
  317. default:
  318. PromptInvalid("Invalid time");
  319. return E_INVALIDARG;
  320. }
  321. }
  322. //------------------------------------------------------------------------------
  323. HRESULT
  324. DuRectFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
  325. {
  326. if (pmsg->pkf->cbSize != sizeof(RectFlow::RectKeyFrame)) {
  327. PromptInvalid("Incorrect keyframe size");
  328. return E_INVALIDARG;
  329. }
  330. const RectFlow::RectKeyFrame * pkfR = static_cast<const RectFlow::RectKeyFrame *>(pmsg->pkf);
  331. if ((pkfR->nChangeFlags & SGR_VALID_SET) != pkfR->nChangeFlags) {
  332. PromptInvalid("Invalid change flags");
  333. return E_INVALIDARG;
  334. }
  335. switch (pmsg->time)
  336. {
  337. case Flow::tBegin:
  338. m_ptStart.x = pkfR->rcPxl.left;
  339. m_ptStart.y = pkfR->rcPxl.top;
  340. m_sizeStart.cx = pkfR->rcPxl.right - pkfR->rcPxl.left;
  341. m_sizeStart.cy = pkfR->rcPxl.bottom - pkfR->rcPxl.top;
  342. m_nChangeFlags = pkfR->nChangeFlags;
  343. return S_OK;
  344. case Flow::tEnd:
  345. m_ptEnd.x = pkfR->rcPxl.left;
  346. m_ptEnd.y = pkfR->rcPxl.top;
  347. m_sizeEnd.cx = pkfR->rcPxl.right - pkfR->rcPxl.left;
  348. m_sizeEnd.cy = pkfR->rcPxl.bottom - pkfR->rcPxl.top;
  349. m_nChangeFlags = pkfR->nChangeFlags;
  350. return S_OK;
  351. default:
  352. PromptInvalid("Invalid time");
  353. return E_INVALIDARG;
  354. }
  355. }
  356. //------------------------------------------------------------------------------
  357. HRESULT
  358. DuRectFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
  359. {
  360. if (m_nChangeFlags != 0) {
  361. pmsg->pgvSubject->SetRect(m_nChangeFlags, m_ptStart.x, m_ptStart.y, m_sizeStart.cx, m_sizeStart.cy);
  362. }
  363. return S_OK;
  364. }
  365. //------------------------------------------------------------------------------
  366. HRESULT
  367. DuRectFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
  368. {
  369. if (m_nChangeFlags != 0) {
  370. POINT ptNew;
  371. SIZE sizeNew;
  372. ptNew.x = Compute(pmsg->pipol, pmsg->flProgress, m_ptStart.x, m_ptEnd.x);
  373. ptNew.y = Compute(pmsg->pipol, pmsg->flProgress, m_ptStart.y, m_ptEnd.y);
  374. sizeNew.cx = Compute(pmsg->pipol, pmsg->flProgress, m_sizeStart.cx, m_sizeEnd.cx);
  375. sizeNew.cy = Compute(pmsg->pipol, pmsg->flProgress, m_sizeStart.cy, m_sizeEnd.cy);
  376. pmsg->pgvSubject->SetRect(m_nChangeFlags, ptNew.x, ptNew.y, sizeNew.cx, sizeNew.cy);
  377. }
  378. return S_OK;
  379. }
  380. /***************************************************************************\
  381. *****************************************************************************
  382. *
  383. * class DuRotateFlow
  384. *
  385. *****************************************************************************
  386. \***************************************************************************/
  387. //------------------------------------------------------------------------------
  388. HRESULT
  389. DuRotateFlow::InitClass()
  390. {
  391. s_pridRotate = RegisterGadgetProperty(&guidRotateFlow);
  392. return s_pridRotate != 0 ? S_OK : (HRESULT) GetLastError();
  393. }
  394. //------------------------------------------------------------------------------
  395. HRESULT
  396. DuRotateFlow::PostBuild(
  397. IN DUser::Gadget::ConstructInfo * pci)
  398. {
  399. //
  400. // Get the information from the Gadget
  401. //
  402. Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
  403. Visual * pgvSubject = pDesc->pgvSubject;
  404. if (pgvSubject != NULL) {
  405. //
  406. // Given a subject, so setup from current attributes
  407. //
  408. float flRotation;
  409. HRESULT hr = pgvSubject->GetRotation(&flRotation);
  410. if (FAILED(hr)) {
  411. return hr;
  412. }
  413. m_flRawStart = flRotation;
  414. m_flRawEnd = flRotation;
  415. m_flActualStart = flRotation;
  416. m_flActualEnd = flRotation;
  417. } else {
  418. //
  419. // No subject, so use some reasonable defaults
  420. //
  421. AssertMsg((m_flRawStart == 0.0f) && (m_flRawEnd == 0.0f),
  422. "Ensure zero-init");
  423. }
  424. m_nDir = RotateFlow::dMin;
  425. MarkDirty();
  426. #if DEBUG_TRACECREATION
  427. Trace("DuRotateFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
  428. #endif // DEBUG_TRACECREATION
  429. return S_OK;
  430. }
  431. //------------------------------------------------------------------------------
  432. HRESULT
  433. DuRotateFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
  434. {
  435. if (pmsg->pkf->cbSize != sizeof(RotateFlow::RotateKeyFrame)) {
  436. PromptInvalid("Incorrect keyframe size");
  437. return E_INVALIDARG;
  438. }
  439. RotateFlow::RotateKeyFrame * pkfR = static_cast<RotateFlow::RotateKeyFrame *>(pmsg->pkf);
  440. switch (pmsg->time)
  441. {
  442. case Flow::tBegin:
  443. pkfR->flRotation = m_flRawStart;
  444. pkfR->nDir = m_nDir;
  445. return S_OK;
  446. case Flow::tEnd:
  447. pkfR->flRotation = m_flRawEnd;
  448. pkfR->nDir = m_nDir;
  449. return S_OK;
  450. default:
  451. PromptInvalid("Invalid time");
  452. return E_INVALIDARG;
  453. }
  454. }
  455. //------------------------------------------------------------------------------
  456. HRESULT
  457. DuRotateFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
  458. {
  459. if (pmsg->pkf->cbSize != sizeof(RotateFlow::RotateKeyFrame)) {
  460. PromptInvalid("Incorrect keyframe size");
  461. return E_INVALIDARG;
  462. }
  463. const RotateFlow::RotateKeyFrame * pkfR = static_cast<const RotateFlow::RotateKeyFrame *>(pmsg->pkf);
  464. switch (pmsg->time)
  465. {
  466. case Flow::tBegin:
  467. m_flRawStart = pkfR->flRotation;
  468. m_nDir = pkfR->nDir;
  469. MarkDirty();
  470. return S_OK;
  471. case Flow::tEnd:
  472. m_flRawEnd = pkfR->flRotation;
  473. m_nDir = pkfR->nDir;
  474. MarkDirty();
  475. return S_OK;
  476. default:
  477. PromptInvalid("Invalid time");
  478. return E_INVALIDARG;
  479. }
  480. }
  481. //------------------------------------------------------------------------------
  482. HRESULT
  483. DuRotateFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
  484. {
  485. ComputeAngles();
  486. pmsg->pgvSubject->SetRotation(m_flActualStart);
  487. return S_OK;
  488. }
  489. //------------------------------------------------------------------------------
  490. HRESULT
  491. DuRotateFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
  492. {
  493. ComputeAngles();
  494. pmsg->pgvSubject->SetRotation(Compute(pmsg->pipol, pmsg->flProgress, m_flActualStart, m_flActualEnd));
  495. return S_OK;
  496. }
  497. /***************************************************************************\
  498. *
  499. * DuRotateFlow::ComputeAngles
  500. *
  501. * ComputeAngles() updates the angles to conform to the desired direction.
  502. * This is lazily computed, allowing the application to specify the angles
  503. * and direction in any order, then snapping the angles when actually needed.
  504. *
  505. \***************************************************************************/
  506. void
  507. DuRotateFlow::ComputeAngles()
  508. {
  509. if (!m_fDirty) {
  510. return;
  511. }
  512. //
  513. // Adjust the starting and ending angles so that we "move" in the correct
  514. // direction. We do this by adding or subtracting full rotations depending
  515. // on the "move" we are trying to accomplish.
  516. //
  517. m_flActualStart = m_flRawStart;
  518. m_flActualEnd = m_flRawEnd;
  519. switch (m_nDir)
  520. {
  521. case RotateFlow::dShort:
  522. if (m_flActualStart < m_flActualEnd) {
  523. while ((m_flActualEnd - m_flActualStart) > (float) PI) {
  524. m_flActualStart += (float) (2 * PI);
  525. }
  526. } else {
  527. while ((m_flActualStart - m_flActualEnd) > (float) PI) {
  528. m_flActualStart -= (float) (2 * PI);
  529. }
  530. }
  531. break;
  532. case RotateFlow::dLong:
  533. if (m_flActualStart < m_flActualEnd) {
  534. while ((m_flActualStart - m_flActualEnd) < (float) PI) {
  535. m_flActualEnd -= (float) (2 * PI);
  536. }
  537. } else {
  538. while ((m_flActualEnd - m_flActualStart) < (float) PI) {
  539. m_flActualEnd += (float) (2 * PI);
  540. }
  541. }
  542. break;
  543. case RotateFlow::dCW:
  544. while (m_flActualStart > m_flActualEnd) {
  545. m_flActualEnd += (float) (2 * PI);
  546. }
  547. break;
  548. case RotateFlow::dCCW:
  549. while (m_flActualStart < m_flActualEnd) {
  550. m_flActualStart += (float) (2 * PI);
  551. }
  552. break;
  553. }
  554. m_fDirty = FALSE;
  555. }
  556. /***************************************************************************\
  557. *****************************************************************************
  558. *
  559. * class DuScaleFlow
  560. *
  561. *****************************************************************************
  562. \***************************************************************************/
  563. //------------------------------------------------------------------------------
  564. HRESULT
  565. DuScaleFlow::InitClass()
  566. {
  567. s_pridScale = RegisterGadgetProperty(&guidScaleFlow);
  568. return s_pridScale != 0 ? S_OK : (HRESULT) GetLastError();
  569. }
  570. //------------------------------------------------------------------------------
  571. HRESULT
  572. DuScaleFlow::PostBuild(
  573. IN DUser::Gadget::ConstructInfo * pci)
  574. {
  575. //
  576. // Get the information from the Gadget
  577. //
  578. Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
  579. Visual * pgvSubject = pDesc->pgvSubject;
  580. if (pgvSubject != NULL) {
  581. //
  582. // Given a subject, so setup from current attributes
  583. //
  584. float flX, flY;
  585. HRESULT hr = pgvSubject->GetScale(&flX, &flY);
  586. if (FAILED(hr)) {
  587. return hr;
  588. }
  589. m_flStart = flX;
  590. m_flEnd = flX;
  591. } else {
  592. //
  593. // No subject, so use some reasonable defaults
  594. //
  595. m_flStart = 1.0f;
  596. m_flEnd = 1.0f;
  597. }
  598. #if DEBUG_TRACECREATION
  599. Trace("DuScaleFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
  600. #endif // DEBUG_TRACECREATION
  601. return S_OK;
  602. }
  603. //------------------------------------------------------------------------------
  604. HRESULT
  605. DuScaleFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
  606. {
  607. if (pmsg->pkf->cbSize != sizeof(ScaleFlow::ScaleKeyFrame)) {
  608. PromptInvalid("Incorrect keyframe size");
  609. return E_INVALIDARG;
  610. }
  611. ScaleFlow::ScaleKeyFrame * pkfS = static_cast<ScaleFlow::ScaleKeyFrame *>(pmsg->pkf);
  612. switch (pmsg->time)
  613. {
  614. case Flow::tBegin:
  615. pkfS->flScale = m_flStart;
  616. return S_OK;
  617. case Flow::tEnd:
  618. pkfS->flScale = m_flEnd;
  619. return S_OK;
  620. default:
  621. PromptInvalid("Invalid time");
  622. return E_INVALIDARG;
  623. }
  624. }
  625. //------------------------------------------------------------------------------
  626. HRESULT
  627. DuScaleFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
  628. {
  629. if (pmsg->pkf->cbSize != sizeof(ScaleFlow::ScaleKeyFrame)) {
  630. PromptInvalid("Incorrect keyframe size");
  631. return E_INVALIDARG;
  632. }
  633. const ScaleFlow::ScaleKeyFrame * pkfS = static_cast<const ScaleFlow::ScaleKeyFrame *>(pmsg->pkf);
  634. switch (pmsg->time)
  635. {
  636. case Flow::tBegin:
  637. m_flStart = pkfS->flScale;
  638. return S_OK;
  639. case Flow::tEnd:
  640. m_flEnd = pkfS->flScale;
  641. return S_OK;
  642. default:
  643. PromptInvalid("Invalid time");
  644. return E_INVALIDARG;
  645. }
  646. }
  647. //------------------------------------------------------------------------------
  648. HRESULT
  649. DuScaleFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
  650. {
  651. pmsg->pgvSubject->SetScale(m_flStart, m_flStart);
  652. return S_OK;
  653. }
  654. //------------------------------------------------------------------------------
  655. HRESULT
  656. DuScaleFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
  657. {
  658. float flx = Compute(pmsg->pipol, pmsg->flProgress, m_flStart, m_flEnd);
  659. float fly = flx;
  660. pmsg->pgvSubject->SetScale(flx, fly);
  661. return S_OK;
  662. }
  663. #else // ENABLE_MSGTABLE_API
  664. /***************************************************************************\
  665. *****************************************************************************
  666. *
  667. * Public API
  668. *
  669. *****************************************************************************
  670. \***************************************************************************/
  671. //------------------------------------------------------------------------------
  672. PRID
  673. DUserGetAlphaPRID()
  674. {
  675. PromptInvalid("Not implemented without MsgTable support");
  676. return 0;
  677. }
  678. //------------------------------------------------------------------------------
  679. PRID
  680. DUserGetRectPRID()
  681. {
  682. PromptInvalid("Not implemented without MsgTable support");
  683. return 0;
  684. }
  685. //------------------------------------------------------------------------------
  686. PRID
  687. DUserGetRotatePRID()
  688. {
  689. PromptInvalid("Not implemented without MsgTable support");
  690. return 0;
  691. }
  692. //------------------------------------------------------------------------------
  693. PRID
  694. DUserGetScalePRID()
  695. {
  696. PromptInvalid("Not implemented without MsgTable support");
  697. return 0;
  698. }
  699. #endif // ENABLE_MSGTABLE_API