GDI+画刷(LinearGradientBrush(一))

发布时间 2023-07-21 15:14:50作者: 左边的翼

一、LinearGradientBrush构造种类

  路径渐变画刷在官方文档中给出构造种类一共5中,如下所示:

1 LinearGradientBrush(Point&,Point&,Color&,Color&);
2 LinearGradientBrush(PointF&,PointF&,Color&,Color&);
3 LinearGradientBrush(Rect&,Color&,Color&,REAL,BOOL);
4 LinearGradientBrush(Rect&,Color&,Color&,LinearGradientMode);
5 LinearGradientBrush(RectF&,Color&,Color&,LinearGradientMode)

   LinearGradientMode在官方文档中定义有4中,如下所示:

1 typedef enum LinearGradientMode {
2 LinearGradientModeHorizontal,
3 LinearGradientModeVertical,
4 LinearGradientModeForwardDiagonal,
5 LinearGradientModeBackwardDiagonal
6 } ;

二、构造函数略

  1、LinearGradientBrush(Point&,Point&,Color&,Color&),该构造模式下,代码效果如下:

   注:构造函数中两个Point指定颜色渐变的方向,Y值相同可实现横向渐变,X值相同可实现纵向渐变

   变量定义:

 1 COLORREF m_pColorRef1;
 2 COLORREF m_pColorRef2;
 3 Point m_pPoint1;
 4 Point m_pPoint2;
 5 GraphicsPath m_pPath1;
 6 GraphicsPath m_pPath2;
 7 
 8 bool m_pLBDown;
 9 bool m_pRBDown;
