Skip to content

Commit 30be03c

Browse files
committed
主窗口新增png格式透明背景图片的支持
1 parent fa5c43a commit 30be03c

File tree

11 files changed

+394
-125
lines changed

11 files changed

+394
-125
lines changed

TrafficMonitor/DrawCommon.cpp

Lines changed: 59 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -71,57 +71,10 @@ void CDrawCommon::DrawBitmap(CBitmap& bitmap, CPoint start_point, CSize size, St
7171
// 以下两行避免图片失真
7272
m_pDC->SetStretchBltMode(HALFTONE);
7373
m_pDC->SetBrushOrg(0, 0);
74-
CSize draw_size;
75-
if (size.cx == 0 || size.cy == 0) //如果指定的size为0,则使用位图的实际大小绘制
76-
{
77-
draw_size = CSize(bm.bmWidth, bm.bmHeight);
78-
}
79-
else
80-
{
81-
draw_size = size;
82-
if (stretch_mode == StretchMode::FILL)
83-
{
84-
SetDrawRect(CRect(start_point, draw_size));
85-
float w_h_radio, w_h_radio_draw; //图像的宽高比、绘制大小的宽高比
86-
w_h_radio = static_cast<float>(bm.bmWidth) / bm.bmHeight;
87-
w_h_radio_draw = static_cast<float>(size.cx) / size.cy;
88-
if (w_h_radio > w_h_radio_draw) //如果图像的宽高比大于绘制区域的宽高比,则需要裁剪两边的图像
89-
{
90-
int image_width; //按比例缩放后的宽度
91-
image_width = bm.bmWidth * draw_size.cy / bm.bmHeight;
92-
start_point.x -= ((image_width - draw_size.cx) / 2);
93-
draw_size.cx = image_width;
94-
}
95-
else
96-
{
97-
int image_height; //按比例缩放后的高度
98-
image_height = bm.bmHeight * draw_size.cx / bm.bmWidth;
99-
start_point.y -= ((image_height - draw_size.cy) / 2);
100-
draw_size.cy = image_height;
101-
}
102-
}
103-
else if (stretch_mode == StretchMode::FIT)
104-
{
105-
draw_size = CSize(bm.bmWidth, bm.bmHeight);
106-
float w_h_radio, w_h_radio_draw; //图像的宽高比、绘制大小的宽高比
107-
w_h_radio = static_cast<float>(bm.bmWidth) / bm.bmHeight;
108-
w_h_radio_draw = static_cast<float>(size.cx) / size.cy;
109-
if (w_h_radio > w_h_radio_draw) //如果图像的宽高比大于绘制区域的宽高比
110-
{
111-
draw_size.cy = draw_size.cy * size.cx / draw_size.cx;
112-
draw_size.cx = size.cx;
113-
start_point.y += ((size.cy - draw_size.cy) / 2);
114-
}
115-
else
116-
{
117-
draw_size.cx = draw_size.cx * size.cy / draw_size.cy;
118-
draw_size.cy = size.cy;
119-
start_point.x += ((size.cx - draw_size.cx) / 2);
120-
}
121-
}
122-
}
12374

124-
m_pDC->StretchBlt(start_point.x, start_point.y, draw_size.cx, draw_size.cy, &memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
75+
DrawCommonHelper::ImageDrawAreaConvert(CSize(bm.bmWidth, bm.bmHeight), start_point, size, stretch_mode);
76+
77+
m_pDC->StretchBlt(start_point.x, start_point.y, size.cx, size.cy, &memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
12578
memDC.DeleteDC();
12679
}
12780

@@ -262,6 +215,11 @@ void CDrawCommon::DrawLine(CPoint start_point, int height, COLORREF color, BYTE
262215
aPen.DeleteObject();
263216
}
264217

218+
int CDrawCommon::GetTextWidth(LPCTSTR lpszString)
219+
{
220+
return m_pDC->GetTextExtent(lpszString).cx;
221+
}
222+
265223
UINT DrawCommonHelper::ProccessTextFormat(CRect rect, CSize text_length, Alignment align, bool multi_line) noexcept
266224
{
267225
UINT result; // CDC::DrawText()函数的文本格式
@@ -289,3 +247,54 @@ UINT DrawCommonHelper::ProccessTextFormat(CRect rect, CSize text_length, Alignme
289247
}
290248
return result;
291249
}
250+
251+
void DrawCommonHelper::ImageDrawAreaConvert(CSize image_size, CPoint& start_point, CSize& size, IDrawCommon::StretchMode stretch_mode)
252+
{
253+
if (size.cx == 0 || size.cy == 0) //如果指定的size为0,则使用位图的实际大小绘制
254+
{
255+
size = CSize(image_size.cx, image_size.cy);
256+
}
257+
else
258+
{
259+
if (stretch_mode == IDrawCommon::StretchMode::FILL)
260+
{
261+
float w_h_ratio, w_h_ratio_draw; //图像的宽高比、绘制大小的宽高比
262+
w_h_ratio = static_cast<float>(image_size.cx) / image_size.cy;
263+
w_h_ratio_draw = static_cast<float>(size.cx) / size.cy;
264+
if (w_h_ratio > w_h_ratio_draw) //如果图像的宽高比大于绘制区域的宽高比,则需要裁剪两边的图像
265+
{
266+
int image_width; //按比例缩放后的宽度
267+
image_width = image_size.cx * size.cy / image_size.cy;
268+
start_point.x -= ((image_width - size.cx) / 2);
269+
size.cx = image_width;
270+
}
271+
else
272+
{
273+
int image_height; //按比例缩放后的高度
274+
image_height = image_size.cy * size.cx / image_size.cx;
275+
start_point.y -= ((image_height - size.cy) / 2);
276+
size.cy = image_height;
277+
}
278+
}
279+
else if (stretch_mode == IDrawCommon::StretchMode::FIT)
280+
{
281+
CSize draw_size = image_size;
282+
float w_h_ratio, w_h_ratio_draw; //图像的宽高比、绘制大小的宽高比
283+
w_h_ratio = static_cast<float>(image_size.cx) / image_size.cy;
284+
w_h_ratio_draw = static_cast<float>(size.cx) / size.cy;
285+
if (w_h_ratio > w_h_ratio_draw) //如果图像的宽高比大于绘制区域的宽高比
286+
{
287+
draw_size.cy = draw_size.cy * size.cx / draw_size.cx;
288+
draw_size.cx = size.cx;
289+
start_point.y += ((size.cy - draw_size.cy) / 2);
290+
}
291+
else
292+
{
293+
draw_size.cx = draw_size.cx * size.cy / draw_size.cy;
294+
draw_size.cy = size.cy;
295+
start_point.x += ((size.cx - draw_size.cx) / 2);
296+
}
297+
size = draw_size;
298+
}
299+
}
300+
}

TrafficMonitor/DrawCommon.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class CDrawCommon final : public IDrawCommon
1515
void Create(CDC* pDC, CWnd* pMainWnd);
1616
void SetFont(CFont* pfont) override; //设置绘制文本的字体
1717
void SetDC(CDC* pDC); //设置绘图的DC
18-
CDC* GetDC() { return m_pDC; }
18+
virtual CDC* GetDC() override { return m_pDC; }
1919
void SetBackColor(COLORREF back_color, BYTE alpha = 255) override { m_back_color = back_color; }
2020
void SetTextColor(const COLORREF text_color, BYTE alpha = 255) override
2121
{
@@ -49,6 +49,8 @@ class CDrawCommon final : public IDrawCommon
4949

5050
void DrawLine(CPoint start_point, int height, COLORREF color, BYTE alpha = 255) override; //使用当前画笔画线
5151

52+
virtual int GetTextWidth(LPCTSTR lpszString) override;
53+
5254
private:
5355
CDC* m_pDC{}; //用于绘图的CDC类的指针
5456
CWnd* m_pMainWnd{}; //绘图窗口的句柄
@@ -101,4 +103,12 @@ class CDrawDoubleBuffer final : public IDrawBuffer
101103
namespace DrawCommonHelper
102104
{
103105
UINT ProccessTextFormat(CRect rect, CSize text_length, Alignment align, bool multi_line) noexcept;
106+
107+
//根据图片拉伸模式,计算绘制图片的实际位置
108+
//image_size[int]:图片的原始大小
109+
//start_point[int][out]:绘制区域的起始位置
110+
//size[int][out]:绘制区域的大小
111+
//stretch_mode[int]:拉伸模式
112+
void ImageDrawAreaConvert(CSize image_size, CPoint& start_point, CSize& size, IDrawCommon::StretchMode stretch_mode);
113+
104114
};

TrafficMonitor/DrawCommonEx.cpp

Lines changed: 112 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,131 @@
11
#include "stdafx.h"
22
#include "DrawCommonEx.h"
3-
3+
#include "DrawCommon.h"
44

55
CDrawCommonEx::CDrawCommonEx(CDC* pDC)
66
{
7-
m_pDC = pDC;
8-
hThm = OpenThemeData(::GetDesktopWindow(), L"Window");
7+
Create(pDC);
8+
}
9+
10+
CDrawCommonEx::CDrawCommonEx()
11+
{
912
}
1013

1114

1215
CDrawCommonEx::~CDrawCommonEx()
1316
{
14-
CloseThemeData(hThm);
17+
SAFE_DELETE(m_pGraphics);
1518
}
1619

17-
void CDrawCommonEx::DrawWindowText(CRect rect, LPCTSTR str, COLORREF color)
20+
void CDrawCommonEx::Create(CDC* pDC)
1821
{
19-
m_pDC->SelectObject(m_pFont);
20-
m_pDC->SetTextColor(color);
22+
ASSERT(pDC != nullptr);
23+
m_pDC = pDC;
24+
SAFE_DELETE(m_pGraphics);
25+
m_pGraphics = new Gdiplus::Graphics(pDC->GetSafeHdc());
26+
}
2127

22-
DTTOPTS dttopts{};
23-
dttopts.dwSize = sizeof(DTTOPTS);
28+
void CDrawCommonEx::SetFont(CFont * pFont)
29+
{
30+
//将字体设置到CDC,绘图时从CDC创建GDI+字体
31+
m_pDC->SelectObject(pFont);
32+
}
2433

25-
dttopts.dwFlags = DTT_GLOWSIZE | DTT_COMPOSITED; //设置选项
26-
dttopts.iGlowSize = 0; //发光的范围大小
27-
HRESULT hr = DrawThemeTextEx(hThm, m_pDC->GetSafeHdc(), TEXT_LABEL, 0, str, -1, DT_LEFT | DT_SINGLELINE, rect, &dttopts);
34+
void CDrawCommonEx::DrawImage(Gdiplus::Image* pImage, CPoint start_point, CSize size, StretchMode stretch_mode)
35+
{
36+
m_pGraphics->SetInterpolationMode(Gdiplus::InterpolationMode::InterpolationModeHighQuality);
37+
DrawCommonHelper::ImageDrawAreaConvert(CSize(pImage->GetWidth(), pImage->GetHeight()), start_point, size, stretch_mode);
38+
m_pGraphics->DrawImage(pImage, INT(start_point.x), INT(start_point.y), INT(size.cx), INT(size.cy));
2839
}
2940

30-
void CDrawCommonEx::SetFont(CFont * pFont)
41+
void CDrawCommonEx::SetBackColor(COLORREF back_color, BYTE alpha)
42+
{
43+
m_back_color = CGdiPlusHelper::COLORREFToGdiplusColor(back_color, alpha);
44+
}
45+
46+
void CDrawCommonEx::DrawWindowText(CRect rect, LPCTSTR lpszString, COLORREF color, Alignment align, bool draw_back_ground, bool multi_line, BYTE alpha)
47+
{
48+
//设置字体
49+
Gdiplus::Font font(m_pDC->GetSafeHdc());
50+
//设置文本颜色
51+
Gdiplus::SolidBrush brush(CGdiPlusHelper::COLORREFToGdiplusColor(color));
52+
//设置对齐方式
53+
Gdiplus::StringFormat format;
54+
Gdiplus::StringAlignment alignment = Gdiplus::StringAlignmentNear;
55+
if (align == Alignment::CENTER)
56+
alignment = Gdiplus::StringAlignmentCenter;
57+
else if (align == Alignment::RIGHT)
58+
alignment = Gdiplus::StringAlignmentFar;
59+
format.SetAlignment(alignment); //水平对齐方式
60+
format.SetFormatFlags(Gdiplus::StringFormatFlagsNoFitBlackBox);
61+
format.SetLineAlignment(Gdiplus::StringAlignmentCenter); //垂直对齐方式
62+
//矩形区域
63+
Gdiplus::RectF rect_gdiplus = CGdiPlusHelper::CRectToGdiplusRect(rect);
64+
//绘制文本
65+
m_pGraphics->DrawString(lpszString, -1, &font, rect_gdiplus, &format, &brush);
66+
}
67+
68+
void CDrawCommonEx::SetDrawRect(CRect rect)
69+
{
70+
m_pGraphics->SetClip(CGdiPlusHelper::CRectToGdiplusRect(rect));
71+
}
72+
73+
void CDrawCommonEx::FillRect(CRect rect, COLORREF color, BYTE alpha)
74+
{
75+
Gdiplus::RectF rect_gdiplus = CGdiPlusHelper::CRectToGdiplusRect(rect);
76+
Gdiplus::SolidBrush brush(CGdiPlusHelper::COLORREFToGdiplusColor(color));
77+
m_pGraphics->FillRectangle(&brush, rect_gdiplus);
78+
}
79+
80+
void CDrawCommonEx::DrawRectOutLine(CRect rect, COLORREF color, int width, bool dot_line, BYTE alpha)
81+
{
82+
}
83+
84+
void CDrawCommonEx::DrawLine(CPoint start_point, int height, COLORREF color, BYTE alpha)
85+
{
86+
}
87+
88+
void CDrawCommonEx::SetTextColor(const COLORREF color, BYTE alpha)
89+
{
90+
m_text_color = CGdiPlusHelper::COLORREFToGdiplusColor(color, alpha);
91+
}
92+
93+
CDC* CDrawCommonEx::GetDC()
94+
{
95+
return m_pDC;
96+
}
97+
98+
int CDrawCommonEx::GetTextWidth(LPCTSTR lpszString)
99+
{
100+
Gdiplus::Font font(m_pDC->GetSafeHdc());
101+
Gdiplus::RectF textSize;
102+
m_pGraphics->MeasureString(lpszString, -1, &font, Gdiplus::PointF(0, 0), &textSize);
103+
return textSize.Width;
104+
}
105+
106+
void CDrawCommonEx::DrawBitmap(HBITMAP hbitmap, CPoint start_point, CSize size, StretchMode stretch_mode, BYTE alpha)
107+
{
108+
}
109+
110+
111+
/////////////////////////////////////////////////////////////////////////////////////////////
112+
/////////////////////////////////////////////////////////////////////////////////////////////
113+
Gdiplus::Color CGdiPlusHelper::COLORREFToGdiplusColor(COLORREF color, BYTE alpha /*= 255*/)
114+
{
115+
return Gdiplus::Color(alpha, GetRValue(color), GetGValue(color), GetBValue(color));
116+
}
117+
118+
COLORREF CGdiPlusHelper::GdiplusColorToCOLORREF(Gdiplus::Color color)
119+
{
120+
return RGB(color.GetR(), color.GetG(), color.GetB());
121+
}
122+
123+
CRect CGdiPlusHelper::GdiplusRectToCRect(Gdiplus::RectF rect)
124+
{
125+
return CRect(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
126+
}
127+
128+
Gdiplus::RectF CGdiPlusHelper::CRectToGdiplusRect(CRect rect)
31129
{
32-
m_pFont = pFont;
130+
return Gdiplus::RectF(rect.left, rect.top, rect.Width(), rect.Height());
33131
}

TrafficMonitor/DrawCommonEx.h

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
11
#pragma once
2-
class CDrawCommonEx
2+
#include "IDrawCommon.h"
3+
#include <gdiplus.h>
4+
5+
//使用GDI+的绘图类
6+
class CDrawCommonEx : public IDrawCommon
37
{
48
public:
5-
CDrawCommonEx(CDC* pDC);
6-
~CDrawCommonEx();
9+
CDrawCommonEx(CDC* pDC);
10+
CDrawCommonEx();
11+
~CDrawCommonEx();
12+
13+
void Create(CDC* pDC);
14+
void SetFont(CFont* pFont);
15+
Gdiplus::Graphics* GetGraphics() { return m_pGraphics; }
16+
17+
//绘制一个GDI+图像
18+
void DrawImage(Gdiplus::Image* pImage, CPoint start_point, CSize size, StretchMode stretch_mode);
719

8-
void DrawWindowText(CRect rect, LPCTSTR str, COLORREF color);
9-
void SetFont(CFont* pFont);
20+
// 通过 IDrawCommon 继承
21+
void SetBackColor(COLORREF back_color, BYTE alpha) override;
22+
void DrawWindowText(CRect rect, LPCTSTR lpszString, COLORREF color, Alignment align, bool draw_back_ground, bool multi_line, BYTE alpha) override;
23+
void SetDrawRect(CRect rect) override;
24+
void FillRect(CRect rect, COLORREF color, BYTE alpha) override;
25+
void DrawRectOutLine(CRect rect, COLORREF color, int width, bool dot_line, BYTE alpha) override;
26+
void DrawLine(CPoint start_point, int height, COLORREF color, BYTE alpha) override;
27+
void SetTextColor(const COLORREF color, BYTE alpha) override;
28+
void DrawBitmap(HBITMAP hbitmap, CPoint start_point, CSize size, StretchMode stretch_mode, BYTE alpha) override;
29+
virtual CDC* GetDC() override;
30+
virtual int GetTextWidth(LPCTSTR lpszString) override;
1031

1132
private:
12-
HTHEME hThm;
13-
CFont* m_pFont{};
14-
CDC* m_pDC{};
33+
CDC* m_pDC{};
34+
Gdiplus::Graphics* m_pGraphics{};
35+
Gdiplus::Color m_text_color{};
36+
Gdiplus::Color m_back_color{};
1537
};
1638

39+
class CGdiPlusHelper
40+
{
41+
public:
42+
static Gdiplus::Color COLORREFToGdiplusColor(COLORREF color, BYTE alpha = 255);
43+
static COLORREF GdiplusColorToCOLORREF(Gdiplus::Color color);
44+
static CRect GdiplusRectToCRect(Gdiplus::RectF rect);
45+
static Gdiplus::RectF CRectToGdiplusRect(CRect rect);
46+
};

TrafficMonitor/IDrawCommon.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ class IDrawCommon
3737
// 需要重新设置绘图剪辑区域,否则图片外的区域会无法绘制)
3838
virtual void DrawBitmap(HBITMAP hbitmap, CPoint start_point, CSize size, StretchMode stretch_mode = StretchMode::STRETCH, BYTE alpha = 255) = 0;
3939
virtual ~IDrawCommon() = default;
40+
41+
//获取绘图上下文句柄。仅在GDI或GDI+时有效
42+
virtual CDC* GetDC() { return nullptr; }
43+
//获取文本宽度
44+
virtual int GetTextWidth(LPCTSTR lpszString) { return 0; }
4045
};
4146

4247
namespace DrawCommonHelper

0 commit comments

Comments
 (0)