GDI+ 是 GDI 後繼者,整合於 .NET Framework,安裝 .NET Framework 後 Win98/2000/XP 皆可使用。本文示範在對話框 OnEraseBkgnd 中用 GDI+ 繪製角度可調的線性漸層,涵蓋兩色與三色漸層。
// 標頭檔
#include
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
// 成員變數
ULONG_PTR m_gdiplusToken; // GDI+ 啟動權杖
int m_nRotation; // 漸層角度 (0-360)
COLORREF m_clr1, m_clr2, m_clr3; // 三色 RGB 值
// 初始化 (OnInitDialog 或建構函數)
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
// 清理 (OnDestroy 或解構函數)
GdiplusShutdown(m_gdiplusToken);
BOOL CTestDlg::OnEraseBkgnd(CDC* pDC)
{
CDialog::OnEraseBkgnd(pDC);
// 1. 取得 RGB 分量
int r1 = GetRValue(m_clr1), g1 = GetGValue(m_clr1), b1 = GetBValue(m_clr1);
int r2 = GetRValue(m_clr2), g2 = GetGValue(m_clr2), b2 = GetBValue(m_clr2);
// 2. 客戶區矩形
CRect rect;
GetClientRect(&rect);
// 3. GDI+ Graphics 物件
Graphics graphics(pDC->GetSafeHdc());
// 4. 線性漸層刷子:矩形區域、起始色、結束色、角度
LinearGradientBrush brush(
Rect(0, 0, rect.Width(), rect.Height()),
Color(255, r1, g1, b1),
Color(255, r2, g2, b2),
(REAL)(90 - m_nRotation)); // GDI+ 0度向右,扣90度符合直覺
// 5. 填滿矩形
graphics.FillRectangle(&brush, Rect(0, 0, rect.Width(), rect.Height()));
return TRUE;
}
原理:對角線長度三等分,前半段 Color1→Color2,後半段 Color2→Color3,繪製到位圖再以旋轉矩陣繪製到螢幕。
BOOL CTestDlg::OnEraseBkgnd(CDC* pDC)
{
CDialog::OnEraseBkgnd(pDC);
int r1 = GetRValue(m_clr1), g1 = GetGValue(m_clr1), b1 = GetBValue(m_clr1);
int r2 = GetRValue(m_clr2), g2 = GetGValue(m_clr2), b2 = GetBValue(m_clr2);
int r3 = GetRValue(m_clr3), g3 = GetGValue(m_clr3), b3 = GetBValue(m_clr3);
CRect rect;
GetClientRect(&rect);
int w = rect.Width(), h = rect.Height();
// 對角線長度
double diag = sqrt((double)w*w + (double)h*h);
// 三塊繪製矩形 (以對角線為基準)
Rect rectFull(0, 0, (INT)diag, (INT)diag);
Rect rectTop(0, 0, (INT)diag, (INT)(diag/2));
Rect rectBottom(0, (INT)(diag/2), (INT)diag, (INT)(diag/2));
// 離屏位圖合成漸層
Bitmap bmp(rectFull.Width, rectFull.Height);
Graphics grTmp(&bmp);
// 上半段 Color1→Color2 (90度 = 垂直)
LinearGradientBrush brush1(rectTop, Color(r1,g1,b1), Color(r2,g2,b2), 90);
grTmp.FillRectangle(&brush1, rectTop);
// 下半段 Color2→Color3
LinearGradientBrush brush2(rectBottom, Color(r2,g2,b2), Color(r3,g3,b3), 90);
grTmp.FillRectangle(&brush2, rectBottom);
// 旋轉變換計算
double angle = m_nRotation * 3.1415926 / 180.0;
double cosA = cos(angle), sinA = sin(angle);
double beta = atan2((double)h, (double)w);
double dist = (diag * 0.5) * sin(fabs(angle) + beta);
double xc = 0.5*w - dist*sinA;
double yc = 0.5*h - dist*cosA;
double xc1 = 0.5*w + dist*sinA;
double yc1 = 0.5*h + dist*cosA;
double dx = diag * 0.5 * cosA;
double dy = -diag * 0.5 * sinA;
// 目標平行四邊形三頂點
Point pts[3];
pts[0] = Point((INT)(xc - dx), (INT)(yc - dy));
pts[1] = Point((INT)(xc + dx), (INT)(yc + dy));
pts[2] = Point((INT)(xc1 - dx), (INT)(yc1 - dy));
Graphics graphics(pDC->GetSafeHdc());
graphics.DrawImage(&bmp, pts, 3);
return TRUE;
}
| 類別/方法 | 用途 |
|---|---|
| GdiplusStartup / GdiplusShutdown | 進程級初始化與清理,必須配對 |
| Graphics(hdc) | 繪圖表面封裝,所有繪圖透過此物件 |
| LinearGradientBrush | 線性漸層刷子,支援角度、多色停駐點 |
| Color(alpha, r, g, b) | 32-bit ARGB 顏色結構 |
| Rect / Point | GDI+ 整數座標矩形/點 |
| Bitmap | 離屏位圖,支援合成後再變換繪製 |
| DrawImage(bmp, pts, 3) | 以平行四邊形三頂點繪製位圖 (含旋轉/縮放/傾斜) |
GDI+ 讓 VC++ 輕鬆實現專業級漸層背景。兩色漸層直接用 LinearGradientBrush 角度參數;三色漸層需離屏合成 + 幾何變換。將角度參數綁定滑桿即可做出即時調整的炫酷背景效果。