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.

192 lines
5.3 KiB

  1. #include "priv.h"
  2. #include "fadetsk.h"
  3. #include "apithk.h"
  4. /// Fade Rect Support
  5. // {2DECD184-21B0-11d2-8385-00C04FD918D0}
  6. const GUID TASKID_Fader =
  7. { 0x2decd184, 0x21b0, 0x11d2, { 0x83, 0x85, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0 } };
  8. CFadeTask::CFadeTask() : CRunnableTask(RTF_DEFAULT)
  9. {
  10. ASSERT(g_bRunOnNT5); // This should only get created on NT5
  11. WNDCLASSEX wc = {0};
  12. if (!GetClassInfoEx(g_hinst, TEXT("SysFader"), &wc))
  13. {
  14. wc.cbSize = sizeof(wc);
  15. wc.lpfnWndProc = DefWindowProc;
  16. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  17. wc.hInstance = g_hinst;
  18. wc.lpszClassName = TEXT("SysFader");
  19. wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); // NULL;
  20. if (!RegisterClassEx(&wc))
  21. return;
  22. }
  23. _hwndFader = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT |
  24. WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
  25. TEXT("SysFader"), TEXT("SysFader"),
  26. WS_POPUP,
  27. 0, 0, 0, 0, NULL, (HMENU) 0,
  28. g_hinst, NULL);
  29. }
  30. CFadeTask::~CFadeTask()
  31. {
  32. if (_hwndFader)
  33. DestroyWindow(_hwndFader);
  34. }
  35. #define ALPHASTART (200)
  36. BOOL CFadeTask::FadeRect(PRECT prc, PFNFADESCREENRECT pfn, LPVOID pvParam)
  37. {
  38. if (IsRunning() == IRTIR_TASK_RUNNING)
  39. return FALSE;
  40. InterlockedExchange(&_lState, IRTIR_TASK_NOT_RUNNING);
  41. _rect = *prc;
  42. _pfn = pfn;
  43. _pvParam = pvParam;
  44. POINT pt;
  45. POINT ptSrc = {0, 0};
  46. SIZE size;
  47. // prc and pt are in screen coordinates.
  48. pt.x = _rect.left;
  49. pt.y = _rect.top;
  50. // Get the size of the rectangle for the blits.
  51. size.cx = RECTWIDTH(_rect);
  52. size.cy = RECTHEIGHT(_rect);
  53. // Get the DC for the screen and window.
  54. HDC hdcScreen = GetDC(NULL);
  55. if (hdcScreen)
  56. {
  57. HDC hdcWin = GetDC(_hwndFader);
  58. if (hdcWin)
  59. {
  60. // If we don't have a HDC for the fade, then create one.
  61. if (!_hdcFade)
  62. {
  63. _hdcFade = CreateCompatibleDC(hdcScreen);
  64. if (!_hdcFade)
  65. goto Stop;
  66. // Create a bitmap that covers the fade region, instead of the whole screen.
  67. _hbm = CreateCompatibleBitmap(hdcScreen, size.cx, size.cy);
  68. if (!_hbm)
  69. goto Stop;
  70. // select it in, saving the old bitmap's handle
  71. _hbmOld = (HBITMAP)SelectBitmap(_hdcFade, _hbm);
  72. }
  73. // Get the stuff from the screen and squirt it into the fade dc.
  74. BitBlt(_hdcFade, 0, 0, size.cx, size.cy, hdcScreen, pt.x, pt.y, SRCCOPY);
  75. // Now let user do it's magic. We're going to mimic user and start with a slightly
  76. // faded, instead of opaque, rendering (Looks smoother and cleaner.
  77. BlendLayeredWindow(_hwndFader, hdcWin, &pt, &size, _hdcFade, &ptSrc, ALPHASTART);
  78. // Now that we have it all build up, display it on screen.
  79. SetWindowPos(_hwndFader, HWND_TOPMOST, 0, 0, 0, 0,
  80. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
  81. Stop:
  82. ReleaseDC(_hwndFader, hdcWin);
  83. }
  84. ReleaseDC(NULL, hdcScreen);
  85. }
  86. if (_pfn)
  87. _pfn(FADE_BEGIN, _pvParam);
  88. return TRUE;
  89. }
  90. #define FADE_TIMER_ID 10
  91. #define FADE_TIMER_TIMEOUT 10 // milliseconds
  92. #define FADE_TIMEOUT 350 // milliseconds
  93. #define FADE_ITERATIONS 35
  94. #define QUAD_PART(a) ((a)##.QuadPart)
  95. void CFadeTask::_StopFade()
  96. {
  97. if (_hwndFader)
  98. {
  99. SetWindowPos(_hwndFader, HWND_BOTTOM, 0, 0, 0, 0,
  100. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
  101. }
  102. if (_pfn)
  103. _pfn(FADE_END, _pvParam);
  104. if (_hdcFade)
  105. {
  106. if (_hbmOld)
  107. {
  108. SelectBitmap(_hdcFade, _hbmOld);
  109. }
  110. DeleteDC(_hdcFade);
  111. _hdcFade = NULL;
  112. }
  113. if (_hbm)
  114. {
  115. DeleteObject(_hbm);
  116. _hbm = NULL;
  117. }
  118. }
  119. STDMETHODIMP CFadeTask::RunInitRT(void)
  120. {
  121. BOOL fRet = FALSE;
  122. LARGE_INTEGER liDiff;
  123. LARGE_INTEGER liFreq;
  124. LARGE_INTEGER liStart;
  125. DWORD dwElapsed;
  126. BYTE bBlendConst;
  127. // Start the fade timer and the count-down for the fade.
  128. QueryPerformanceFrequency(&liFreq);
  129. QueryPerformanceCounter(&liStart);
  130. // Do this until the conditions specified in the loop.
  131. while ( TRUE )
  132. {
  133. // Calculate the elapsed time in milliseconds.
  134. QueryPerformanceCounter(&liDiff);
  135. QUAD_PART(liDiff) -= QUAD_PART(liStart);
  136. dwElapsed = (DWORD)((QUAD_PART(liDiff) * 1000) / QUAD_PART(liFreq));
  137. if (dwElapsed >= FADE_TIMEOUT)
  138. {
  139. goto Stop;
  140. }
  141. bBlendConst = (BYTE)(ALPHASTART * (FADE_TIMEOUT -
  142. dwElapsed) / FADE_TIMEOUT);
  143. if (bBlendConst <= 1)
  144. {
  145. goto Stop;
  146. }
  147. // Since only the alpha is updated, there is no need to pass
  148. // anything but the new alpha function. This saves a source copy.
  149. BlendLayeredWindow(_hwndFader, NULL, NULL, NULL, NULL, NULL, bBlendConst);
  150. Sleep(FADE_TIMER_TIMEOUT);
  151. }
  152. Stop:
  153. _StopFade();
  154. return S_OK;
  155. }