效果演示
例程通过自己编写按钮类实现不同形状按钮功能,效果如图:
上位机MFC各种定制形状按钮实例
工程实现目录内编译生成有可执行例程,可直接运行查看效果
下面代码可复制使用,也可直接下载工程源代码
实现过程
1.新建一基于对应框的工程,如界面添加按钮控件并进行排版,按钮ID依次修改为m_cButton1。。。。m_cButton12。
2.将例程根据目录四个文件VTXBUTTON.CPP,VTXBUTTON.H,VTX.H,VTX.CPP复制到自己项目根目录,
并加载到项目中。这样项目的类管理窗口就会多出三个新的类CVertex,CVTXBUTTON,CVTXPOLYGON.
上位机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
- #if _MSC_VER >= 1000
- #pragma once
- #endif // _MSC_VER >= 1000
- const VTX_RECT = 0;
- const VTX_DIAMOND = 1;
- const VTX_CIRCLE = 2;
- const VTX_STRETCHEDCIRCLE = 3;
- class CVertex : public CObject
- {
- // Construction
- public:
- CVertex();
- CVertex(const CPoint& pt);
- CVertex(const int& nX, const int& nY);
- CVertex(const CVertex& vtx);
- // Attributes
- public:
- int x; // Wouldn't it be counter-productive to call this m_nX?
- int y;
- // Operations
- public:
- operator CPoint()
- {
- return CPoint(x, y);
- }
- operator!=(const CVertex& right)
- {
- if (x == right.x && y == right.y)
- return FALSE;
- return TRUE;
- }
- // Implementation
- public:
- virtual ~CVertex();
- };
- ///////////////////////////////////////////////////////////////////////////////////////////
- // CVtxPolygons object
- //
- // A container class specifically designed for use in a CVtxButton. It contains an array of
- // four CObArray's. Each CObArray is a list of CVertex's which define a polygon.
- //
- class CVtxPolygons : public CObject
- {
- // Construction
- public:
- CVtxPolygons();
- // Attributes
- private:
- CObArray m_oaPolygons[4];
- // Operations
- public:
- // Removes all the CVertex's from all the CObArray's:
- void RemoveAll();
- // Functions that are specific to the nPolygon CObArray:
- int GetSize(const int& nPolygon);
- CVertex *GetAt(const int& nPolygon, const int& nVertex);
- void SetAt(const int& nPolygon, const int& nVertex, const CVertex& vtx);
- void InsertAt(const int& nPolygon, const int& nVertex, const CVertex& vtx);
- void Add(const int& nPolygon, const CVertex& vtx);
- void RemoveAt(const int& nPolygon, const int& nVertex);
- // Returns true if each CObArray contains at least one CVertex and
- // contains the same number of CVertex's as each of the other CObArray's:
- BOOL ValidPolygons();
- // If the last CVertex in a CObArray is not the same as the first,
- // this function will add a CVertex to the end that is the same:
- void ClosePolygons();
- // Create standard shape functions:
- void Create(const CRect& rect, const int& nType = VTX_RECT);
- void CreateRect(const CRect& rect);
- void CreateDiamond(const CRect& rect);
- void CreateCircle(const CRect& rect, const int& nSegments = 0);
- void CreateStretchedCircle(const CRect& rect, const int& nSegments = 0);
- // Create a CRgn from the nPolygon CObArray:
- void CreatePolygonRgn(CRgn *rgn, const int& nPolygon);
- void Copy(const CVtxPolygons& vtxBtnPolygons)
- {
- RemoveAll();
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < vtxBtnPolygons.m_oaPolygons[i].GetSize(); j++)
- Add(i, *(CVertex*)vtxBtnPolygons.m_oaPolygons[i].GetAt(j));
- }
- // Implementation
- public:
- virtual ~CVtxPolygons();
- };
- ///////////////////////////////////////////////////////////////////////////////////////////
复制代码 VTX.CPP
- #include "stdafx.h"
- #include "Vtx.h"
- #include <math.h>
- // There is no excuse for inaccuracy in this area =)
- #define PI 3.1415926535897932384626433832795028841971693993751058209
- // A very convenient way to properly convert double's to int's:
- #define round(x) (int)(x + 0.5)
- ///////////////////////////////////////////////////////////////////////////////////////////
- // CVertex object
- CVertex::CVertex()
- {
- x = 0;
- y = 0;
- }
- CVertex::CVertex(const CPoint& pt)
- {
- x = pt.x;
- y = pt.y;
- }
- CVertex::CVertex(const int& nX, const int& nY)
- {
- x = nX;
- y = nY;
- }
- //
- CVertex::CVertex(const CVertex& vtx)
- {
- x = vtx.x;
- y = vtx.y;
- }
- CVertex::~CVertex()
- {
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
- // CVtxPolygons object
- CVtxPolygons::CVtxPolygons()
- {
- }
- CVtxPolygons::~CVtxPolygons()
- {
- RemoveAll();
- }
- void CVtxPolygons::RemoveAll()
- {
- for (int i = 0; i < 4; i++)
- {
- for (int j = 0; j < m_oaPolygons[i].GetSize(); j++)
- {
- if (m_oaPolygons[i].GetAt(j) != NULL)
- delete m_oaPolygons[i].GetAt(j);
- }
- }
- }
- int CVtxPolygons::GetSize(const int& nPolygon)
- {
- return m_oaPolygons[nPolygon].GetSize();
- }
- CVertex *CVtxPolygons::GetAt(const int& nPolygon, const int& nVertex)
- {
- return (CVertex*)m_oaPolygons[nPolygon].GetAt(nVertex);
- }
- void CVtxPolygons::SetAt(const int& nPolygon, const int& nVertex, const CVertex& vtx)
- {
- m_oaPolygons[nPolygon].SetAt(nVertex, new CVertex(vtx));
- }
-
- void CVtxPolygons::InsertAt(const int& nPolygon, const int& nVertex, const CVertex& vtx)
- {
- m_oaPolygons[nPolygon].InsertAt(nVertex, new CVertex(vtx));
- }
- void CVtxPolygons::Add(const int& nPolygon, const CVertex& vtx)
- {
- m_oaPolygons[nPolygon].Add(new CVertex(vtx));
- }
- void CVtxPolygons::RemoveAt(const int& nPolygon, const int& nVertex)
- {
- m_oaPolygons[nPolygon].RemoveAt(nVertex);
- }
- BOOL CVtxPolygons::ValidPolygons()
- {
- int nSize = GetSize(0);
- if (nSize == 0)
- return FALSE;
- if (nSize != GetSize(1))
- return FALSE;
- if (nSize != GetSize(2))
- return FALSE;
- if (nSize != GetSize(3))
- return FALSE;
- return TRUE;
- }
- void CVtxPolygons::ClosePolygons()
- {
- for (int i = 0; i < 4; i++)
- if (*GetAt(i, GetSize(i) - 1) != *GetAt(i, 0))
- Add(i, *GetAt(i, 0));
- }
- void CVtxPolygons::Create(const CRect& rect, const int& nType)
- {
- switch (nType)
- {
- case VTX_RECT:
- CreateRect(rect);
- break;
- case VTX_DIAMOND:
- CreateDiamond(rect);
- break;
- case VTX_CIRCLE:
- CreateCircle(rect);
- break;
- case VTX_STRETCHEDCIRCLE:
- CreateStretchedCircle(rect);
- break;
- }
- }
- void CVtxPolygons::CreateRect(const CRect& rect)
- {
- RemoveAll();
- CRect offset[4] = {CRect(0, 0, 0, 0), CRect(1, 1, -1, -1),
- CRect(2, 2, -2, -2), CRect(4, 4, -4, -4)};
- CRect realRect = *rect;
- realRect.right--;
- realRect.bottom--;
- for (int i = 0; i < 4; i++)
- {
- m_oaPolygons[i].Add(new CVertex(realRect.left + offset[i].left,
- realRect.top + offset[i].top));
- m_oaPolygons[i].Add(new CVertex(realRect.right + offset[i].right,
- realRect.top + offset[i].top));
- m_oaPolygons[i].Add(new CVertex(realRect.right + offset[i].right,
- realRect.bottom + offset[i].bottom));
- m_oaPolygons[i].Add(new CVertex(realRect.left + offset[i].left,
- realRect.bottom + offset[i].bottom));
- }
- ClosePolygons();
- }
- void CVtxPolygons::CreateDiamond(const CRect& rect)
- {
- RemoveAll();
- CRect offset[4] = {CRect(0, 0, 0, 0), CRect(1, 1, -1, -1),
- CRect(2, 2, -2, -2), CRect(4, 4, -4, -4)};
- CRect realRect = *rect;
- realRect.right--;
- realRect.bottom--;
- UINT side;
- if (realRect.right > realRect.bottom)
- {
- side = realRect.bottom;
- realRect.left = round((realRect.right - side) / 2);
- realRect.right = realRect.left + side;
- }
- else
- {
- side = realRect.right;
- realRect.top = round((realRect.bottom - side) / 2);
- realRect.bottom = realRect.top + side;
- }
- for (UINT i = 0; i < 4; i++)
- {
- m_oaPolygons[i].Add(new CVertex(realRect.left + offset[i].left,
- round(realRect.top + realRect.Height() / 2)));
- m_oaPolygons[i].Add(new CVertex(round(realRect.left + realRect.Width() / 2),
- realRect.top + offset[i].top));
- m_oaPolygons[i].Add(new CVertex(realRect.right + offset[i].right,
- round(realRect.top + realRect.Height() / 2)));
- m_oaPolygons[i].Add(new CVertex(round(realRect.left + realRect.Width() / 2),
- realRect.bottom + offset[i].bottom));
- }
- ClosePolygons();
- }
- void CVtxPolygons::CreateCircle(const CRect& rect, const int& nSegments)
- {
- RemoveAll();
- CRect realRect = *rect;
- realRect.right--;
- realRect.bottom--;
- double dCenterX = realRect.left + realRect.Width() / 2;
- double dCenterY = realRect.top + realRect.Height() / 2;
- UINT nSide;
- double dRadius;
- if (realRect.right > realRect.bottom)
- {
- nSide = realRect.bottom;
- realRect.left = round((realRect.right - nSide) / 2);
- realRect.right = realRect.left + nSide;
- dRadius = dCenterY;
- }
- else
- {
- nSide = realRect.right;
- realRect.top = round((realRect.bottom - nSide) / 2);
- realRect.bottom = realRect.top + nSide;
- dRadius = dCenterX;
- }
- double dLayers[4] = {dRadius, dRadius - 1, dRadius - 2, dRadius - 4};
- int segments = (nSegments < 2 ? round(dRadius) : nSegments);
- double dAngle;
- for (int i = 0; i < 4; i++)
- {
- m_oaPolygons[i].RemoveAll();
- for (int j = 0; j < segments; j++)
- {
- dAngle = 2.0 * PI * j / segments;
- m_oaPolygons[i].Add(new CVertex(round(dCenterX + cos(dAngle) * dLayers[i]),
- round(dCenterY + sin(dAngle) * dLayers[i])));
- }
- }
- ClosePolygons();
- }
- void CVtxPolygons::CreateStretchedCircle(const CRect& rect, const int& nSegments)
- {
- RemoveAll();
- CRect realRect = *rect;
- realRect.right--;
- realRect.bottom--;
- double dRadius;
- double dRightX, dRightY;
- double dStartAngle;
- BOOL bHorizontal = realRect.right > realRect.bottom;
- if (bHorizontal)
- {
- dRadius = realRect.top + realRect.Height() / 2;
- dRightX = realRect.right - dRadius;
- dRightY = dRadius;
- dStartAngle = 3 * PI / 2;
- }
- else
- {
- dRadius = realRect.left + realRect.Width() / 2;
- dRightX = dRadius;
- dRightY = realRect.bottom - dRadius;
- dStartAngle = 0;
- }
- double dLeftX = dRadius;
- double dLeftY = dRadius;
-
- double dRadiusLayers[4] = {dRadius, dRadius - 1, dRadius - 2, dRadius - 4};
- int segments = (nSegments < 1 ? round(dRadius) : nSegments);
- double dAngle;
- for (int i = 0; i < 4; i++)
- {
- m_oaPolygons[i].RemoveAll();
- for (int j = 0; j < round(segments / 2 + 1); j++)
- {
- dAngle = dStartAngle + 2 * PI * j / segments;
- m_oaPolygons[i].Add(new CVertex(round(dRightX + cos(dAngle) *
- dRadiusLayers[i]), round(dRightY + sin(dAngle) * dRadiusLayers[i])));
- }
- for (j = round(segments / 2); j < segments + 1; j++)
- {
- dAngle = dStartAngle + 2 * PI * j / segments;
- m_oaPolygons[i].Add(new CVertex(round(dLeftX + cos(dAngle) *
- dRadiusLayers[i]), round(dLeftY + sin(dAngle) *dRadiusLayers[i])));
- }
- }
- ClosePolygons();
- }
- void CVtxPolygons::CreatePolygonRgn(CRgn *rgn, const int& nPolygon)
- {
- ASSERT(ValidPolygons());
- ClosePolygons();
-
- CPoint pts[1024];
- for (int i = 0; i < m_oaPolygons[nPolygon].GetSize(); i++)
- pts[i] = (CPoint)(*(CVertex*)m_oaPolygons[nPolygon].GetAt(i));
- rgn->CreatePolygonRgn(pts, m_oaPolygons[nPolygon].GetSize(), ALTERNATE);
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
复制代码
VTXBUTTON.H
- #if _MSC_VER >= 1000
- #pragma once
- #endif // _MSC_VER >= 1000
- #include "Vtx.h"
- ///////////////////////////////////////////////////////////////////////////////////////////
- // CVtxButton button
- //
- // A class derived from CButton that is drawn in the shape specified by
- // CVtxPolygons.
- //
- class CVtxButton : public CButton
- {
- // Construction
- public:
- CVtxButton();
- // Attributes
- private:
- CVtxPolygons m_vtxBtnPolygons;
- CDC *m_pBitmapDC;
- CBitmap *m_pBtn,
- *m_pBtnFocus,
- *m_pBtnSelected;
- DWORD m_dwStyle;
- BOOL m_bNeedToRegenerateBitmaps;
- // Operations
- public:
- // Select a custom CVtxPolygons shape:
- void SetVtxPolygons(CVtxPolygons *vtxBtnPolygons);
- // Select a standard CVtxPolygons shape:
- void SetVtx(const int& nType);
- private:
- void GenerateBitmaps(LPDRAWITEMSTRUCT lpDrawItemStruct);
- // Overrides
- public:
- virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
- protected:
- virtual void PreSubclassWindow();
- // Implementation
- public:
- virtual ~CVtxButton();
- };
- ///////////////////////////////////////////////////////////////////////////////////////////
复制代码
VTXBUTTON.CPP
- #include "stdafx.h"
- #include "Vtx.h"
- #include "VtxButton.h"
- #include <math.h>
- // Windows system colors:
- #define RGB_BUTTON_BLACK (GetSysColor(COLOR_3DDKSHADOW))
- #define RGB_BUTTON_WHITE (GetSysColor(COLOR_3DHILIGHT))
- #define RGB_BUTTON_GRAY (GetSysColor(COLOR_3DFACE))
- #define RGB_BUTTON_LIGHT (GetSysColor(COLOR_3DLIGHT))
- #define RGB_BUTTON_DARK (GetSysColor(COLOR_3DSHADOW))
- // The angle (in radians) from which the light is from:
- #define LIGHT_SOURCE_ANGLE 3 * PI / 4
- // There is no excuse for inaccuracy in this area =)
- #define PI 3.1415926535897932384626433832795028841971693993751058209
- // A very convenient way to properly convert double's to int's:
- #define round(x) (int)(x + 0.5)
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Misc functions
- // Compute the angle of a line segment given it's rise and run:
- double GetAngle(const double& dRise, const double& dRun)
- {
- double dAngle = atan2(dRise, dRun);
-
- if (dAngle < 0.0)
- dAngle = 2 * PI + dAngle;
- return dAngle;
- }
- // Compute an intermediate color:
- COLORREF InterpolateColors(const COLORREF& crA, const COLORREF& crB, const double& dWeight)
- {
- BYTE Red = (BYTE)(dWeight * GetRValue(crA) + (1.0 - dWeight) * GetRValue(crB));
- BYTE Green = (BYTE)(dWeight * GetGValue(crA) + (1.0 - dWeight) * GetGValue(crB));
- BYTE Blue = (BYTE)(dWeight * GetBValue(crA) + (1.0 - dWeight) * GetBValue(crB));
- return RGB(Red, Green, Blue);
- }
- // Compute the color of a line segment defined by ptA and ptB:
- COLORREF GetColor(const CPoint& ptA, const CPoint& ptZ, const COLORREF& crDark,
- const COLORREF& crBright)
- {
- double dRise = (double)(ptZ.y - ptA.y);
- double dRun = (double)(ptA.x - ptZ.x);
- double dAngle = 2 * PI - GetAngle(dRun, dRise);
- double dAngleDifference = fabs(LIGHT_SOURCE_ANGLE - dAngle);
- // I blatantly took this code fragment, "0.5 * (cos(dAngleDifference) + 1.0)," from
- // Chris Maunder because it works. I am at a loss as to why.
- return InterpolateColors(crBright, crDark, 0.5 * (cos(dAngleDifference) + 1.0));
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
- // CVtxButton button
- CVtxButton::CVtxButton()
- {
- m_pBtn = new CBitmap;
- m_pBtnFocus = new CBitmap;
- m_pBtnSelected = new CBitmap;
- m_pBitmapDC = new CDC;
- m_bNeedToRegenerateBitmaps = TRUE;
- }
- CVtxButton::~CVtxButton()
- {
- delete m_pBitmapDC;
- delete m_pBtn;
- delete m_pBtnFocus;
- delete m_pBtnSelected;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CVtxButton message handlers
- void CVtxButton::PreSubclassWindow()
- {
- CButton::PreSubclassWindow();
- ModifyStyle(0, BS_OWNERDRAW);
- }
- // Paint the button with the correct bitmap:
- void CVtxButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- ASSERT(lpDrawItemStruct != NULL);
- CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- CRect rect = lpDrawItemStruct->rcItem;
- UINT state = lpDrawItemStruct->itemState;
- if (!m_vtxBtnPolygons.ValidPolygons())
- SetVtx(VTX_RECT);
- if (m_bNeedToRegenerateBitmaps || m_dwStyle != GetStyle())
- GenerateBitmaps(lpDrawItemStruct);
- if (state & ODS_SELECTED)
- m_pBitmapDC->SelectObject(m_pBtnSelected);
- else
- {
- if (state & ODS_FOCUS)
- m_pBitmapDC->SelectObject(m_pBtnFocus);
- else
- m_pBitmapDC->SelectObject(m_pBtn);
- }
- pDC->BitBlt(0, 0, rect.Width(), rect.Height(), m_pBitmapDC, 0, 0, SRCCOPY);
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
- // CVtxButton operations
- void CVtxButton::SetVtxPolygons(CVtxPolygons *vtxBtnPolygons)
- {
- m_vtxBtnPolygons.Copy(*vtxBtnPolygons);
- CRgn rgn;
- m_vtxBtnPolygons.CreatePolygonRgn(&rgn, 0);
-
- HRGN hRgn;
- hRgn = (HRGN)rgn.Detach();
- SetWindowRgn(hRgn, TRUE);
- m_bNeedToRegenerateBitmaps = TRUE;
- }
- void CVtxButton::SetVtx(const int& nType)
- {
- CRect rect;
- GetClientRect(rect);
- m_vtxBtnPolygons.Create(&rect, nType);
- CRgn rgn;
- m_vtxBtnPolygons.CreatePolygonRgn(&rgn, 0);
- HRGN hRgn;
- hRgn = (HRGN)rgn.Detach();
- SetWindowRgn(hRgn, TRUE);
- m_bNeedToRegenerateBitmaps = TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
- // CVtxButton state bitmap generation:
- void CVtxButton::GenerateBitmaps(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- ASSERT(lpDrawItemStruct != NULL);
- CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- CRect rect = lpDrawItemStruct->rcItem;
- UINT state = lpDrawItemStruct->itemState;
- m_dwStyle = GetStyle();
- CRgn rgn;
- m_vtxBtnPolygons.CreatePolygonRgn(&rgn, 3);
- delete m_pBitmapDC;
- m_pBitmapDC = new CDC;
- m_pBitmapDC->CreateCompatibleDC(pDC);
- CFont *oldFont = m_pBitmapDC->SelectObject(pDC->GetCurrentFont());
- CString strText;
- GetWindowText(strText);
- CSize extent = m_pBitmapDC->GetTextExtent(strText);
- CPoint ptCenter = rect.CenterPoint();
- CPoint pt = CPoint(ptCenter.x - extent.cx / 2 - 1, ptCenter.y - extent.cy / 2 - 1);
- CRect textRect(pt.x, pt.y, pt.x + extent.cx, pt.y + extent.cy);
- delete m_pBtn;
- m_pBtn = new CBitmap;
- m_pBtn->CreateCompatibleBitmap(pDC, rect.right, rect.bottom);
- m_pBitmapDC->SelectObject(m_pBtn);
- m_pBitmapDC->SelectStockObject(NULL_BRUSH);
- m_pBitmapDC->FillSolidRect(rect, RGB_BUTTON_GRAY);
- // Generate m_pBtn bitmap: unfocused button
- if (m_dwStyle & BS_FLAT)
- {
- COLORREF crBlend = InterpolateColors(RGB_BUTTON_WHITE, RGB_BUTTON_BLACK, 0.5);
- CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
- CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(crBlend));
- CPoint pts[4];
-
- for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
- pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
- delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_WHITE));
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(1, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(1, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(1, i), RGB_BUTTON_WHITE);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
- }
- delete m_pBitmapDC->SelectObject(oldpen);
- delete m_pBitmapDC->SelectObject(oldBrush);
- }
- else
- {
- CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
- CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_GRAY));
- CPoint pts[4];
- COLORREF crLighter = RGB_BUTTON_LIGHT;
- COLORREF crDarker = RGB_BUTTON_DARK;
- COLORREF crBlend = RGB_BUTTON_GRAY;
-
- for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
- pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
- crLighter = GetColor(*m_vtxBtnPolygons.GetAt(1, i),
- *m_vtxBtnPolygons.GetAt(1, i + 1), RGB_BUTTON_DARK,
- RGB_BUTTON_LIGHT);
- crDarker = GetColor(*m_vtxBtnPolygons.GetAt(0, i),
- *m_vtxBtnPolygons.GetAt(0, i + 1), RGB_BUTTON_BLACK,
- RGB_BUTTON_WHITE);
- crBlend = InterpolateColors(crLighter, crDarker, 0.5);
- delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crLighter));
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(1, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(1, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(1, i), crLighter);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crDarker));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- }
- delete m_pBitmapDC->SelectObject(oldpen);
- delete m_pBitmapDC->SelectObject(oldBrush);
- }
- if (!strText.IsEmpty())
- {
- m_pBitmapDC->SelectClipRgn(&rgn);
- m_pBitmapDC->SetBkMode(TRANSPARENT);
- if (state & ODS_DISABLED)
- m_pBitmapDC->DrawState(pt, extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
- else
- {
- m_pBitmapDC->DrawText(strText, -1, textRect, DT_SINGLELINE | DT_CENTER |
- DT_VCENTER);
- }
- m_pBitmapDC->SelectClipRgn(NULL);
- }
- delete m_pBtnFocus;
- m_pBtnFocus = new CBitmap;
- m_pBtnFocus->CreateCompatibleBitmap(pDC, rect.right, rect.bottom);
- m_pBitmapDC->SelectObject(m_pBtnFocus);
- m_pBitmapDC->SelectStockObject(NULL_BRUSH);
- m_pBitmapDC->FillSolidRect(rect, RGB_BUTTON_GRAY);
- // Generate m_pBtnFocus bitmap: focused button
- if (m_dwStyle & BS_FLAT)
- {
- CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
- CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_GRAY));
- CPoint pts[4];
- COLORREF crBlend = InterpolateColors(RGB_BUTTON_WHITE, RGB_BUTTON_BLACK, 0.5);
-
- for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
- pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
- delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(2, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(2, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_WHITE));
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(2, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(2, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(2, i), RGB_BUTTON_WHITE);
- delete m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_BLACK));
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- }
-
- delete m_pBitmapDC->SelectObject(oldBrush);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
- for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
- }
- COLORREF crColor = InterpolateColors(RGB_BUTTON_GRAY, RGB_BUTTON_DARK, 0.5);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crColor));
- for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(3, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(3, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(3, i), crColor);
- }
- delete m_pBitmapDC->SelectObject(oldpen);
- }
- else
- {
- CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
- CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_GRAY));
- CPoint pts[4];
- COLORREF crLighter = RGB_BUTTON_LIGHT;
- COLORREF crDarker = RGB_BUTTON_DARK;
- COLORREF crBlend = RGB_BUTTON_GRAY;
-
- for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
- pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
- crLighter = GetColor(*m_vtxBtnPolygons.GetAt(2, i),
- *m_vtxBtnPolygons.GetAt(2, i + 1), RGB_BUTTON_DARK,
- RGB_BUTTON_LIGHT);
- crDarker = GetColor(*m_vtxBtnPolygons.GetAt(1, i),
- *m_vtxBtnPolygons.GetAt(1, i + 1), RGB_BUTTON_BLACK,
- RGB_BUTTON_WHITE);
- crBlend = InterpolateColors(crLighter, crDarker, 0.5);
- delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(2, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(2, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crLighter));
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(2, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(2, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(2, i), crLighter);
- delete m_pBitmapDC->SelectObject(new CBrush(crDarker));
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crDarker));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- }
-
- delete m_pBitmapDC->SelectObject(oldBrush);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
- for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
- }
- COLORREF crColor = InterpolateColors(RGB_BUTTON_GRAY, RGB_BUTTON_DARK, 0.5);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crColor));
- for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(3, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(3, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(3, i), crColor);
- }
- delete m_pBitmapDC->SelectObject(oldpen);
- }
- if (!strText.IsEmpty())
- {
- m_pBitmapDC->SelectClipRgn(&rgn);
- m_pBitmapDC->SetBkMode(TRANSPARENT);
- if (state & ODS_DISABLED)
- m_pBitmapDC->DrawState(pt, extent, strText, DSS_DISABLED, TRUE, 0,
- (HBRUSH)NULL);
- else
- {
- m_pBitmapDC->DrawText(strText, -1, textRect, DT_SINGLELINE | DT_CENTER |
- DT_VCENTER);
- }
- m_pBitmapDC->SelectClipRgn(NULL);
- }
- delete m_pBtnSelected;
- m_pBtnSelected = new CBitmap;
- m_pBtnSelected->CreateCompatibleBitmap(pDC, rect.right, rect.bottom);
- m_pBitmapDC->SelectObject(m_pBtnSelected);
- m_pBitmapDC->SelectStockObject(NULL_BRUSH);
- m_pBitmapDC->FillSolidRect(rect, RGB_BUTTON_GRAY);
- // Generate m_pBtnSelected bitmap: selected button
- if (m_dwStyle & BS_FLAT)
- {
- COLORREF crBlend = InterpolateColors(RGB_BUTTON_DARK, RGB_BUTTON_BLACK, 0.5);
- CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_GRAY));
- CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_GRAY));
- CPoint pts[4];
-
- for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
- pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
- delete m_pBitmapDC->SelectObject(new CBrush(crBlend));
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(2, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(2, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_WHITE));
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(2, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(2, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(2, i), RGB_BUTTON_WHITE);
- delete m_pBitmapDC->SelectObject(new CBrush(RGB_BUTTON_BLACK));
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
- m_pBitmapDC->Polygon(pts, 4);
- }
-
- delete m_pBitmapDC->SelectObject(oldBrush);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
- for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
- }
- COLORREF crColor = InterpolateColors(RGB_BUTTON_GRAY, RGB_BUTTON_DARK, 0.5);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crColor));
- for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(3, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(3, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(3, i), crColor);
- }
- delete m_pBitmapDC->SelectObject(oldpen);
- }
- else
- {
- COLORREF crBlend = InterpolateColors(RGB_BUTTON_DARK, RGB_BUTTON_BLACK, 0.5);
- CPen *oldpen = m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_DARK));
- CBrush *oldBrush = m_pBitmapDC->SelectObject(new CBrush(crBlend));
- CPoint pts[4];
- for (int i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crBlend));
- pts[0] = CPoint(*m_vtxBtnPolygons.GetAt(1, i));
- pts[1] = CPoint(*m_vtxBtnPolygons.GetAt(1, i + 1));
- pts[2] = CPoint(*m_vtxBtnPolygons.GetAt(0, i + 1));
- pts[3] = CPoint(*m_vtxBtnPolygons.GetAt(0, i));
- m_pBitmapDC->Polygon(pts, 4);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_DARK));
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(1, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(1, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(1, i), RGB_BUTTON_DARK);
- }
- delete m_pBitmapDC->SelectObject(oldBrush);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, RGB_BUTTON_BLACK));
- for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(0, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(0, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(0, i), RGB_BUTTON_BLACK);
- }
- COLORREF crColor = InterpolateColors(RGB_BUTTON_GRAY, RGB_BUTTON_DARK, 0.5);
- delete m_pBitmapDC->SelectObject(new CPen(PS_SOLID, 1, crColor));
- for (i = 0; i < m_vtxBtnPolygons.GetSize(0) - 1; i++)
- {
- m_pBitmapDC->MoveTo(*m_vtxBtnPolygons.GetAt(3, i + 1));
- m_pBitmapDC->LineTo(*m_vtxBtnPolygons.GetAt(3, i));
- m_pBitmapDC->SetPixelV(*m_vtxBtnPolygons.GetAt(3, i), crColor);
- }
- delete m_pBitmapDC->SelectObject(oldpen);
- }
- if (!strText.IsEmpty())
- {
- m_pBitmapDC->SelectClipRgn(&rgn);
- pt.Offset(1, 1);
- textRect.OffsetRect(1, 1);
- m_pBitmapDC->SetBkMode(TRANSPARENT);
- if (state & ODS_DISABLED)
- m_pBitmapDC->DrawState(pt, extent, strText, DSS_DISABLED, TRUE, 0,
- (HBRUSH)NULL);
- else
- {
- m_pBitmapDC->DrawText(strText, -1, textRect, DT_SINGLELINE | DT_CENTER |
- DT_VCENTER);
- }
- m_pBitmapDC->SelectClipRgn(NULL);
- }
- m_pBitmapDC->SelectObject(oldFont);
- m_bNeedToRegenerateBitmaps = FALSE;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
复制代码 如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
|