QQ登录

只需一步,快速开始

上位机MFC各种定制形状按钮实例

[ 复制链接 ]
效果演示
例程通过自己编写按钮类实现不同形状按钮功能,效果如图:

上位机MFC各种定制形状按钮实例

上位机MFC各种定制形状按钮实例

工程实现目录内编译生成有可执行例程,可直接运行查看效果
下面代码可复制使用,也可直接下载工程源代码
请点击此处下载

请先注册会员后在进行下载

已注册会员,请先登录后下载

文件名称:CBtn.rar 
文件大小:118.11 KB  售价:10金币
下载权限: 不限 以上或 VIP会员   [购买捐助会员]   [充值积分]   有问题联系我



实现过程
1.新建一基于对应框的工程,如界面添加按钮控件并进行排版,按钮ID依次修改为m_cButton1。。。。m_cButton12。
2.将例程根据目录四个文件VTXBUTTON.CPP,VTXBUTTON.H,VTX.H,VTX.CPP复制到自己项目根目录,
并加载到项目中。这样项目的类管理窗口就会多出三个新的类CVertex,CVTXBUTTON,CVTXPOLYGON.

上位机MFC各种定制形状按钮实例

上位机MFC各种定制形状按钮实例

3.添加按钮对象,关联按钮控件,记得包含CVtxButton类的头文件#include "VtxButton.h"
        CVtxButton        m_cButton12;
        CVtxButton        m_cButton11;
        CVtxButton        m_cButton10;
        CVtxButton        m_cButton9;
        CVtxButton        m_cButton8;
        CVtxButton        m_cButton7;
        CVtxButton        m_cButton6;
        CVtxButton        m_cButton5;
        CVtxButton        m_cButton4;
        CVtxButton        m_cButton3;
        CVtxButton        m_cButton2;
        CVtxButton        m_cButton1;

       
       DDX_Control(pDX, IDC_BUTTON9, m_cButton9);
        DDX_Control(pDX, IDC_BUTTON8, m_cButton8);
        DDX_Control(pDX, IDC_BUTTON7, m_cButton7);
        DDX_Control(pDX, IDC_BUTTON6, m_cButton6);
        DDX_Control(pDX, IDC_BUTTON5, m_cButton5);
        DDX_Control(pDX, IDC_BUTTON12, m_cButton12);
        DDX_Control(pDX, IDC_BUTTON11, m_cButton11);
        DDX_Control(pDX, IDC_BUTTON10, m_cButton10);
        DDX_Control(pDX, IDC_BUTTON4, m_cButton4);
        DDX_Control(pDX, IDC_BUTTON3, m_cButton3);
        DDX_Control(pDX, IDC_BUTTON2, m_cButton2);
        DDX_Control(pDX, IDC_BUTTON1, m_cButton1);


4.在主对话框类的函数OnInitDialog里添加代码,初始化按钮控件类:
        CRect rect;
        m_cButton1.GetClientRect(&rect);            // Get the button's original dimensions
        CVtxPolygons vtxPolygons;
        int offset[4] = {0, 1, 2, 4};
        for (int i = 0; i < 4; i++)                 // Iterate through each of the polygons
        {
                // Add the corners
                vtxPolygons.Add(i, CVertex(rect.left + offset, rect.top + offset));
                vtxPolygons.Add(i, CVertex(rect.right - offset - 1, rect.top + offset));
                vtxPolygons.Add(i, CVertex(rect.right - offset - 1, rect.bottom - offset - 1));
                vtxPolygons.Add(i, CVertex(rect.left + offset, rect.bottom - offset - 1));
        }
        vtxPolygons.ClosePolygons();                // Close the polygons off
        m_cButton1.SetVtxPolygons(&vtxPolygons);    // Set the button's polygons

        m_cButton2.SetVtx(VTX_DIAMOND);
        m_cButton3.SetVtx(VTX_CIRCLE);
        m_cButton4.SetVtx(VTX_STRETCHEDCIRCLE);

        m_cButton5.SetVtx(VTX_RECT);
        m_cButton6.SetVtx(VTX_DIAMOND);
        m_cButton7.SetVtx(VTX_CIRCLE);
        m_cButton8.SetVtx(VTX_STRETCHEDCIRCLE);

        m_cButton9.SetVtx(VTX_RECT);
        m_cButton10.SetVtx(VTX_DIAMOND);
        m_cButton11.SetVtx(VTX_CIRCLE);
        m_cButton12.SetVtx(VTX_STRETCHEDCIRCLE);

