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.

921 lines
25 KiB

  1. #include "stdafx.h"
  2. #include "Ctrl.h"
  3. #include "OldAnimation.h"
  4. PRID OldAlphaAnimation::s_pridAlpha = 0;
  5. PRID OldScaleAnimation::s_pridScale = 0;
  6. PRID OldRectAnimation::s_pridRect = 0;
  7. PRID OldRotateAnimation::s_pridRotate = 0;
  8. static const GUID guidAlphaAnimation = { 0x41a2e2f2, 0xf262, 0x41ae, { 0x89, 0xda, 0xb7, 0x9c, 0x8f, 0xf5, 0x94, 0xbb } }; // {41A2E2F2-F262-41ae-89DA-B79C8FF594BB}
  9. static const GUID guidScaleAnimation = { 0xa5b1df84, 0xb9c0, 0x4305, { 0xb9, 0x3a, 0x5b, 0x80, 0x31, 0x86, 0x70, 0x69 } }; // {A5B1DF84-B9C0-4305-B93A-5B8031867069}
  10. static const GUID guidRectAnimation = { 0x8e41c241, 0x3cdf, 0x432e, { 0xa1, 0xae, 0xf, 0x7b, 0x59, 0xdc, 0x82, 0xb } }; // {8E41C241-3CDF-432e-A1AE-0F7B59DC820B}
  11. static const GUID guidRotateAnimation = { 0x78f16dd5, 0xa198, 0x4cd2, { 0xb1, 0x78, 0x31, 0x61, 0x3e, 0x32, 0x12, 0x54 } }; // {78F16DD5-A198-4cd2-B178-31613E321254}
  12. const IID * OldAlphaAnimation::s_rgpIID[] =
  13. {
  14. &__uuidof(IUnknown),
  15. &__uuidof(IAnimation),
  16. NULL
  17. };
  18. const IID * OldScaleAnimation::s_rgpIID[] =
  19. {
  20. &__uuidof(IUnknown),
  21. &__uuidof(IAnimation),
  22. NULL
  23. };
  24. const IID * OldRectAnimation::s_rgpIID[] =
  25. {
  26. &__uuidof(IUnknown),
  27. &__uuidof(IAnimation),
  28. NULL
  29. };
  30. const IID * OldRotateAnimation::s_rgpIID[] =
  31. {
  32. &__uuidof(IUnknown),
  33. &__uuidof(IAnimation),
  34. NULL
  35. };
  36. /***************************************************************************\
  37. *****************************************************************************
  38. *
  39. * class OldAnimation
  40. *
  41. *****************************************************************************
  42. \***************************************************************************/
  43. //------------------------------------------------------------------------------
  44. OldAnimation::~OldAnimation()
  45. {
  46. #if DEBUG_TRACECREATION
  47. Trace("STOP Animation 0x%p @ %d (%d frames)\n", this, GetTickCount(), m_DEBUG_cUpdates);
  48. #endif // DEBUG_TRACECREATION
  49. //
  50. // Ensure proper destruction
  51. //
  52. AssertMsg(m_hact == NULL, "Action should already be destroyed");
  53. }
  54. //------------------------------------------------------------------------------
  55. HRESULT
  56. OldAnimation::Create(
  57. IN const GUID * pguid,
  58. IN OUT PRID * pprid,
  59. IN GANI_DESC * pDesc) // Animation information
  60. {
  61. if (pDesc->pipol != NULL) {
  62. pDesc->pipol->AddRef();
  63. m_pipol = pDesc->pipol;
  64. }
  65. if (pDesc->pcb != NULL) {
  66. pDesc->pcb->AddRef();
  67. m_pcb = pDesc->pcb;
  68. }
  69. GMA_ACTION gma;
  70. ZeroMemory(&gma, sizeof(gma));
  71. gma.cbSize = sizeof(gma);
  72. gma.flDelay = pDesc->act.flDelay;
  73. gma.flDuration = pDesc->act.flDuration;
  74. gma.flPeriod = pDesc->act.flPeriod;
  75. gma.cRepeat = pDesc->act.cRepeat;
  76. gma.dwPause = pDesc->act.dwPause;
  77. gma.pfnProc = RawActionProc;
  78. gma.pvData = this;
  79. m_hact = CreateAction(&gma);
  80. if (m_hact == NULL) {
  81. return (HRESULT) GetLastError();
  82. }
  83. HRESULT hr = OldExtension::Create(pDesc->hgadChange, pguid, pprid, OldExtension::oAsyncDestroy);
  84. if (FAILED(hr)) {
  85. return hr;
  86. }
  87. return S_OK;
  88. }
  89. //------------------------------------------------------------------------------
  90. void
  91. OldAnimation::Destroy(BOOL fFinal)
  92. {
  93. //
  94. // Mark that we have already started the destruction process and don't need
  95. // to start again. We only want to post the destruction message once.
  96. //
  97. if (m_fStartDestroy) {
  98. return;
  99. }
  100. m_fStartDestroy = TRUE;
  101. //
  102. // Give the derived Animation a chance to cleanup
  103. //
  104. // Check that we are still the Animation attached to this Gadget. We need
  105. // to remove this property immediately. We can not wait for a posted
  106. // message to be processed because we may need to set it right now if we are
  107. // creating a new Animation.
  108. //
  109. if (m_hgadSubject != NULL) {
  110. OnComplete();
  111. #if DBG
  112. OldAnimation * paniExist = static_cast<OldAnimation *> (GetExtension(m_hgadSubject, m_pridListen));
  113. if (paniExist != NULL) {
  114. AssertMsg(paniExist == this, "Animations must match");
  115. }
  116. #endif // DBG
  117. CleanupChangeGadget();
  118. }
  119. //
  120. // Destroy the Animation
  121. //
  122. AssertMsg(!fFinal, "Object is already being destructed");
  123. if (fFinal) {
  124. OnAsyncDestroy();
  125. } else {
  126. PostAsyncDestroy();
  127. }
  128. }
  129. //------------------------------------------------------------------------------
  130. void
  131. OldAnimation::OnAsyncDestroy()
  132. {
  133. AssertMsg(m_fStartDestroy, "Must call Destroy() to start the destruction process.");
  134. AssertMsg(!m_fProcessing, "Should not be processing when start destruction");
  135. AssertMsg(m_hgadSubject == NULL, "Animation should already have detached from Gadget");
  136. HACTION hact = m_hact;
  137. //
  138. // Notify any callback that the Animation is finished
  139. //
  140. if (m_pcb != NULL) {
  141. IAnimation * paniI = static_cast<IAnimation *> (this);
  142. __try
  143. {
  144. m_pcb->OnComplete(paniI, m_time);
  145. }
  146. __except(StdExceptionFilter(GetExceptionInformation()))
  147. {
  148. ExitProcess(GetExceptionCode());
  149. }
  150. }
  151. //
  152. // Set everything to NULL now.
  153. //
  154. m_hact = NULL;
  155. OldExtension::DeleteHandle();
  156. //
  157. // Stop the Action
  158. //
  159. if (hact != NULL) {
  160. ::DeleteHandle(hact);
  161. hact = NULL;
  162. }
  163. //
  164. // Release() our cached interfaces
  165. //
  166. SafeRelease(m_pipol);
  167. SafeRelease(m_pcb);
  168. }
  169. //------------------------------------------------------------------------------
  170. STDMETHODIMP_(void)
  171. OldAnimation::SetFunction(IInterpolation * pipol)
  172. {
  173. AssertReadPtr(pipol);
  174. SafeRelease(m_pipol);
  175. pipol->AddRef();
  176. m_pipol = pipol;
  177. }
  178. //------------------------------------------------------------------------------
  179. STDMETHODIMP_(void)
  180. OldAnimation::SetTime(IAnimation::ETime time)
  181. {
  182. GMA_ACTIONINFO mai;
  183. //
  184. // TODO: Need to save these values from the last time so that they are
  185. // valid.
  186. //
  187. mai.hact = m_hact;
  188. mai.pvData = this;
  189. mai.flDuration = 0.0f;
  190. m_time = time;
  191. switch (time)
  192. {
  193. case IAnimation::tComplete:
  194. // Don't do anything
  195. return;
  196. default:
  197. case IAnimation::tAbort:
  198. case IAnimation::tDestroy:
  199. goto Done;
  200. case IAnimation::tEnd:
  201. mai.flProgress = 1.0f;
  202. break;
  203. case IAnimation::tReset:
  204. mai.flProgress = 0.0f;
  205. break;
  206. }
  207. mai.cEvent = 0;
  208. mai.cPeriods = 0;
  209. mai.fFinished = FALSE;
  210. m_fProcessing = TRUE;
  211. Action(&mai);
  212. Assert(m_fProcessing);
  213. m_fProcessing = FALSE;
  214. Done:
  215. if (m_pcb != NULL) {
  216. IAnimation * paniI = static_cast<IAnimation *> (this);
  217. m_pcb->OnSetTime(paniI, time);
  218. }
  219. ::DeleteHandle(m_hact);
  220. }
  221. //------------------------------------------------------------------------------
  222. STDMETHODIMP_(void)
  223. OldAnimation::SetCallback(IAnimationCallback * pcb)
  224. {
  225. // pcb can be NULL
  226. SafeRelease(m_pcb);
  227. if (pcb != NULL) {
  228. pcb->AddRef();
  229. m_pcb = pcb;
  230. }
  231. }
  232. //------------------------------------------------------------------------------
  233. HRESULT
  234. OldAnimation::GetInterface(HGADGET hgad, PRID prid, REFIID riid, void ** ppvUnk)
  235. {
  236. OldAnimation * paniExist = static_cast<OldAnimation *> (GetExtension(hgad, prid));
  237. if (paniExist != NULL) {
  238. if (IsEqualIID(riid, __uuidof(IAnimation))) {
  239. paniExist->AddRef();
  240. *ppvUnk = static_cast<IAnimation *> (paniExist);
  241. return S_OK;
  242. } else {
  243. return paniExist->QueryInterface(riid, ppvUnk);
  244. }
  245. }
  246. return DU_E_NOTFOUND; // This Animation doesn't exist on this Gadget.
  247. }
  248. //------------------------------------------------------------------------------
  249. void
  250. OldAnimation::CleanupChangeGadget()
  251. {
  252. Assert(m_hgadSubject != NULL);
  253. Assert(m_pridListen != 0);
  254. Verify(::RemoveGadgetProperty(m_hgadSubject, m_pridListen));
  255. m_hgadSubject = NULL;
  256. }
  257. //------------------------------------------------------------------------------
  258. void CALLBACK
  259. OldAnimation::RawActionProc(
  260. IN GMA_ACTIONINFO * pmai)
  261. {
  262. OldAnimation * pani = (OldAnimation *) pmai->pvData;
  263. pani->AddRef();
  264. Assert(!pani->m_fProcessing);
  265. #if DBG
  266. pani->m_DEBUG_cUpdates++;
  267. #endif // DBG
  268. #if DEBUG_TRACECREATION
  269. Trace("START RawActionP 0x%p @ %d\n", pani, GetTickCount());
  270. #endif // DEBUG_TRACECREATION
  271. if ((!pani->m_fStartDestroy) && (pani->m_hgadSubject != NULL)) {
  272. //
  273. // This ActionProc will be called when the Action is being destroyed, so
  274. // we only want to invoke the Action under certain circumstances.
  275. //
  276. switch (pani->m_time)
  277. {
  278. case tComplete:
  279. case tEnd:
  280. case tReset:
  281. //
  282. // All of these are valid to complete. If it isn't in this list, we
  283. // don't want to execute it during a shutdown.
  284. //
  285. pani->m_fProcessing = TRUE;
  286. pani->Action(pmai);
  287. Assert(pani->m_fProcessing);
  288. pani->m_fProcessing = FALSE;
  289. break;
  290. }
  291. }
  292. if (pmai->fFinished) {
  293. pani->m_hact = NULL;
  294. pani->Destroy(FALSE);
  295. }
  296. #if DEBUG_TRACECREATION
  297. Trace("STOP RawActionP 0x%p @ %d\n", pani, GetTickCount());
  298. #endif // DEBUG_TRACECREATION
  299. Assert(!pani->m_fProcessing);
  300. pani->Release();
  301. }
  302. //------------------------------------------------------------------------------
  303. void
  304. OldAnimation::OnRemoveExisting()
  305. {
  306. SetTime(IAnimation::tDestroy);
  307. }
  308. //------------------------------------------------------------------------------
  309. void
  310. OldAnimation::OnDestroyListener()
  311. {
  312. AddRef();
  313. if (m_hgadListen != NULL) {
  314. //
  315. // TODO: Figure out when this case can actually occur. This means that
  316. // the MessageGadget was destroyed, but the caller didn't go through
  317. // OldAnimation::Destroy() to do it.
  318. //
  319. m_hgadListen = NULL;
  320. Destroy(FALSE);
  321. }
  322. VerifyMsg(Release() > 0, "Must still have lock from beginning of function");
  323. Release();
  324. }
  325. //------------------------------------------------------------------------------
  326. void
  327. OldAnimation::OnDestroySubject()
  328. {
  329. AddRef();
  330. if (m_hgadSubject != NULL) {
  331. CleanupChangeGadget();
  332. //
  333. // The Gadget that we are modifying is being destroyed, so we need
  334. // to stop animating it.
  335. //
  336. m_time = IAnimation::tDestroy;
  337. Destroy(FALSE);
  338. }
  339. Release();
  340. }
  341. /***************************************************************************\
  342. *****************************************************************************
  343. *
  344. * class OldAlphaAnimation
  345. *
  346. *****************************************************************************
  347. \***************************************************************************/
  348. //------------------------------------------------------------------------------
  349. OldAlphaAnimation::~OldAlphaAnimation()
  350. {
  351. Destroy(TRUE);
  352. #if DEBUG_TRACECREATION
  353. Trace("OldAlphaAnimation 0x%p destroyed\n", this);
  354. #endif // DEBUG_TRACECREATION
  355. }
  356. //------------------------------------------------------------------------------
  357. HRESULT
  358. OldAlphaAnimation::Create(
  359. IN GANI_DESC * pDesc)
  360. {
  361. HRESULT hr = OldAnimation::Create(&guidAlphaAnimation, &s_pridAlpha, pDesc);
  362. if (FAILED(hr)) {
  363. return hr;
  364. }
  365. //
  366. // Get the information from the Gadget
  367. //
  368. GANI_ALPHADESC * pDescA = (GANI_ALPHADESC *) pDesc;
  369. m_nOnComplete = pDescA->nOnComplete;
  370. m_fPushToChildren = pDescA->fPushToChildren &&
  371. (::GetGadget(m_hgadSubject, GG_TOPCHILD) != NULL);
  372. BOOL fBuffered = TestFlag(::GetGadgetStyle(m_hgadSubject), GS_BUFFERED);
  373. if (TestFlag(pDesc->nAniFlags, ANIF_USESTART)) {
  374. m_flStart = pDescA->flStart;
  375. } else {
  376. if (fBuffered) {
  377. //
  378. // Gadget is already buffered, so use it current alpha value.
  379. //
  380. BUFFER_INFO bi;
  381. ZeroMemory(&bi, sizeof(bi));
  382. bi.cbSize = sizeof(bi);
  383. bi.nMask = GBIM_ALPHA;
  384. if (::GetGadgetBufferInfo(m_hgadSubject, &bi)) {
  385. m_flStart = ((float) bi.bAlpha) / 255.0f;
  386. } else {
  387. m_flStart = 1.0f;
  388. }
  389. } else {
  390. m_flStart = 1.0f;
  391. }
  392. }
  393. if (m_fPushToChildren) {
  394. //
  395. // If we are currently alpha blended, we need to turn this off.
  396. //
  397. if (fBuffered) {
  398. ::SetGadgetStyle(m_hgadSubject, 0, GS_BUFFERED);
  399. ::SetGadgetStyle(m_hgadSubject, 0, GS_OPAQUE);
  400. }
  401. //
  402. // Setup each direct child to be buffered for the alpha-blending
  403. //
  404. BYTE bAlpha = (BYTE) (m_flStart * 255.0f);
  405. HGADGET hgadChild = ::GetGadget(m_hgadSubject, GG_TOPCHILD);
  406. while (hgadChild != NULL) {
  407. if (!::SetGadgetStyle(hgadChild, GS_BUFFERED | GS_OPAQUE, GS_BUFFERED | GS_OPAQUE)) {
  408. return (HRESULT) GetLastError();
  409. }
  410. BUFFER_INFO bi;
  411. bi.cbSize = sizeof(bi);
  412. bi.nMask = GBIM_ALPHA;
  413. bi.bAlpha = bAlpha;
  414. if (!SetGadgetBufferInfo(hgadChild, &bi)) {
  415. return (HRESULT) GetLastError();
  416. }
  417. hgadChild = ::GetGadget(hgadChild, GG_NEXT);
  418. }
  419. } else if (!fBuffered) {
  420. //
  421. // Need to mark the Gadget as being buffered to perform alpha effects
  422. //
  423. if (!::SetGadgetStyle(m_hgadSubject, GS_BUFFERED | GS_OPAQUE, GS_BUFFERED | GS_OPAQUE)) {
  424. return (HRESULT) GetLastError();
  425. }
  426. }
  427. m_flEnd = pDescA->flEnd;
  428. #if DEBUG_TRACECREATION
  429. Trace("OldAlphaAnimation 0x%p on 0x%p initialized\n", m_hgadSubject, this);
  430. #endif // DEBUG_TRACECREATION
  431. return S_OK;
  432. }
  433. //------------------------------------------------------------------------------
  434. STDMETHODIMP_(UINT)
  435. OldAlphaAnimation::GetID() const
  436. {
  437. return ANIMATION_ALPHA;
  438. }
  439. //------------------------------------------------------------------------------
  440. void
  441. OldAlphaAnimation::Action(GMA_ACTIONINFO * pmai)
  442. {
  443. float flPr = pmai->flProgress;
  444. float flAlpha = m_pipol->Compute(flPr, m_flStart, m_flEnd);
  445. BYTE bAlpha;
  446. if (flAlpha < 0.0f) {
  447. bAlpha = (BYTE) 0;
  448. } else if (flAlpha > 1.0f) {
  449. bAlpha = (BYTE) 255;
  450. } else {
  451. bAlpha = (BYTE) (flAlpha * 255.0f);
  452. }
  453. BUFFER_INFO bi;
  454. bi.cbSize = sizeof(bi);
  455. bi.nMask = GBIM_ALPHA;
  456. bi.bAlpha = bAlpha;
  457. if (m_fPushToChildren) {
  458. HGADGET hgadChild = ::GetGadget(m_hgadSubject, GG_TOPCHILD);
  459. while (hgadChild != NULL) {
  460. SetGadgetStyle(hgadChild, GS_BUFFERED | GS_OPAQUE, GS_BUFFERED | GS_OPAQUE);
  461. SetGadgetBufferInfo(hgadChild, &bi);
  462. InvalidateGadget(hgadChild);
  463. hgadChild = ::GetGadget(hgadChild, GG_NEXT);
  464. }
  465. } else {
  466. SetGadgetStyle(m_hgadSubject, GS_BUFFERED | GS_OPAQUE, GS_BUFFERED | GS_OPAQUE);
  467. SetGadgetBufferInfo(m_hgadSubject, &bi);
  468. InvalidateGadget(m_hgadSubject);
  469. }
  470. }
  471. //------------------------------------------------------------------------------
  472. void
  473. OldAlphaAnimation::OnComplete()
  474. {
  475. if (TestFlag(m_nOnComplete, GANI_ALPHACOMPLETE_OPTIMIZE)) {
  476. if ((m_flEnd * 255.0f) >= 245) {
  477. if (m_fPushToChildren) {
  478. HGADGET hgadChild = ::GetGadget(m_hgadSubject, GG_TOPCHILD);
  479. while (hgadChild != NULL) {
  480. SetGadgetStyle(hgadChild, 0, GS_BUFFERED);
  481. hgadChild = ::GetGadget(hgadChild, GG_NEXT);
  482. }
  483. } else {
  484. SetGadgetStyle(m_hgadSubject, 0, GS_BUFFERED);
  485. }
  486. InvalidateGadget(m_hgadSubject);
  487. }
  488. }
  489. }
  490. /***************************************************************************\
  491. *****************************************************************************
  492. *
  493. * class OldScaleAnimation
  494. *
  495. *****************************************************************************
  496. \***************************************************************************/
  497. //------------------------------------------------------------------------------
  498. OldScaleAnimation::~OldScaleAnimation()
  499. {
  500. Destroy(TRUE);
  501. #if DEBUG_TRACECREATION
  502. Trace("OldScaleAnimation 0x%p destroyed\n", this);
  503. #endif // DEBUG_TRACECREATION
  504. }
  505. //------------------------------------------------------------------------------
  506. HRESULT
  507. OldScaleAnimation::Create(
  508. IN GANI_DESC * pDesc)
  509. {
  510. HRESULT hr = OldAnimation::Create(&guidScaleAnimation, &s_pridScale, pDesc);
  511. if (FAILED(hr)) {
  512. return hr;
  513. }
  514. //
  515. // Get the information from the Gadget
  516. //
  517. GANI_SCALEDESC * pDescS = (GANI_SCALEDESC *) pDesc;
  518. if (TestFlag(pDesc->nAniFlags, ANIF_USESTART)) {
  519. m_flStart = pDescS->flStart;
  520. } else {
  521. float flX, flY;
  522. if (!::GetGadgetScale(m_hgadSubject, &flX, &flY)) {
  523. return (HRESULT) GetLastError();
  524. }
  525. m_flStart = flX;
  526. }
  527. m_flEnd = pDescS->flEnd;
  528. m_al = pDescS->al;
  529. RECT rcParent;
  530. ::GetGadgetRect(m_hgadSubject, &rcParent, SGR_PARENT);
  531. m_ptStart.x = rcParent.left;
  532. m_ptStart.y = rcParent.top;
  533. m_sizeCtrl.cx = rcParent.right - rcParent.left;
  534. m_sizeCtrl.cy = rcParent.bottom - rcParent.top;
  535. #if DEBUG_TRACECREATION
  536. Trace("OldScaleAnimation 0x%p on 0x%p initialized\n", m_hgadSubject, this);
  537. #endif // DEBUG_TRACECREATION
  538. return S_OK;
  539. }
  540. //------------------------------------------------------------------------------
  541. STDMETHODIMP_(UINT)
  542. OldScaleAnimation::GetID() const
  543. {
  544. return ANIMATION_SCALE;
  545. }
  546. //------------------------------------------------------------------------------
  547. void
  548. OldScaleAnimation::Action(GMA_ACTIONINFO * pmai)
  549. {
  550. float flPr = pmai->flProgress;
  551. float flx = m_pipol->Compute(flPr, m_flStart, m_flEnd);
  552. float fly = flx;
  553. ::SetGadgetScale(m_hgadSubject, flx, fly);
  554. POINT ptNew;
  555. ptNew.x = m_ptStart.x - (int) ((m_sizeCtrl.cx * flx - m_sizeCtrl.cx) / 2.0);
  556. ptNew.y = m_ptStart.y - (int) ((m_sizeCtrl.cy * fly - m_sizeCtrl.cy) / 2.0);
  557. ::SetGadgetRect(m_hgadSubject, ptNew.x, ptNew.y, 0, 0, SGR_MOVE | SGR_PARENT);
  558. }
  559. /***************************************************************************\
  560. *****************************************************************************
  561. *
  562. * class OldRectAnimation
  563. *
  564. *****************************************************************************
  565. \***************************************************************************/
  566. //------------------------------------------------------------------------------
  567. OldRectAnimation::~OldRectAnimation()
  568. {
  569. Destroy(TRUE);
  570. #if DEBUG_TRACECREATION
  571. Trace("OldRectAnimation 0x%p destroyed\n", this);
  572. #endif // DEBUG_TRACECREATION
  573. }
  574. //------------------------------------------------------------------------------
  575. HRESULT
  576. OldRectAnimation::Create(
  577. IN GANI_DESC * pDesc)
  578. {
  579. HRESULT hr = OldAnimation::Create(&guidRectAnimation, &s_pridRect, pDesc);
  580. if (FAILED(hr)) {
  581. return hr;
  582. }
  583. //
  584. // Get the information from the Gadget
  585. //
  586. GANI_RECTDESC * pDescR = (GANI_RECTDESC *) pDesc;
  587. UINT nGetFlags = SGR_VALID_GET & pDescR->nChangeFlags;
  588. if (nGetFlags == 0) {
  589. return E_INVALIDARG;
  590. }
  591. if (TestFlag(pDesc->nAniFlags, ANIF_USESTART)) {
  592. m_ptStart = pDescR->ptStart;
  593. m_sizeStart = pDescR->sizeStart;
  594. } else {
  595. RECT rcGadget;
  596. if (!::GetGadgetRect(m_hgadSubject, &rcGadget, nGetFlags)) {
  597. return (HRESULT) GetLastError();
  598. }
  599. m_ptStart.x = rcGadget.left;
  600. m_ptStart.y = rcGadget.top;
  601. m_sizeStart.cx = rcGadget.right - rcGadget.left;
  602. m_sizeStart.cy = rcGadget.bottom - rcGadget.top;
  603. }
  604. m_ptEnd = pDescR->ptEnd;
  605. m_sizeEnd = pDescR->sizeEnd;
  606. m_nChangeFlags = pDescR->nChangeFlags;
  607. #if DEBUG_TRACECREATION
  608. Trace("OldRectAnimation 0x%p on 0x%p initialized\n", m_hgadSubject, this);
  609. #endif // DEBUG_TRACECREATION
  610. return S_OK;
  611. }
  612. //------------------------------------------------------------------------------
  613. STDMETHODIMP_(UINT)
  614. OldRectAnimation::GetID() const
  615. {
  616. return ANIMATION_RECT;
  617. }
  618. //------------------------------------------------------------------------------
  619. void
  620. OldRectAnimation::Action(GMA_ACTIONINFO * pmai)
  621. {
  622. POINT ptNew;
  623. SIZE sizeNew;
  624. float flProgress = pmai->flProgress;
  625. ptNew.x = Compute(m_pipol, flProgress, m_ptStart.x, m_ptEnd.x);
  626. ptNew.y = Compute(m_pipol, flProgress, m_ptStart.y, m_ptEnd.y);
  627. sizeNew.cx = Compute(m_pipol, flProgress, m_sizeStart.cx, m_sizeEnd.cx);
  628. sizeNew.cy = Compute(m_pipol, flProgress, m_sizeStart.cy, m_sizeEnd.cy);
  629. SetGadgetRect(m_hgadSubject, ptNew.x, ptNew.y, sizeNew.cx, sizeNew.cy, m_nChangeFlags);
  630. }
  631. /***************************************************************************\
  632. *****************************************************************************
  633. *
  634. * class OldRotateAnimation
  635. *
  636. *****************************************************************************
  637. \***************************************************************************/
  638. //------------------------------------------------------------------------------
  639. OldRotateAnimation::~OldRotateAnimation()
  640. {
  641. Destroy(TRUE);
  642. #if DEBUG_TRACECREATION
  643. Trace("OldRotateAnimation 0x%p destroyed\n", this);
  644. #endif // DEBUG_TRACECREATION
  645. }
  646. //------------------------------------------------------------------------------
  647. HRESULT
  648. OldRotateAnimation::Create(
  649. IN GANI_DESC * pDesc)
  650. {
  651. HRESULT hr = OldAnimation::Create(&guidRotateAnimation, &s_pridRotate, pDesc);
  652. if (FAILED(hr)) {
  653. return hr;
  654. }
  655. //
  656. // Get the information from the Gadget
  657. //
  658. GANI_ROTATEDESC * pDescR = (GANI_ROTATEDESC *) pDesc;
  659. if (TestFlag(pDesc->nAniFlags, ANIF_USESTART)) {
  660. m_flStart = pDescR->flStart;
  661. } else {
  662. if (!::GetGadgetRotation(m_hgadSubject, &m_flStart)) {
  663. return (HRESULT) GetLastError();
  664. }
  665. }
  666. m_flEnd = pDescR->flEnd;
  667. m_nDir = pDescR->nDir;
  668. //
  669. // Adjust the starting and ending angles so that we "move" in the correct
  670. // direction. We do this by adding or subtracting full rotations depending
  671. // on the "move" we are trying to accomplish.
  672. //
  673. switch (m_nDir)
  674. {
  675. case GANI_ROTATEDIRECTION_SHORT:
  676. if (m_flStart < m_flEnd) {
  677. while ((m_flEnd - m_flStart) > (float) PI) {
  678. m_flStart += (float) (2 * PI);
  679. }
  680. } else {
  681. while ((m_flStart - m_flEnd) > (float) PI) {
  682. m_flStart -= (float) (2 * PI);
  683. }
  684. }
  685. break;
  686. case GANI_ROTATEDIRECTION_LONG:
  687. if (m_flStart < m_flEnd) {
  688. while ((m_flStart - m_flEnd) < (float) PI) {
  689. m_flEnd -= (float) (2 * PI);
  690. }
  691. } else {
  692. while ((m_flEnd - m_flStart) < (float) PI) {
  693. m_flEnd += (float) (2 * PI);
  694. }
  695. }
  696. break;
  697. case GANI_ROTATEDIRECTION_CW:
  698. while (m_flStart > m_flEnd) {
  699. m_flEnd += (float) (2 * PI);
  700. }
  701. break;
  702. case GANI_ROTATEDIRECTION_CCW:
  703. while (m_flStart < m_flEnd) {
  704. m_flStart += (float) (2 * PI);
  705. }
  706. break;
  707. }
  708. #if DEBUG_TRACECREATION
  709. Trace("OldRotateAnimation 0x%p on 0x%p initialized\n", m_hgadSubject, this);
  710. #endif // DEBUG_TRACECREATION
  711. return S_OK;
  712. }
  713. //------------------------------------------------------------------------------
  714. STDMETHODIMP_(UINT)
  715. OldRotateAnimation::GetID() const
  716. {
  717. return ANIMATION_ROTATE;
  718. }
  719. //------------------------------------------------------------------------------
  720. void
  721. OldRotateAnimation::Action(GMA_ACTIONINFO * pmai)
  722. {
  723. float flProgress = pmai->flProgress;
  724. float flAngleNew = Compute(m_pipol, flProgress, m_flStart, m_flEnd);
  725. SetGadgetRotation(m_hgadSubject, flAngleNew);
  726. }