C++/CLI (Managed C++) 結合 **GDI+** (System.Drawing) 提供強大的向量繪圖能力。本文示範在 Windows Forms 控件 Paint 事件中,使用 **線性漸層畫刷** 、**網格畫刷** 繪製特效文字,涵蓋 Graphics 取得、字體建立、文字測量、畫刷實例化、背景填充、DrawString 繪製完整流程。
Paint 事件處理函數中繪製 (確保重繪正確)。PaintEventArgs.Graphics 取得 **永久有效** 的 Graphics 物件 (勿用 CreateGraphics)。Font 物件 (字體名、大小、樣式)。Graphics.MeasureString 測量文字尺寸 (SizeF)。HatchBrush (網格) 或 LinearGradientBrush (漸層)。Graphics.Clear 或 FillRectangle。Graphics.DrawString 繪製文字 (指定畫刷、字體、位置)。
#pragma once
using namespace System;
using namespace System::Drawing;
using namespace System::Drawing::Drawing2D;
using namespace System::Windows::Forms;
namespace GDIPlusTextDemo {
public ref class TextDisplayControl : public PictureBox
{
public:
property String^ TextToDisplay {
String^ get() { return textToDisplay; }
void set(String^ value) { textToDisplay = value; Invalidate(); }
}
property Font^ DisplayFont {
Font^ get() { return displayFont; }
void set(Font^ value) { displayFont = value; Invalidate(); }
}
property BrushType BrushType { // 自訂列舉
BrushType get() { return brushType; }
void set(BrushType value) { brushType = value; Invalidate(); }
}
protected:
virtual void OnPaint(PaintEventArgs^ e) override
{
PictureBox::OnPaint(e);
Graphics^ g = e->Graphics; // 關鍵:使用事件提供的 Graphics
if (String::IsNullOrEmpty(textToDisplay) || displayFont == nullptr) return;
// 1. 測量文字尺寸
SizeF textSize = g->MeasureString(textToDisplay, displayFont);
// 2. 建立畫刷
Brush^ brush;
if (brushType == BrushType::Hatch) {
brush = gcnew HatchBrush(HatchStyle::Cross, Color::Black, Color::Blue);
} else { // LinearGradient
RectangleF rect(0, 0, textSize.Width, textSize.Height);
brush = gcnew LinearGradientBrush(rect, Color::Black, Color::Blue,
LinearGradientMode::ForwardDiagonal);
}
// 3. 填充背景 (示範兩種方式)
// g->Clear(Color::White); // 簡單全域填充
g->FillRectangle(SystemBrushes::Control, 0, 0, this->Width, this->Height); // 系統控件色
// 4. 置中繪製文字
float x = (this->Width - textSize.Width) / 2;
float y = (this->Height - textSize.Height) / 2;
g->DrawString(textToDisplay, displayFont, brush, x, y);
}
private:
String^ textToDisplay = "GDI+ Special Text";
Font^ displayFont = gcnew Font("Times New Roman", 20, FontStyle::Regular);
enum class BrushType { Hatch, LinearGradient };
BrushType brushType = BrushType::LinearGradient;
};
}
| 類別/方法 | 命名空間 | 用途 |
|---|---|---|
Graphics | System::Drawing | 繪圖介面,對應 HDC |
Font | System::Drawing | 字體 (名稱、大小、樣式) |
MeasureString | Graphics | 回傳 SizeF 文字繪製範圍 |
HatchBrush | System::Drawing::Drawing2D | 網格/斜線/十字等圖案填充 |
LinearGradientBrush | System::Drawing::Drawing2D | 線性漸層 (雙色、多色、路徑漸層) |
SolidBrush | System::Drawing | 純色填充 |
TextureBrush | System::Drawing | 圖片紋理填充 |
DrawString | Graphics | 繪製文字 (支援畫刷、字體、格式) |
FillRectangle | Graphics | 填充矩形 (支援任意畫刷) |
SystemBrushes | System::Drawing | 系統預設畫刷 (Control, Window, Highlight 等) |
StringFormat 設定對齊、換行、省略號、數位替換等。g->DrawString(text, font, brush, rect, format)。g->TextRenderingHint = TextRenderingHint::AntiAliasGridFit (或 ClearTypeGridFit)。PathGradientBrush 依 GraphicsPath 形狀產生放射/自定漸層。SetProcessDPIAware 即可正確縮放。
#include
#pragma comment(lib, "gdiplus.lib")
// 初始化 (App 啟動)
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartupInput input;
Gdiplus::GdiplusStartup(&gdiplusToken, &input, NULL);
// 繪製 (OnPaint)
void CMyView::OnPaint()
{
CPaintDC dc(this);
Gdiplus::Graphics g(dc.m_hDC);
Gdiplus::Font font(L"Times New Roman", 20);
Gdiplus::SolidBrush brush(Gdiplus::Color(255, 0, 0, 255)); // ARGB
g.DrawString(L"GDI+ Text", -1, &font, Gdiplus::PointF(10,10), &brush);
}
// 關閉 (App 結束)
Gdiplus::GdiplusShutdown(gdiplusToken);
GDI+ 提供豐富的**畫刷體系** (漸層、網格、紋理) 讓文字繪製極具表現力。關鍵在於:**在 Paint 事件中使用 e->Graphics**、**正確測量尺寸**、**選擇適合的畫刷**。Managed C++ (C++/CLI) 程式碼極簡潔;原生 MFC 亦可透過 Gdiplus.h 直接呼叫,僅需手動管理啟動/關閉與 Graphics 建構。