5.这样各种形状按钮就可以编译支持起来查看效果了。
下面是四个文件的代码,可以复制使用
VTE.H
  1. #if _MSC_VER >= 1000
  2. #pragma once
  3. #endif // _MSC_VER >= 1000

  4. const VTX_RECT                                = 0;
  5. const VTX_DIAMOND                        = 1;
  6. const VTX_CIRCLE                        = 2;
  7. const VTX_STRETCHEDCIRCLE        = 3;

  8. class CVertex : public CObject
  9. {
  10. // Construction
  11. public:
  12.         CVertex();
  13.         CVertex(const CPoint& pt);
  14.         CVertex(const int& nX, const int& nY);
  15.         CVertex(const CVertex& vtx);

  16. // Attributes
  17. public:
  18.         int x; // Wouldn't it be counter-productive to call this m_nX?
  19.         int y;

  20. // Operations
  21. public:
  22.         operator CPoint()
  23.         {
  24.                 return CPoint(x, y);
  25.         }
  26.         operator!=(const CVertex& right)
  27.         {
  28.                 if (x == right.x && y == right.y)
  29.                         return FALSE;
  30.                 return TRUE;
  31.         }

  32. // Implementation
  33. public:
  34.         virtual ~CVertex();
  35. };

  36. ///////////////////////////////////////////////////////////////////////////////////////////
  37. // CVtxPolygons object
  38. //
  39. // A container class specifically designed for use in a CVtxButton. It contains an array of
  40. // four CObArray's. Each CObArray is a list of CVertex's which define a polygon.
  41. //

  42. class CVtxPolygons : public CObject
  43. {
  44. // Construction
  45. public:
  46.         CVtxPolygons();

  47. // Attributes
  48. private:
  49.         CObArray m_oaPolygons[4];

  50. // Operations
  51. public:
  52.         // Removes all the CVertex's from all the CObArray's:
  53.         void RemoveAll();

  54.         // Functions that are specific to the nPolygon CObArray:
  55.         int GetSize(const int& nPolygon);
  56.         CVertex *GetAt(const int& nPolygon, const int& nVertex);
  57.         void SetAt(const int& nPolygon, const int& nVertex, const CVertex& vtx);
  58.         void InsertAt(const int& nPolygon, const int& nVertex, const CVertex& vtx);
  59.         void Add(const int& nPolygon, const CVertex& vtx);
  60.         void RemoveAt(const int& nPolygon, const int& nVertex);

  61.         // Returns true if each CObArray contains at least one CVertex and
  62.         // contains the same number of CVertex's as each of the other CObArray's:
  63.         BOOL ValidPolygons();
  64.         // If the last CVertex in a CObArray is not the same as the first,
  65.         // this function will add a CVertex to the end that is the same:
  66.         void ClosePolygons();

  67.         // Create standard shape functions:
  68.         void Create(const CRect& rect, const int& nType = VTX_RECT);
  69.         void CreateRect(const CRect& rect);
  70.         void CreateDiamond(const CRect& rect);
  71.         void CreateCircle(const CRect& rect, const int& nSegments = 0);
  72.         void CreateStretchedCircle(const CRect& rect, const int& nSegments = 0);

  73.         // Create a CRgn from the nPolygon CObArray:
  74.         void CreatePolygonRgn(CRgn *rgn, const int& nPolygon);

  75.         void Copy(const CVtxPolygons& vtxBtnPolygons)
  76.         {
  77.                 RemoveAll();
  78.                 for (int i = 0; i < 4; i++)
  79.                         for (int j = 0; j < vtxBtnPolygons.m_oaPolygons[i].GetSize(); j++)
  80.                                 Add(i, *(CVertex*)vtxBtnPolygons.m_oaPolygons[i].GetAt(j));
  81.         }

  82. // Implementation
  83. public:
  84.         virtual ~CVtxPolygons();
  85. };

  86. ///////////////////////////////////////////////////////////////////////////////////////////
