GradientCaptionBackground.cpp
上传用户:zhoushen
上传日期:2022-06-15
资源大小:84k
文件大小:3k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. /////////////////////////////////
  2. // Class for painting a windows caption background as
  3. // a shaded gradient.
  4. //
  5. // Used by custom caption class CCaption and its derived classes.
  6. //
  7. //
  8. // Author: Dave Lorde (dlorde@cix.compulink.co.uk)
  9. //
  10. //          Copyright January 2000
  11. //
  12. //          Portions of this file copyright Paul DiLascia
  13. //
  14. #include "stdafx.h"
  15. #include "GradientCaptionBackground.h"
  16. #include <algorithm>
  17. using std::_cpp_max;
  18. using std::_cpp_min;
  19. namespace 
  20. {
  21. const COLORREF ColorBlack = RGB(0, 0, 0);
  22. const int nColorShades = 64;      // this many shades in gradient
  23. }
  24. void CGradientCaptionBackground::Paint(CDC* pDC, CSize paintArea, BOOL active)
  25. {
  26. int cxCap = paintArea.cx;
  27. int cyCap = paintArea.cy;
  28. if (!active)
  29. {
  30. // Inactive caption: don't do shading, just fill w/bg color
  31. PaintRect(pDC, 0, 0, cxCap, cyCap, GetInactiveColor());
  32. else 
  33. {
  34. // Active caption: do shading
  35. //
  36. COLORREF clrBG = GetActiveColor(); // background color
  37. int r = GetRValue(clrBG); // red..
  38. int g = GetGValue(clrBG); // ..green
  39. int b = GetBValue(clrBG); // ..blue color vals
  40. int x = 5 * cxCap / 6; // start 5/6 of the way right
  41. int w = x; // width of area to shade
  42. int xDelta = _MAX(w / nColorShades, 1); // width of one shade band
  43. // Paint far right 1/6 of caption the background color
  44. PaintRect(pDC, x, 0, cxCap - x, cyCap, clrBG);
  45. // Compute new color brush for each band from x to x + xDelta.
  46. // Excel uses a linear algorithm from black to normal, i.e.
  47. //
  48. // color = CaptionColor * r
  49. //
  50. // where r is the ratio x/w, which ranges from 0 (x=0, left)
  51. // to 1 (x=w, right). This results in a mostly black title bar,
  52. // since we humans don't distinguish dark colors as well as light
  53. // ones. So instead, I use the formula
  54. //
  55. // color = CaptionColor * [1-(1-r)^2]
  56. //
  57. // which still equals black when r=0 and CaptionColor when r=1,
  58. // but spends more time near CaptionColor. For example, when r=0.5,
  59. // the multiplier is [1-(1-.5)^2] = 0.75, closer to 1 than 0.5.
  60. // I leave the algebra to the reader to verify that the above formula
  61. // is equivalent to
  62. //
  63. // color = CaptionColor - (CaptionColor*(w-x)*(w-x))/(w*w)
  64. //
  65. // The computation looks horrendous, but it's only done once each
  66. // time the caption changes size; thereafter BitBlt'ed to the screen.
  67. //
  68. while (x > xDelta)  // paint bands right to left
  69. {
  70. x -= xDelta; // next band
  71. int wmx2 = (w - x) *(w - x); // w minus x squared
  72. int w2 = w * w; // w squared
  73. PaintRect(pDC, x, 0, xDelta, cyCap,
  74. RGB(r -(r * wmx2) / w2, g -(g * wmx2) / w2, b -(b * wmx2) / w2));
  75. }
  76. PaintRect(pDC, 0, 0, x, cyCap, ColorBlack);  // whatever's left ==> black
  77. }
  78. }