工控编程吧
标题:
上位机MFC各种定制形状按钮实例
[打印本页]
作者:
qq263946146
时间:
2019-7-3 14:59
标题:
上位机MFC各种定制形状按钮实例
效果演示
例程通过自己编写按钮类实现不同形状按钮功能,效果如图:
(, 下载次数: 0)
上传
点击文件名下载附件
工程实现目录内编译生成有可执行例程,可直接运行查看效果
下面代码可复制使用,也可直接下载工程源代码
(, 下载次数: 0)
上传
点击文件名下载附件
实现过程
1.新建一基于对应框的工程,如界面添加按钮控件并进行排版,按钮ID依次修改为m_cButton1。。。。m_cButton12。
2.将例程根据目录四个文件VTXBUTTON.CPP,VTXBUTTON.H,VTX.H,VTX.CPP复制到自己项目根目录,
并加载到项目中。这样项目的类管理窗口就会多出三个新的类CVertex,CVTXBUTTON,CVTXPOLYGON.
(, 下载次数: 0)
上传
点击文件名下载附件
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;
}
///////////////////////////////////////////////////////////////////////////////////////////
复制代码
[weixinlianxi]1[/weixinlianxi]
欢迎光临 工控编程吧 (https://www.gkbc8.com/)
Powered by Discuz! X3.4