复制代码
VTX.CPP

  1. #include "stdafx.h"
  2. #include "Vtx.h"
  3. #include <math.h>

  4. // There is no excuse for inaccuracy in this area =)
  5. #define PI                        3.1415926535897932384626433832795028841971693993751058209
  6. // A very convenient way to properly convert double's to int's:
  7. #define round(x)        (int)(x + 0.5)

  8. ///////////////////////////////////////////////////////////////////////////////////////////
  9. // CVertex object

  10. CVertex::CVertex()
  11. {
  12.         x = 0;
  13.         y = 0;
  14. }

  15. CVertex::CVertex(const CPoint& pt)
  16. {
  17.         x = pt.x;
  18.         y = pt.y;
  19. }

  20. CVertex::CVertex(const int& nX, const int& nY)
  21. {
  22.         x = nX;
  23.         y = nY;
  24. }

  25. //
  26. CVertex::CVertex(const CVertex& vtx)
  27. {
  28.         x = vtx.x;
  29.         y = vtx.y;
  30. }

  31. CVertex::~CVertex()
  32. {
  33. }

  34. ///////////////////////////////////////////////////////////////////////////////////////////
  35. // CVtxPolygons object

  36. CVtxPolygons::CVtxPolygons()
  37. {
  38. }

  39. CVtxPolygons::~CVtxPolygons()
  40. {
  41.         RemoveAll();
  42. }

  43. void CVtxPolygons::RemoveAll()
  44. {
  45.         for (int i = 0; i < 4; i++)
  46.         {
  47.                 for (int j = 0; j < m_oaPolygons[i].GetSize(); j++)
  48.                 {
  49.                         if (m_oaPolygons[i].GetAt(j) != NULL)
  50.                                 delete m_oaPolygons[i].GetAt(j);
  51.                 }
  52.         }
  53. }

  54. int CVtxPolygons::GetSize(const int& nPolygon)
  55. {
  56.         return m_oaPolygons[nPolygon].GetSize();
  57. }

  58. CVertex *CVtxPolygons::GetAt(const int& nPolygon, const int& nVertex)
  59. {
  60.         return (CVertex*)m_oaPolygons[nPolygon].GetAt(nVertex);
  61. }

  62. void CVtxPolygons::SetAt(const int& nPolygon, const int& nVertex, const CVertex& vtx)
  63. {
  64.         m_oaPolygons[nPolygon].SetAt(nVertex, new CVertex(vtx));
  65. }
  66.        
  67. void CVtxPolygons::InsertAt(const int& nPolygon, const int& nVertex, const CVertex& vtx)
  68. {
  69.         m_oaPolygons[nPolygon].InsertAt(nVertex, new CVertex(vtx));
  70. }

  71. void CVtxPolygons::Add(const int& nPolygon, const CVertex& vtx)
  72. {
  73.         m_oaPolygons[nPolygon].Add(new CVertex(vtx));
  74. }

  75. void CVtxPolygons::RemoveAt(const int& nPolygon, const int& nVertex)
  76. {
  77.         m_oaPolygons[nPolygon].RemoveAt(nVertex);
  78. }

  79. BOOL CVtxPolygons::ValidPolygons()
  80. {
  81.         int nSize = GetSize(0);
  82.         if (nSize == 0)
  83.                 return FALSE;
  84.         if (nSize != GetSize(1))
  85.                 return FALSE;
  86.         if (nSize != GetSize(2))
  87.                 return FALSE;
  88.         if (nSize != GetSize(3))
  89.                 return FALSE;
  90.         return TRUE;
  91. }

  92. void CVtxPolygons::ClosePolygons()
  93. {
  94.         for (int i = 0; i < 4; i++)
  95.                 if (*GetAt(i, GetSize(i) - 1) != *GetAt(i, 0))
  96.                         Add(i, *GetAt(i, 0));
  97. }

  98. void CVtxPolygons::Create(const CRect& rect, const int& nType)
  99. {
  100.         switch (nType)
  101.         {
  102.                 case VTX_RECT:
  103.                         CreateRect(rect);
  104.                         break;
  105.                 case VTX_DIAMOND:
  106.                         CreateDiamond(rect);
  107.                         break;
  108.                 case VTX_CIRCLE:
  109.                         CreateCircle(rect);
  110.                         break;
  111.                 case VTX_STRETCHEDCIRCLE:
  112.                         CreateStretchedCircle(rect);
  113.                         break;
  114.         }
  115. }

  116. void CVtxPolygons::CreateRect(const CRect& rect)
  117. {
  118.         RemoveAll();

  119.         CRect offset[4] = {CRect(0, 0, 0, 0), CRect(1, 1, -1, -1),
  120.                 CRect(2, 2, -2, -2), CRect(4, 4, -4, -4)};

  121.         CRect realRect = *rect;
  122.         realRect.right--;
  123.         realRect.bottom--;

  124.         for (int i = 0; i < 4; i++)
  125.         {
  126.                 m_oaPolygons[i].Add(new CVertex(realRect.left + offset[i].left,
  127.                         realRect.top + offset[i].top));
  128.                 m_oaPolygons[i].Add(new CVertex(realRect.right + offset[i].right,
  129.                         realRect.top + offset[i].top));
  130.                 m_oaPolygons[i].Add(new CVertex(realRect.right + offset[i].right,
  131.                         realRect.bottom + offset[i].bottom));
  132.                 m_oaPolygons[i].Add(new CVertex(realRect.left + offset[i].left,
  133.                         realRect.bottom + offset[i].bottom));

  134.         }

  135.         ClosePolygons();
  136. }

  137. void CVtxPolygons::CreateDiamond(const CRect& rect)
  138. {
  139.         RemoveAll();

  140.         CRect offset[4] = {CRect(0, 0, 0, 0), CRect(1, 1, -1, -1),
  141.                 CRect(2, 2, -2, -2), CRect(4, 4, -4, -4)};

  142.         CRect realRect = *rect;
  143.         realRect.right--;
  144.         realRect.bottom--;

  145.         UINT side;
  146.         if (realRect.right > realRect.bottom)
  147.         {
  148.                 side = realRect.bottom;
  149.                 realRect.left = round((realRect.right - side) / 2);
  150.                 realRect.right = realRect.left + side;
  151.         }
  152.         else
  153.         {
  154.                 side = realRect.right;
  155.                 realRect.top = round((realRect.bottom - side) / 2);
  156.                 realRect.bottom = realRect.top + side;
  157.         }

  158.         for (UINT i = 0; i < 4; i++)
  159.         {
  160.                 m_oaPolygons[i].Add(new CVertex(realRect.left + offset[i].left,
  161.                         round(realRect.top + realRect.Height() / 2)));
  162.                 m_oaPolygons[i].Add(new CVertex(round(realRect.left + realRect.Width() / 2),
  163.                         realRect.top + offset[i].top));
  164.                 m_oaPolygons[i].Add(new CVertex(realRect.right + offset[i].right,
  165.                         round(realRect.top + realRect.Height() / 2)));
  166.                 m_oaPolygons[i].Add(new CVertex(round(realRect.left + realRect.Width() / 2),
  167.                         realRect.bottom + offset[i].bottom));
  168.         }

  169.         ClosePolygons();
  170. }

  171. void CVtxPolygons::CreateCircle(const CRect& rect, const int& nSegments)
  172. {
  173.         RemoveAll();

  174.         CRect realRect = *rect;
  175.         realRect.right--;
  176.         realRect.bottom--;

  177.         double dCenterX = realRect.left + realRect.Width() / 2;
  178.         double dCenterY = realRect.top + realRect.Height() / 2;

  179.         UINT nSide;
  180.         double dRadius;
  181.         if (realRect.right > realRect.bottom)
  182.         {
  183.                 nSide = realRect.bottom;
  184.                 realRect.left = round((realRect.right - nSide) / 2);
  185.                 realRect.right = realRect.left + nSide;
  186.                 dRadius = dCenterY;
  187.         }
  188.         else
  189.         {
  190.                 nSide = realRect.right;
  191.                 realRect.top = round((realRect.bottom - nSide) / 2);
  192.                 realRect.bottom = realRect.top + nSide;
  193.                 dRadius = dCenterX;
  194.         }

  195.         double dLayers[4] = {dRadius, dRadius - 1, dRadius - 2, dRadius - 4};
  196.         int segments = (nSegments < 2 ? round(dRadius) : nSegments);

  197.         double dAngle;
  198.         for (int i = 0; i < 4; i++)
  199.         {
  200.                 m_oaPolygons[i].RemoveAll();
  201.                 for (int j = 0; j < segments; j++)
  202.                 {
  203.                         dAngle = 2.0 * PI * j / segments;
  204.                         m_oaPolygons[i].Add(new CVertex(round(dCenterX + cos(dAngle) * dLayers[i]),
  205.                                 round(dCenterY + sin(dAngle) * dLayers[i])));
  206.                 }
  207.         }

  208.         ClosePolygons();
  209. }

  210. void CVtxPolygons::CreateStretchedCircle(const CRect& rect, const int& nSegments)
  211. {
  212.         RemoveAll();

  213.         CRect realRect = *rect;
  214.         realRect.right--;
  215.         realRect.bottom--;

  216.         double dRadius;
  217.         double dRightX, dRightY;
  218.         double dStartAngle;
  219.         BOOL bHorizontal = realRect.right > realRect.bottom;
  220.         if (bHorizontal)
  221.         {
  222.                 dRadius = realRect.top + realRect.Height() / 2;
  223.                 dRightX = realRect.right - dRadius;
  224.                 dRightY = dRadius;
  225.                 dStartAngle = 3 * PI / 2;
  226.         }
  227.         else
  228.         {
  229.                 dRadius = realRect.left + realRect.Width() / 2;
  230.                 dRightX = dRadius;
  231.                 dRightY = realRect.bottom - dRadius;
  232.                 dStartAngle = 0;
  233.         }

  234.         double dLeftX = dRadius;
  235.         double dLeftY = dRadius;
  236.        
  237.         double dRadiusLayers[4] = {dRadius, dRadius - 1, dRadius - 2, dRadius - 4};
  238.         int segments = (nSegments < 1 ? round(dRadius) : nSegments);

  239.         double dAngle;
  240.         for (int i = 0; i < 4; i++)
  241.         {
  242.                 m_oaPolygons[i].RemoveAll();
  243.                 for (int j = 0; j < round(segments / 2 + 1); j++)
  244.                 {
  245.                         dAngle = dStartAngle + 2 * PI * j / segments;
  246.                         m_oaPolygons[i].Add(new CVertex(round(dRightX + cos(dAngle) *
  247.                                 dRadiusLayers[i]), round(dRightY + sin(dAngle) * dRadiusLayers[i])));
  248.                 }

  249.                 for (j = round(segments / 2); j < segments + 1; j++)
  250.                 {
  251.                         dAngle = dStartAngle + 2 * PI * j / segments;
  252.                         m_oaPolygons[i].Add(new CVertex(round(dLeftX + cos(dAngle) *
  253.                                 dRadiusLayers[i]), round(dLeftY + sin(dAngle)  *dRadiusLayers[i])));
  254.                 }
  255.         }

  256.         ClosePolygons();
  257. }

  258. void CVtxPolygons::CreatePolygonRgn(CRgn *rgn, const int& nPolygon)
  259. {
  260.         ASSERT(ValidPolygons());

  261.         ClosePolygons();
  262.        
  263.         CPoint pts[1024];
  264.         for (int i = 0; i < m_oaPolygons[nPolygon].GetSize(); i++)
  265.                 pts[i] = (CPoint)(*(CVertex*)m_oaPolygons[nPolygon].GetAt(i));

  266.         rgn->CreatePolygonRgn(pts, m_oaPolygons[nPolygon].GetSize(), ALTERNATE);       
  267. }

  268. ///////////////////////////////////////////////////////////////////////////////////////////
