//////////////////////////////////////////////////////////////////////////
/// Hearder File
//////////////////////////////////////////////////////////////////////////
#pragma once
//////////////////////////////////////////////////////////////////////////
///GDI+ Common function interface
///Author:QuLonghui
///Date:2017-08-22
//////////////////////////////////////////////////////////////////////////
#include <Windows.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment(lib,"gdiplus.lib")
class CGDIEncapsulation
{
public:
CGDIEncapsulation();
~CGDIEncapsulation();
static CGDIEncapsulation * GetInstance();
private:
Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;
ULONG_PTR m_gdiplusToken;
static CGDIEncapsulation * m_pInstance;
public:
//////////////////////////////////////////////////////////////////////////
/// Rectangle Relevant
//////////////////////////////////////////////////////////////////////////
// Transparent rectangle
void DrawTransparentRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_colorPen, int a_iPenWid);
// Translucent rectangle
void DrawTranslucentRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_colorBrush, int a_iAlpha);
// LinearGradient rectangle
void DrawLinearGradientRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_color1, COLORREF a_color2, int a_iAlpha, int a_iDirect);
// RoundRectangle
void DrawRoundRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_colorPen, int a_iPenWid = 1, int a_iOffset = 10);
// FillRoundRectangle
void FillRoundRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_colorBrush, int a_iOffset = 10);
////////////////////////////////////////////////////////////////
/// Draw Image
/// RotateFlipType:0-不旋转不翻转、1-旋转90度不翻转、2-旋转180度不翻转、
/// 3-旋转270度不翻转、4-不旋转水平翻转、5-旋转90度水平翻转、
/// 6-旋转180度水平翻转、7-旋转270度水平翻转
//////////////////////////////////////////////////////////////////////////
void DrawImage(HDC a_hDC, const WCHAR* a_sImgPath, RECT a_rDest, int a_iRotateFlipType = 0);
//////////////////////////////////////////////////////////////////////////
/// Text & Font
/// FontStyle : 0-常规、1-加粗、2-斜体、3-粗斜、4-下划线、8-强调线,即在字体中部画线
/// ShowDirect : 0:水平方向、1:垂直方向
/// Alignment : 0-靠近(对于水平对齐来说是居左对齐,对于垂直而言是居上)、
/// 1-靠中
/// 2-靠远
/// a_iSrcLine : 计算字符串显示行数并显示第SrcLine行开始的文字
//////////////////////////////////////////////////////////////////////////
void ShowText(HDC a_hDC, const WCHAR* a_sText, RECT a_rDest, COLORREF a_fontColor, int a_iFontSize, int a_iFontStyle = 0,
int a_iShowDirect = 0, int a_iAlignment = 0, const WCHAR * a_sFontType = L"Arial", unsigned int a_iSrcLine = 0);
};
////////////////////////////////////////////////////////////////////////
/// CPP FILE
///////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GDIEncapsulation.h"
CGDIEncapsulation * CGDIEncapsulation::m_pInstance = NULL;
CGDIEncapsulation::CGDIEncapsulation()
{
Gdiplus::GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
}
CGDIEncapsulation::~CGDIEncapsulation()
{
//delete gdi+ object before
Gdiplus::GdiplusShutdown(m_gdiplusToken);
}
CGDIEncapsulation * CGDIEncapsulation::GetInstance()
{
if (NULL == m_pInstance)
{
m_pInstance = new CGDIEncapsulation();
}
return m_pInstance;
}
void CGDIEncapsulation::DrawTransparentRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_colorPen, int a_iPenWid)
{
Gdiplus::Graphics graphics(a_hDC);
Color colorPen(GetRValue(a_colorPen), GetGValue(a_colorPen), GetBValue(a_colorPen));
Pen pen(colorPen, Gdiplus::REAL(a_iPenWid));
graphics.DrawRectangle(&pen, a_iX, a_iY, a_iWidth, a_iHeight);
}
void CGDIEncapsulation::DrawTranslucentRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_colorBrush, int a_iAlpha)
{
Gdiplus::Graphics graphics(a_hDC);
SolidBrush brush(Color((BYTE)a_iAlpha, GetRValue(a_colorBrush), GetGValue(a_colorBrush), GetBValue(a_colorBrush)));
graphics.FillRectangle(&brush, RectF(Gdiplus::REAL(a_iX), Gdiplus::REAL(a_iY), Gdiplus::REAL(a_iWidth), Gdiplus::REAL(a_iHeight)));
}
void CGDIEncapsulation::DrawLinearGradientRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_color1, COLORREF a_color2, int a_iAlpha, int a_iDirect)
{
Gdiplus::Graphics graphics(a_hDC);
PointF pnt1, pnt2;
pnt1 = PointF(Gdiplus::REAL(a_iX), Gdiplus::REAL(a_iY));
switch (a_iDirect)
{
case 0:
{
pnt2 = PointF(Gdiplus::REAL(a_iX + a_iWidth), Gdiplus::REAL(a_iY));
break;
}
case 1:
{
pnt2 = PointF(Gdiplus::REAL(a_iX), Gdiplus::REAL(a_iY + a_iHeight));
break;
}
case 2:
{
pnt2 = PointF(Gdiplus::REAL(a_iX + a_iWidth), Gdiplus::REAL(a_iY + a_iHeight));
break;
}
default:
{
pnt2 = PointF(Gdiplus::REAL(a_iX + a_iWidth), Gdiplus::REAL(a_iY));
break;
}
}
Color color1((BYTE)a_iAlpha, GetRValue(a_color1), GetGValue(a_color1), GetBValue(a_color1));
Color color2((BYTE)a_iAlpha, GetRValue(a_color2), GetGValue(a_color2), GetBValue(a_color2));
LinearGradientBrush lgBrush(pnt1, pnt2, color1, color2);
graphics.FillRectangle(&lgBrush, a_iX, a_iY, a_iWidth, a_iHeight);
}
void CGDIEncapsulation::DrawRoundRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_colorPen, int a_iPenWid, int a_iOffset)
{
Gdiplus::Graphics graphics(a_hDC);
//设置滤波模式为消除锯齿现象
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
Color colPen(GetRValue(a_colorPen), GetGValue(a_colorPen), GetBValue(a_colorPen));
Pen * pen = new Pen(colPen, Gdiplus::REAL(a_iPenWid));
graphics.DrawLine(pen, a_iX + a_iOffset, a_iY, a_iX + a_iWidth - a_iOffset, a_iY);
graphics.DrawLine(pen, a_iX + a_iWidth, a_iY + a_iOffset, a_iX + a_iWidth, a_iY + a_iHeight - a_iOffset);
graphics.DrawLine(pen, a_iX + a_iOffset, a_iY + a_iHeight, a_iX + a_iWidth - a_iOffset, a_iY + a_iHeight);
graphics.DrawLine(pen, a_iX, a_iY + a_iOffset, a_iX, a_iY + a_iHeight - a_iOffset);
graphics.DrawArc(pen, a_iX, a_iY, a_iOffset * 2, a_iOffset * 2, 180, 90);
graphics.DrawArc(pen, a_iX + a_iWidth - a_iOffset * 2, a_iY, a_iOffset * 2, a_iOffset * 2, 270, 90);
graphics.DrawArc(pen, a_iX + a_iWidth - a_iOffset * 2, a_iY + a_iHeight - a_iOffset * 2, a_iOffset * 2, a_iOffset * 2, 0, 90);
graphics.DrawArc(pen, a_iX, a_iY + a_iHeight - a_iOffset * 2, a_iOffset * 2, a_iOffset * 2, 90, 90);
delete pen;
}
void CGDIEncapsulation::FillRoundRectangle(HDC a_hDC, int a_iX, int a_iY, int a_iWidth, int a_iHeight, COLORREF a_colorBrush, int a_iOffset)
{
Gdiplus::Graphics graphics(a_hDC);
Color colBrush(GetRValue(a_colorBrush), GetGValue(a_colorBrush), GetBValue(a_colorBrush));
SolidBrush brush(colBrush);
graphics.FillRectangle(&brush, a_iX, a_iY + a_iOffset, a_iWidth, a_iHeight - a_iOffset * 2);
graphics.FillRectangle(&brush, a_iX + a_iOffset, a_iY, a_iWidth - a_iOffset * 2, a_iHeight);
graphics.FillPie(&brush, a_iX, a_iY, a_iOffset * 2, a_iOffset * 2, 180, 90);
graphics.FillPie(&brush, a_iX + a_iWidth - 2 * a_iOffset, a_iY, a_iOffset * 2, a_iOffset * 2, 270, 90);
graphics.FillPie(&brush, a_iX + a_iWidth - 2 * a_iOffset, a_iY + a_iHeight - 2 * a_iOffset, a_iOffset * 2, a_iOffset * 2, 0, 90);
graphics.FillPie(&brush, a_iX, a_iY + a_iHeight - 2 * a_iOffset, a_iOffset * 2, a_iOffset * 2, 90, 90);
DrawRoundRectangle(a_hDC, a_iX, a_iY, a_iWidth, a_iHeight, a_colorBrush, 1, a_iOffset);
}
void CGDIEncapsulation::DrawImage(HDC a_hDC, const WCHAR* a_sImgPath, RECT a_rDest, int a_iRotateFlipType)
{
Gdiplus::Graphics graphics(a_hDC);
graphics.SetInterpolationMode(InterpolationModeBilinear); //双线性插值
Image image(a_sImgPath);
RectF destRect(Gdiplus::REAL(a_rDest.left), Gdiplus::REAL(a_rDest.top),
Gdiplus::REAL(a_rDest.right - a_rDest.left), Gdiplus::REAL(a_rDest.bottom - a_rDest.top));
//旋转和翻转
RotateFlipType rfType;
switch (a_iRotateFlipType)
{
case 0:
rfType = RotateNoneFlipNone;
break;
case 1:
rfType = Rotate90FlipNone;
break;
case 2:
rfType = Rotate180FlipNone;
break;
case 3:
rfType = Rotate270FlipNone;
break;
case 4:
rfType = RotateNoneFlipX;
break;
case 5:
rfType = Rotate90FlipX;
break;
case 6:
rfType = Rotate180FlipX;
break;
case 7:
rfType = Rotate270FlipX;
break;
default:
rfType = RotateNoneFlipNone;
break;
}
image.RotateFlip(rfType);
graphics.DrawImage(&image, destRect);
}
void CGDIEncapsulation::ShowText(HDC a_hDC, const WCHAR* a_sText, RECT a_rDest, COLORREF a_fontColor, int a_iFontSize,
int a_iFontStyle, int a_iShowDirect, int a_iAlignment, const WCHAR * a_sFontType, unsigned int a_iSrcLine)
{
int strlen = (int)wcslen(a_sText);
if (strlen <= 0) return;
Gdiplus::Graphics graphics(a_hDC);
FontFamily fontFamily(a_sFontType);
FontStyle fontStyle;
switch (a_iFontStyle)
{
case 0:
fontStyle = FontStyleRegular;
break;
case 1:
fontStyle = FontStyleBold;
break;
case 2:
fontStyle = FontStyleItalic;
break;
case 3:
fontStyle = FontStyleBoldItalic;
break;
case 4:
fontStyle = FontStyleUnderline;
break;
case 8:
fontStyle = FontStyleStrikeout;
break;
default:
fontStyle = FontStyleRegular;
break;
}
Gdiplus::Font font(&fontFamily, Gdiplus::REAL(a_iFontSize), fontStyle, UnitPixel);
Color colorBrush(GetRValue(a_fontColor), GetGValue(a_fontColor), GetBValue(a_fontColor));
SolidBrush solidbrush(colorBrush);
graphics.SetTextRenderingHint(TextRenderingHintSystemDefault); //字体边缘平滑处理(使用系统相同的处理方式)
StringFormat strformat;
if (1 == a_iShowDirect)
{
strformat.SetFormatFlags(StringFormatFlagsDirectionVertical | StringFormatFlagsDirectionRightToLeft);
}
StringAlignment align;
switch (a_iAlignment)
{
case 0:
align = StringAlignmentNear;
break;
case 1:
align = StringAlignmentCenter;
break;
case 2:
align = StringAlignmentFar;
break;
default:
align = StringAlignmentNear;
break;
}
strformat.SetAlignment(align);
strformat.SetLineAlignment(align);
strformat.SetTrimming(StringTrimmingEllipsisPath);
RectF destRect(Gdiplus::REAL(a_rDest.left), Gdiplus::REAL(a_rDest.top),
Gdiplus::REAL(a_rDest.right - a_rDest.left), Gdiplus::REAL(a_rDest.bottom - a_rDest.top));
RectF layoutRect(Gdiplus::REAL(a_rDest.left), Gdiplus::REAL(a_rDest.top), Gdiplus::REAL(a_rDest.right - a_rDest.left), 0);
RectF boundRect;
INT codePointsFitted = 0;
INT linesFitted = 0;
graphics.MeasureString(a_sText, strlen, &font, layoutRect, NULL, &boundRect, &codePointsFitted, &linesFitted);
if (linesFitted == 1)
{
graphics.DrawString(a_sText, strlen, &font, destRect, &strformat, &solidbrush);
}
else
{
int iWidPerLine = codePointsFitted / linesFitted;
int iMode = codePointsFitted % linesFitted;
if (iMode > 0)
{
iWidPerLine += 1;
}
if (a_iSrcLine >= (unsigned int)(linesFitted - 1))
{
a_iSrcLine = (unsigned int)(linesFitted - 1);
}
int iIndex = a_iSrcLine*iWidPerLine;
if (iIndex >= codePointsFitted)
{
iIndex = codePointsFitted - 1;
}
int iShowLen = codePointsFitted - iIndex;
graphics.DrawString(a_sText + iIndex, iShowLen, &font, destRect, NULL, &solidbrush);
}
}