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.

144 lines
4.8 KiB

  1. // CSqueegee.cpp: implementation of the CSqueegee class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "CSqueegee.h"
  5. extern TextureBrush *g_paBrCleanBkg;
  6. extern Bitmap *g_paBmDirtyBkg;
  7. CSqueegee::CSqueegee()
  8. {
  9. ZeroMemory(&m_rDesktop,sizeof(m_rDesktop));
  10. ZeroMemory(&m_vLastPos,sizeof(m_vLastPos));
  11. m_flSqueegeeWidth=0.0f;
  12. m_paSqueegee=NULL;
  13. m_paBackground=NULL;
  14. m_flLastAngle=0.0f;
  15. }
  16. CSqueegee::~CSqueegee()
  17. {
  18. Destroy();
  19. }
  20. void CSqueegee::Destroy()
  21. {
  22. if (m_paSqueegee!=NULL) {
  23. delete m_paSqueegee;
  24. m_paSqueegee=NULL;
  25. }
  26. if (m_paBackground!=NULL) {
  27. delete m_paBackground;
  28. m_paBackground=NULL;
  29. }
  30. }
  31. BOOL CSqueegee::Init(HWND hWnd)
  32. {
  33. float flWidth;
  34. float flHeight;
  35. Destroy();
  36. // Get desktop dimensions (left/top can be negative on multimon)
  37. GetClientRect(hWnd,&m_rDesktop);
  38. flWidth=(float)m_rDesktop.right;
  39. flHeight=(float)m_rDesktop.bottom;
  40. m_rDesktop.top+=GetSystemMetrics(SM_YVIRTUALSCREEN);
  41. m_rDesktop.bottom+=GetSystemMetrics(SM_YVIRTUALSCREEN);
  42. m_rDesktop.left+=GetSystemMetrics(SM_XVIRTUALSCREEN);
  43. m_rDesktop.right+=GetSystemMetrics(SM_XVIRTUALSCREEN);
  44. m_flVelMax=((float)rand()/(float)RAND_MAX)*10.0f+35.0f;
  45. m_paSqueegee=LoadTGAResource(MAKEINTRESOURCE(IDR_SQUEEGEE));
  46. m_nSnapshotSize=(int)sqrt(m_paSqueegee->GetWidth()*m_paSqueegee->GetWidth()+(m_paSqueegee->GetHeight()+m_flVelMax*2.0f)*(m_paSqueegee->GetHeight()+m_flVelMax*2.0f));
  47. m_paBackground=new Bitmap(m_nSnapshotSize,m_nSnapshotSize,PixelFormat32bppPARGB);
  48. m_flSqueegeeWidth=m_paSqueegee->GetWidth()-6.0f;
  49. // Squeegees start from top left corner
  50. m_vPos.X=(float)m_rDesktop.left-(float)m_nSnapshotSize/2.0f;
  51. m_vPos.Y=(float)m_rDesktop.top+m_flSqueegeeWidth/2.0f;
  52. m_vVel.X=m_flVelMax;
  53. m_vVel.Y=0.0f;
  54. m_vAcc.X=0.0f;
  55. m_vAcc.Y=0.0f;
  56. m_vLastPos=m_vPos;
  57. m_flLastAngle=((float)atan2(m_vVel.Y,m_vVel.X)*180.0f/3.1415f);
  58. return true;
  59. }
  60. BOOL CSqueegee::Move(Graphics *g)
  61. // Returns true if moved on screen, false if moved outside screen
  62. {
  63. // Update position and other variables
  64. m_vLastPos=m_vPos;
  65. m_vPos=m_vPos+m_vVel;
  66. if ((m_vPos.X<(float)m_rDesktop.left-(float)m_nSnapshotSize) ||
  67. (m_vPos.X>(float)m_rDesktop.right+(float)m_nSnapshotSize)) {
  68. // If past the left/right edge of the screen, turn around and move down a notch
  69. m_vPos.Y+=m_flSqueegeeWidth-10.0f;
  70. m_vVel.X*=-1.0f;
  71. m_flLastAngle+=180.0f;
  72. }
  73. else if (m_vPos.Y>(float)m_rDesktop.bottom+(float)m_nSnapshotSize) {
  74. // If past the bottom of the screen, its done
  75. return false;
  76. }
  77. Wipe(g);
  78. return true;
  79. }
  80. void CSqueegee::Wipe(Graphics *g)
  81. {
  82. Graphics *gBackground;
  83. RectF rect(0.0f,0.0f,m_flSqueegeeWidth,m_flVelMax);
  84. RectF rect2(0.0f,0.0f,(float)m_paSqueegee->GetWidth(),(float)m_paSqueegee->GetHeight()+m_flVelMax);
  85. Matrix mat;
  86. GraphicsPath Path;
  87. Graphics *gDirty;
  88. // Set up the brush transform (opposite from original transform)
  89. g_paBrCleanBkg->ResetTransform();
  90. mat.Reset();
  91. mat.Translate((float)m_paSqueegee->GetWidth()/2.0f-5.0f,-(float)m_paSqueegee->GetHeight()+30.0f);
  92. mat.Rotate(-m_flLastAngle-90.0f);
  93. mat.Translate(-m_vLastPos.X+m_rDesktop.left,-m_vLastPos.Y+m_rDesktop.top);
  94. g_paBrCleanBkg->SetTransform(&mat);
  95. // Set up original transform and erase from DirtyBkg a rectangle where the squeegee moved
  96. gDirty=new Graphics(g_paBmDirtyBkg);
  97. gDirty->TranslateTransform(m_vLastPos.X-m_rDesktop.left,m_vLastPos.Y-m_rDesktop.top);
  98. gDirty->RotateTransform(m_flLastAngle+90.0f);
  99. gDirty->TranslateTransform(-(float)m_paSqueegee->GetWidth()/2.0f+5.0f,(float)m_paSqueegee->GetHeight()-30.0f);
  100. gDirty->FillRectangle(g_paBrCleanBkg,rect);
  101. delete gDirty;
  102. // Get the bounds of the squeegee after rotations
  103. Path.AddRectangle(rect2);
  104. mat.Reset();
  105. mat.Translate(m_vLastPos.X-m_rDesktop.left,m_vLastPos.Y-m_rDesktop.top);
  106. mat.Rotate(m_flLastAngle+90.0f);
  107. mat.Translate(-m_flSqueegeeWidth/2.0f,0.0);
  108. Path.GetBounds(&rect,&mat,NULL);
  109. // Draw on a temp surface whatever was on the dirty background where the squeegee is to be drawn
  110. gBackground=new Graphics(m_paBackground);
  111. gBackground->DrawImage(g_paBmDirtyBkg,0,0,(int)rect.X,(int)rect.Y,(int)rect.Width,(int)rect.Height,UnitPixel);
  112. // Draw squeegee on temp surface
  113. gBackground->ResetTransform();
  114. gBackground->TranslateTransform(rect.Width/2.0f,rect.Height/2.0f);
  115. gBackground->RotateTransform(m_flLastAngle+90.0f);
  116. gBackground->TranslateTransform(-(float)m_paSqueegee->GetWidth()/2.0f,-(float)m_paSqueegee->GetHeight()/2.0f-m_flVelMax);
  117. gBackground->DrawImage(m_paSqueegee,0,0,0,0,m_paSqueegee->GetWidth(),m_paSqueegee->GetHeight(),UnitPixel);
  118. delete gBackground;
  119. // Draw temp surface to screen
  120. g->ResetTransform();
  121. g->DrawImage(m_paBackground,(int)rect.X,(int)rect.Y,0,0,(int)rect.Width,(int)rect.Height,UnitPixel);
  122. }