复制代码


VTXBUTTON.H

  1. #if _MSC_VER >= 1000
  2. #pragma once
  3. #endif // _MSC_VER >= 1000

  4. #include "Vtx.h"

  5. ///////////////////////////////////////////////////////////////////////////////////////////
  6. // CVtxButton button
  7. //
  8. // A class derived from CButton that is drawn in the shape specified by
  9. // CVtxPolygons.
  10. //

  11. class CVtxButton : public CButton
  12. {
  13. // Construction
  14. public:
  15.         CVtxButton();

  16. // Attributes
  17. private:
  18.         CVtxPolygons        m_vtxBtnPolygons;
  19.         CDC                                *m_pBitmapDC;
  20.         CBitmap                        *m_pBtn,
  21.                                         *m_pBtnFocus,
  22.                                         *m_pBtnSelected;
  23.         DWORD                        m_dwStyle;
  24.         BOOL                        m_bNeedToRegenerateBitmaps;

  25. // Operations
  26. public:
  27.         // Select a custom CVtxPolygons shape:
  28.         void SetVtxPolygons(CVtxPolygons *vtxBtnPolygons);
  29.         // Select a standard CVtxPolygons shape:
  30.         void SetVtx(const int& nType);

  31. private:
  32.         void GenerateBitmaps(LPDRAWITEMSTRUCT lpDrawItemStruct);

  33. // Overrides
  34. public:
  35.         virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
  36. protected:
  37.         virtual void PreSubclassWindow();

  38. // Implementation
  39. public:
  40.         virtual ~CVtxButton();
  41. };

  42. ///////////////////////////////////////////////////////////////////////////////////////////
