GradientCaptionBackground.cpp
上传用户:kssdz899
上传日期:2007-01-08
资源大小:79k
文件大小:3k
源码类别:

钩子与API截获

开发平台:

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