10 
11 CDC MemDCIndicator;
12 CBitmap MemBitmapIndicator;
13 CDC *pDC;
14 
15 CColorCombo m_pColor1;
16 CColorCombo m_pColor2;

  关键代码:

  1 void LinearGradientDlg::DoDataExchange(CDataExchange* pDX)
  2 {
  3     CDialogEx::DoDataExchange(pDX);
  4     DDX_Control(pDX, IDC_COMBO_FORECOLOR, m_pColor1);
  5     DDX_Control(pDX, IDC_COMBO_BACKCOLOR, m_pColor2);
  6 }
  7 
  8 BEGIN_MESSAGE_MAP(LinearGradientDlg, CDialogEx)
  9     ON_CBN_SELCHANGE(IDC_COMBO_FORECOLOR, &LinearGradientDlg::OnSelchangeComboForecolor)
 10     ON_CBN_SELCHANGE(IDC_COMBO_BACKCOLOR, &LinearGradientDlg::OnSelchangeComboBackcolor)
 11     ON_WM_PAINT()
 12     ON_WM_MOUSEMOVE()
 13     ON_WM_LBUTTONDOWN()
 14     ON_WM_LBUTTONUP()
 15     ON_WM_RBUTTONDOWN()
 16     ON_WM_RBUTTONUP()
 17 END_MESSAGE_MAP()
 18 
 19 BOOL LinearGradientDlg::OnInitDialog()
 20 {
 21     CDialogEx::OnInitDialog();
 22     m_pColor1.AddItem(_T("紫色"), RGB(128, 0, 128));
 23     m_pColor1.AddItem(_T("青色"), RGB(0, 255, 255));
 24     m_pColor1.AddItem(_T("红色"), RGB(255, 0, 0));
 25     m_pColor1.AddItem(_T("蓝色"), RGB(0, 0, 255));
 26     m_pColor1.AddItem(_T("绿色"), RGB(0, 255, 0));
 27     m_pColor1.AddItem(_T("黄色"), RGB(255, 255, 0));
 28     m_pColor1.AddItem(_T("粉色"), RGB(255, 0, 255));
 29     m_pColor1.AddItem(_T("棕色"), RGB(255, 128, 64));
 30     m_pColor1.SetCurSel(0);
 31 
 32     m_pColor2.AddItem(_T("紫色"), RGB(128, 0, 128));
 33     m_pColor2.AddItem(_T("青色"), RGB(0, 255, 255));
 34     m_pColor2.AddItem(_T("红色"), RGB(255, 0, 0));
 35     m_pColor2.AddItem(_T("蓝色"), RGB(0, 0, 255));
 36     m_pColor2.AddItem(_T("绿色"), RGB(0, 255, 0));
 37     m_pColor2.AddItem(_T("黄色"), RGB(255, 255, 0));
 38     m_pColor2.AddItem(_T("粉色"), RGB(255, 0, 255));
 39     m_pColor2.AddItem(_T("棕色"), RGB(255, 128, 64));
 40     m_pColor2.SetCurSel(0);
 41 
 42     m_pColorRef1 = RGB(255, 0, 0);
 43     m_pColorRef2 = RGB(0, 0, 255);
 44 
 45     m_pLBDown = false;
 46     m_pRBDown = false;
 47 
 48     CRect crt;
 49     GetClientRect(&crt);
 50     m_pPoint1 = Point(0,0);
 51     m_pPoint2 = Point(crt.Width() / 2, 0);
 52     m_pPath1.AddRectangle(Rect(-5, -5, 10, 10));
 53     m_pPath2.AddRectangle(Rect(crt.Width() / 2 - 5, -5, 10, 10));
 54 
 55     return TRUE;
 56 }
 57 
 58 void LinearGradientDlg::OnSelchangeComboForecolor()
 59 {
 60     m_pColorRef1 = m_pColor1.GetItemData(m_pColor1.GetCurSel());
 61     Invalidate();
 62 }
 63 
 64 void LinearGradientDlg::OnSelchangeComboBackcolor()
 65 {
 66     m_pColorRef2 = m_pColor2.GetItemData(m_pColor2.GetCurSel());
 67     Invalidate();
 68 }
 69 
 70 void LinearGradientDlg::OnPaint()
 71 {
 72     CPaintDC dc(this);
 73     DrawFunction();
 74 }
 75 
 76 void LinearGradientDlg::OnMouseMove(UINT nFlags, CPoint point)
 77 {
 78     if (m_pLBDown)
 79     {
 80         m_pPoint1.X = point.x;
 81         m_pPoint1.Y = point.y;
 82         DrawFunction();
 83     }
 84 
 85     if (m_pRBDown)
 86     {
 87         m_pPoint2.X = point.x;
 88         m_pPoint2.Y = point.y;
 89         DrawFunction();
 90     }
 91     CDialogEx::OnMouseMove(nFlags, point);
 92 }
 93 
 94 void LinearGradientDlg::DrawFunction()
 95 {
 96     CRect rt;
 97     GetClientRect(&rt);
 98     pDC = GetDC();
 99     MemDCIndicator.CreateCompatibleDC(pDC);
100     MemBitmapIndicator.CreateCompatibleBitmap(pDC, rt.Width(), rt.Height() / 2);
101     MemDCIndicator.SelectObject(&MemBitmapIndicator);
102     MemDCIndicator.FillSolidRect(rt, RGB(100, 100, 100));
103 
104     Graphics graphics(MemDCIndicator);
105     graphics.SetSmoothingMode(SmoothingModeAntiAlias);
106     LinearGradientBrush lbr(m_pPoint1, m_pPoint2,
107         Color(GetRValue(m_pColorRef1), GetGValue(m_pColorRef1), GetBValue(m_pColorRef1)),
108         Color(GetRValue(m_pColorRef2), GetGValue(m_pColorRef2), GetBValue(m_pColorRef2)));
109 
110     graphics.FillRectangle(&SolidBrush(Color(100, 100, 100)), Rect(0, 0, rt.Width() / 2, rt.Height() / 2));
111     graphics.FillEllipse(&lbr, Rect(0, 0, rt.Width() / 2, rt.Height() / 2));
112     graphics.FillRectangle(&lbr, Rect(rt.Width() / 2, 0, rt.Width() / 2, rt.Height() / 2));
113 
114     graphics.DrawRectangle(&Pen(Color(255, 255, 0), 2.0), Rect(m_pPoint1.X - 5, m_pPoint1.Y - 5, 10, 10));
115     graphics.DrawRectangle(&Pen(Color(255, 255, 0), 2.0), Rect(m_pPoint2.X - 5, m_pPoint2.Y - 5, 10, 10));
116 
117     pDC->BitBlt(rt.left, rt.top, rt.Width(), rt.Height() / 2, &MemDCIndicator, 0, 0, SRCCOPY);
118     MemDCIndicator.DeleteDC();
119     MemBitmapIndicator.DeleteObject();
120     ReleaseDC(pDC);
121 }
122 
123 void LinearGradientDlg::OnLButtonDown(UINT nFlags, CPoint point)
124 {
125     m_pLBDown = !m_pLBDown;
126     CDialogEx::OnLButtonDown(nFlags, point);
127 }
128 
129 
130 void LinearGradientDlg::OnLButtonUp(UINT nFlags, CPoint point)
131 {
132     m_pLBDown = !m_pLBDown;
133     CDialogEx::OnLButtonUp(nFlags, point);
134 }
135 
136 
137 
138 void LinearGradientDlg::OnRButtonDown(UINT nFlags, CPoint point)
139 {
140     m_pRBDown = !m_pRBDown;
141     CDialogEx::OnRButtonDown(nFlags, point);
142 }
143 
144 
145 void LinearGradientDlg::OnRButtonUp(UINT nFlags, CPoint point)
146 {
147     m_pRBDown = !m_pRBDown;
148     CDialogEx::OnRButtonUp(nFlags, point);
149 }