复制代码


VTXBUTTON.CPP
  1. #include "stdafx.h"
  2. #include "Vtx.h"
  3. #include "VtxButton.h"
  4. #include <math.h>

  5. // Windows system colors:
  6. #define RGB_BUTTON_BLACK        (GetSysColor(COLOR_3DDKSHADOW))
  7. #define RGB_BUTTON_WHITE        (GetSysColor(COLOR_3DHILIGHT))
  8. #define RGB_BUTTON_GRAY                (GetSysColor(COLOR_3DFACE))
  9. #define RGB_BUTTON_LIGHT        (GetSysColor(COLOR_3DLIGHT))
  10. #define RGB_BUTTON_DARK                (GetSysColor(COLOR_3DSHADOW))

  11. // The angle (in radians) from which the light is from:
  12. #define LIGHT_SOURCE_ANGLE        3 * PI / 4

  13. // There is no excuse for inaccuracy in this area =)
  14. #define PI                        3.1415926535897932384626433832795028841971693993751058209
  15. // A very convenient way to properly convert double's to int's:
  16. #define round(x)        (int)(x + 0.5)

  17. ///////////////////////////////////////////////////////////////////////////////////////////
  18. // Misc functions

  19. // Compute the angle of a line segment given it's rise and run:
  20. double GetAngle(const double& dRise, const double& dRun)
  21. {
  22.         double dAngle = atan2(dRise, dRun);
  23.        
  24.         if (dAngle < 0.0)
  25.                 dAngle = 2 * PI + dAngle;

  26.         return dAngle;
  27. }

  28. // Compute an intermediate color:
  29. COLORREF InterpolateColors(const COLORREF& crA, const COLORREF& crB, const double& dWeight)
  30. {
  31.         BYTE Red   = (BYTE)(dWeight * GetRValue(crA) + (1.0 - dWeight) * GetRValue(crB));
  32.         BYTE Green = (BYTE)(dWeight * GetGValue(crA) + (1.0 - dWeight) * GetGValue(crB));
  33.         BYTE Blue  = (BYTE)(dWeight * GetBValue(crA) + (1.0 - dWeight) * GetBValue(crB));

  34.         return RGB(Red, Green, Blue);
  35. }

  36. // Compute the color of a line segment defined by ptA and ptB:
  37. COLORREF GetColor(const CPoint& ptA, const CPoint& ptZ, const COLORREF& crDark,
  38.                                   const COLORREF& crBright)
  39. {

  40.         double dRise = (double)(ptZ.y - ptA.y);
  41.         double dRun = (double)(ptA.x - ptZ.x);
  42.         double dAngle = 2 * PI - GetAngle(dRun, dRise);

  43.         double dAngleDifference = fabs(LIGHT_SOURCE_ANGLE - dAngle);

  44.         // I blatantly took this code fragment, "0.5 * (cos(dAngleDifference) + 1.0)," from  
  45.         // Chris Maunder because it works. I am at a loss as to why.
  46.         return InterpolateColors(crBright, crDark, 0.5 * (cos(dAngleDifference) + 1.0));
  47. }

  48. ///////////////////////////////////////////////////////////////////////////////////////////
  49. // CVtxButton button

  50. CVtxButton::CVtxButton()
  51. {
  52.         m_pBtn = new CBitmap;
  53.         m_pBtnFocus = new CBitmap;
  54.         m_pBtnSelected = new CBitmap;
  55.         m_pBitmapDC = new CDC;

  56.         m_bNeedToRegenerateBitmaps = TRUE;
  57. }

  58. CVtxButton::~CVtxButton()
  59. {
  60.         delete m_pBitmapDC;
  61.         delete m_pBtn;
  62.         delete m_pBtnFocus;
  63.         delete m_pBtnSelected;
  64. }

  65. /////////////////////////////////////////////////////////////////////////////
  66. // CVtxButton message handlers

  67. void CVtxButton::PreSubclassWindow()
  68. {
  69.         CButton::PreSubclassWindow();

  70.         ModifyStyle(0, BS_OWNERDRAW);
  71. }

  72. // Paint the button with the correct bitmap:
  73. void CVtxButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  74. {
  75.         ASSERT(lpDrawItemStruct != NULL);
  76.         CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  77.         CRect rect = lpDrawItemStruct->rcItem;
  78.         UINT state = lpDrawItemStruct->itemState;

  79.         if (!m_vtxBtnPolygons.ValidPolygons())
  80.                 SetVtx(VTX_RECT);
  81.         if (m_bNeedToRegenerateBitmaps || m_dwStyle != GetStyle())
  82.                 GenerateBitmaps(lpDrawItemStruct);

  83.         if (state & ODS_SELECTED)
  84.                 m_pBitmapDC->SelectObject(m_pBtnSelected);
  85.         else
  86.         {
  87.                 if (state & ODS_FOCUS)
  88.                         m_pBitmapDC->SelectObject(m_pBtnFocus);
  89.                 else
  90.                         m_pBitmapDC->SelectObject(m_pBtn);
  91.         }

  92.         pDC->BitBlt(0, 0, rect.Width(), rect.Height(), m_pBitmapDC, 0, 0, SRCCOPY);
  93. }

  94. ///////////////////////////////////////////////////////////////////////////////////////////
  95. // CVtxButton operations

  96. void CVtxButton::SetVtxPolygons(CVtxPolygons *vtxBtnPolygons)
  97. {
  98.         m_vtxBtnPolygons.Copy(*vtxBtnPolygons);

  99.         CRgn rgn;
  100.         m_vtxBtnPolygons.CreatePolygonRgn(&rgn, 0);
  101.        
  102.         HRGN hRgn;
  103.         hRgn = (HRGN)rgn.Detach();
  104.         SetWindowRgn(hRgn, TRUE);

  105.         m_bNeedToRegenerateBitmaps = TRUE;
  106. }

  107. void CVtxButton::SetVtx(const int& nType)
  108. {
  109.         CRect rect;
  110.         GetClientRect(rect);

  111.         m_vtxBtnPolygons.Create(&rect, nType);
  112.         CRgn rgn;
  113.         m_vtxBtnPolygons.CreatePolygonRgn(&rgn, 0);

  114.         HRGN hRgn;
  115.         hRgn = (HRGN)rgn.Detach();
  116.         SetWindowRgn(hRgn, TRUE);

  117.         m_bNeedToRegenerateBitmaps = TRUE;
  118. }

  119. ///////////////////////////////////////////////////////////////////////////////////////////
  120. // CVtxButton state bitmap generation:

  121. void CVtxButton::GenerateBitmaps(LPDRAWITEMSTRUCT lpDrawItemStruct)
  122. {
  123.         ASSERT(lpDrawItemStruct != NULL);
  124.         CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  125.         CRect rect = lpDrawItemStruct->rcItem;
  126.         UINT state = lpDrawItemStruct->itemState;

  127.         m_dwStyle = GetStyle();

  128.         CRgn rgn;
  129.         m_vtxBtnPolygons.CreatePolygonRgn(&rgn, 3);

  130.         delete m_pBitmapDC;       
  131.         m_pBitmapDC = new CDC;
  132.         m_pBitmapDC->CreateCompatibleDC(pDC);
  133.         CFont *oldFont = m_pBitmapDC->SelectObject(pDC->GetCurrentFont());

  134.         CString        strText;
  135.         GetWindowText(strText);
  136.         CSize        extent = m_pBitmapDC->GetTextExtent(strText);
  137.         CPoint        ptCenter = rect.CenterPoint();
  138.         CPoint        pt = CPoint(ptCenter.x - extent.cx / 2 - 1, ptCenter.y - extent.cy / 2 - 1);
  139.         CRect        textRect(pt.x, pt.y, pt.x + extent.cx, pt.y + extent.cy);

  140.         delete m_pBtn;
  141.         m_pBtn = new CBitmap;
  142.         m_pBtn->CreateCompatibleBitmap(pDC, rect.right, rect.bottom);
  143.         m_pBitmapDC->SelectObject(m_pBtn);
  144.         m_pBitmapDC->SelectStockObject(NULL_BRUSH);
  145.         m_pBitmapDC->FillSolidRect(rect, RGB_BUTTON_GRAY);

  146.         // Generate m_pBtn bitmap: unfocused button
  147.         if (m_dwStyle & BS_FLAT)
  148.         {
  149.                 COLORREF crBlend = InterpolateColors(RGB_BUTTON_WHITE, RGB_BUTTON_BLACK, 0.5);

  150.                 CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
  151.                 CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(crBlend));
  152.                 CPoint pts[4];
  153.                
  154.                 for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  155.                 {
  156.                         pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
  157.                         pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));

  158.                         delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
  159.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
  160.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
  161.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
  162.                         m_pBitmapDC->Polygon(pts, 4);
  163.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_WHITE));
  164.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(1, i + 1));
  165.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(1, i));
  166.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(1, i), RGB_BUTTON_WHITE);

  167.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
  168.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
  169.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
  170.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
  171.                 }

  172.                 delete m_pBitmapDC->SelectObject(oldpen);
  173.                 delete m_pBitmapDC->SelectObject(oldBrush);
  174.         }
  175.         else
  176.         {
  177.                 CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
  178.                 CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_GRAY));
  179.                 CPoint pts[4];

  180.                 COLORREF crLighter = RGB_BUTTON_LIGHT;
  181.                 COLORREF crDarker = RGB_BUTTON_DARK;
  182.                 COLORREF crBlend = RGB_BUTTON_GRAY;
  183.                
  184.                 for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  185.                 {
  186.                         pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
  187.                         pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));

  188.                         crLighter = GetColor(*m_vtxBtnPolygons.GetAt(1, i),
  189.                                 *m_vtxBtnPolygons.GetAt(1, i + 1), RGB_BUTTON_DARK,
  190.                                 RGB_BUTTON_LIGHT);
  191.                         crDarker = GetColor(*m_vtxBtnPolygons.GetAt(0, i),
  192.                                 *m_vtxBtnPolygons.GetAt(0, i + 1), RGB_BUTTON_BLACK,
  193.                                 RGB_BUTTON_WHITE);
  194.                         crBlend = InterpolateColors(crLighter, crDarker, 0.5);

  195.                         delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
  196.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
  197.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
  198.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
  199.                         m_pBitmapDC->Polygon(pts, 4);
  200.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crLighter));
  201.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(1, i + 1));
  202.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(1, i));
  203.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(1, i), crLighter);

  204.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crDarker));
  205.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
  206.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
  207.                         m_pBitmapDC->Polygon(pts, 4);
  208.                 }

  209.                 delete m_pBitmapDC->SelectObject(oldpen);
  210.                 delete m_pBitmapDC->SelectObject(oldBrush);
  211.         }
  212.         if (!strText.IsEmpty())
  213.         {               
  214.                 m_pBitmapDC->SelectClipRgn(&rgn);

  215.                 m_pBitmapDC->SetBkMode(TRANSPARENT);
  216.                 if (state & ODS_DISABLED)
  217.                         m_pBitmapDC->DrawState(pt, extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
  218.                 else
  219.                 {
  220.                         m_pBitmapDC->DrawText(strText, -1, textRect, DT_SINGLELINE | DT_CENTER |
  221.                                 DT_VCENTER);
  222.                 }

  223.                 m_pBitmapDC->SelectClipRgn(NULL);
  224.         }

  225.         delete m_pBtnFocus;
  226.         m_pBtnFocus = new CBitmap;
  227.         m_pBtnFocus->CreateCompatibleBitmap(pDC, rect.right, rect.bottom);
  228.         m_pBitmapDC->SelectObject(m_pBtnFocus);
  229.         m_pBitmapDC->SelectStockObject(NULL_BRUSH);
  230.         m_pBitmapDC->FillSolidRect(rect, RGB_BUTTON_GRAY);

  231.         // Generate m_pBtnFocus bitmap: focused button
  232.         if (m_dwStyle & BS_FLAT)
  233.         {
  234.                 CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
  235.                 CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_GRAY));
  236.                 CPoint pts[4];

  237.                 COLORREF crBlend = InterpolateColors(RGB_BUTTON_WHITE, RGB_BUTTON_BLACK, 0.5);
  238.                
  239.                 for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  240.                 {
  241.                         pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
  242.                         pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));

  243.                         delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
  244.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
  245.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(2, i));
  246.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(2, i + 1));
  247.                         m_pBitmapDC->Polygon(pts, 4);
  248.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_WHITE));
  249.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(2, i + 1));
  250.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(2, i));
  251.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(2, i), RGB_BUTTON_WHITE);

  252.                         delete m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_BLACK));
  253.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
  254.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
  255.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
  256.                         m_pBitmapDC->Polygon(pts, 4);
  257.                 }
  258.                
  259.                 delete m_pBitmapDC->SelectObject(oldBrush);
  260.                 delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));

  261.                 for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  262.                 {
  263.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
  264.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
  265.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
  266.                 }

  267.                 COLORREF crColor = InterpolateColors(RGB_BUTTON_GRAY, RGB_BUTTON_DARK, 0.5);
  268.                 delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crColor));

  269.                 for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  270.                 {
  271.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(3, i + 1));
  272.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(3, i));
  273.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(3, i), crColor);
  274.                 }

  275.                 delete m_pBitmapDC->SelectObject(oldpen);       
  276.         }
  277.         else
  278.         {
  279.                 CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
  280.                 CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_GRAY));
  281.                 CPoint pts[4];

  282.                 COLORREF crLighter = RGB_BUTTON_LIGHT;
  283.                 COLORREF crDarker = RGB_BUTTON_DARK;
  284.                 COLORREF crBlend = RGB_BUTTON_GRAY;
  285.                
  286.                 for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  287.                 {
  288.                         pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
  289.                         pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));

  290.                         crLighter = GetColor(*m_vtxBtnPolygons.GetAt(2, i),
  291.                                 *m_vtxBtnPolygons.GetAt(2, i + 1), RGB_BUTTON_DARK,
  292.                                 RGB_BUTTON_LIGHT);
  293.                         crDarker = GetColor(*m_vtxBtnPolygons.GetAt(1, i),
  294.                                 *m_vtxBtnPolygons.GetAt(1, i + 1), RGB_BUTTON_BLACK,
  295.                                 RGB_BUTTON_WHITE);
  296.                         crBlend = InterpolateColors(crLighter, crDarker, 0.5);

  297.                         delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
  298.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));       
  299.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(2, i));
  300.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(2, i + 1));
  301.                         m_pBitmapDC->Polygon(pts, 4);
  302.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crLighter));
  303.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(2, i + 1));
  304.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(2, i));
  305.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(2, i), crLighter);

  306.                         delete m_pBitmapDC->SelectObject(new CBrush(crDarker));
  307.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crDarker));
  308.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
  309.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
  310.                         m_pBitmapDC->Polygon(pts, 4);
  311.                 }
  312.                
  313.                 delete m_pBitmapDC->SelectObject(oldBrush);
  314.                 delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));

  315.                 for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  316.                 {
  317.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
  318.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
  319.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
  320.                 }

  321.                 COLORREF crColor = InterpolateColors(RGB_BUTTON_GRAY, RGB_BUTTON_DARK, 0.5);
  322.                 delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crColor));

  323.                 for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  324.                 {
  325.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(3, i + 1));
  326.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(3, i));
  327.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(3, i), crColor);
  328.                 }

  329.                 delete m_pBitmapDC->SelectObject(oldpen);       
  330.         }
  331.         if (!strText.IsEmpty())
  332.         {               
  333.                 m_pBitmapDC->SelectClipRgn(&rgn);

  334.                 m_pBitmapDC->SetBkMode(TRANSPARENT);
  335.                 if (state & ODS_DISABLED)
  336.                         m_pBitmapDC->DrawState(pt, extent, strText, DSS_DISABLED, TRUE, 0,
  337.                         (HBRUSH)NULL);
  338.                 else
  339.                 {
  340.                         m_pBitmapDC->DrawText(strText, -1, textRect, DT_SINGLELINE | DT_CENTER |
  341.                                 DT_VCENTER);
  342.                 }

  343.                 m_pBitmapDC->SelectClipRgn(NULL);
  344.         }

  345.         delete m_pBtnSelected;
  346.         m_pBtnSelected = new CBitmap;
  347.         m_pBtnSelected->CreateCompatibleBitmap(pDC, rect.right, rect.bottom);
  348.         m_pBitmapDC->SelectObject(m_pBtnSelected);
  349.         m_pBitmapDC->SelectStockObject(NULL_BRUSH);
  350.         m_pBitmapDC->FillSolidRect(rect, RGB_BUTTON_GRAY);

  351.         // Generate m_pBtnSelected bitmap: selected button
  352.         if (m_dwStyle & BS_FLAT)
  353.         {
  354.                 COLORREF crBlend = InterpolateColors(RGB_BUTTON_DARK, RGB_BUTTON_BLACK, 0.5);

  355.                 CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
  356.                 CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_GRAY));
  357.                 CPoint pts[4];
  358.                
  359.                 for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  360.                 {
  361.                         pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
  362.                         pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));

  363.                         delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
  364.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
  365.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(2, i));
  366.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(2, i + 1));
  367.                         m_pBitmapDC->Polygon(pts, 4);
  368.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_WHITE));
  369.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(2, i + 1));
  370.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(2, i));
  371.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(2, i), RGB_BUTTON_WHITE);

  372.                         delete m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_BLACK));
  373.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
  374.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
  375.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
  376.                         m_pBitmapDC->Polygon(pts, 4);
  377.                 }
  378.                
  379.                 delete m_pBitmapDC->SelectObject(oldBrush);
  380.                 delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));

  381.                 for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  382.                 {
  383.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
  384.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
  385.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
  386.                 }

  387.                 COLORREF crColor = InterpolateColors(RGB_BUTTON_GRAY, RGB_BUTTON_DARK, 0.5);
  388.                 delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crColor));

  389.                 for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  390.                 {
  391.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(3, i + 1));
  392.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(3, i));
  393.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(3, i), crColor);
  394.                 }

  395.                 delete m_pBitmapDC->SelectObject(oldpen);
  396.         }
  397.         else
  398.         {
  399.                 COLORREF crBlend = InterpolateColors(RGB_BUTTON_DARK, RGB_BUTTON_BLACK, 0.5);

  400.                 CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_DARK));
  401.                 CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(crBlend));
  402.                 CPoint pts[4];

  403.                 for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  404.                 {
  405.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
  406.                         pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
  407.                         pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
  408.                         pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
  409.                         pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
  410.                         m_pBitmapDC->Polygon(pts, 4);
  411.                         delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_DARK));
  412.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(1, i + 1));
  413.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(1, i));
  414.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(1, i), RGB_BUTTON_DARK);
  415.                 }

  416.                 delete m_pBitmapDC->SelectObject(oldBrush);
  417.                 delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));

  418.                 for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  419.                 {
  420.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
  421.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
  422.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
  423.                 }

  424.                 COLORREF crColor = InterpolateColors(RGB_BUTTON_GRAY, RGB_BUTTON_DARK, 0.5);
  425.                 delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crColor));

  426.                 for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
  427.                 {
  428.                         m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(3, i + 1));
  429.                         m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(3, i));
  430.                         m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(3, i), crColor);
  431.                 }

  432.                 delete m_pBitmapDC->SelectObject(oldpen);
  433.         }
  434.         if (!strText.IsEmpty())
  435.         {               
  436.                 m_pBitmapDC->SelectClipRgn(&rgn);

  437.                 pt.Offset(1, 1);
  438.                 textRect.OffsetRect(1, 1);

  439.                 m_pBitmapDC->SetBkMode(TRANSPARENT);
  440.                 if (state & ODS_DISABLED)
  441.                         m_pBitmapDC->DrawState(pt, extent, strText, DSS_DISABLED, TRUE, 0,
  442.                         (HBRUSH)NULL);
  443.                 else
  444.                 {
  445.                         m_pBitmapDC->DrawText(strText, -1, textRect, DT_SINGLELINE | DT_CENTER |
  446.                                 DT_VCENTER);
  447.                 }

  448.                 m_pBitmapDC->SelectClipRgn(NULL);
  449.         }

  450.         m_pBitmapDC->SelectObject(oldFont);

  451.         m_bNeedToRegenerateBitmaps = FALSE;
  452. }

  453. ///////////////////////////////////////////////////////////////////////////////////////////
复制代码
  

如果您认可,可联系功能定制!

  

如果您着急,充值会员可直接联系发您资料!

  

QQ联系我

微信扫扫联系我

  

回复

使用道具 举报

快速回复 返回列表 客服中心 搜索