.NET Framework (WinForms) 讓按鈕自繪變得異常簡單:用 GraphicsPath 定義形狀 (如圓形)、設定 Region 屬性即可實現非矩形按鈕,配合 MouseEnter/Leave/Down/Up 事件切換背景色/圖片,無需複雜的 WM_PAINT/DrawItem 手動繪圖。本文展示 VC.NET (C++/CLI) 實現圓形按鈕的極簡代碼。

private: System::Void Form1_Load(System::Object* sender, System::EventArgs* e)
{
// 1. 建立圖形路徑:畫橢圓 (圓形)
System::Drawing::Drawing2D::GraphicsPath* path = new GraphicsPath();
path->AddEllipse(Rectangle(10, 10, 80, 80)); // 相對按鈕客戶區座標
// 2. 路徑轉區域,賦予按鈕
System::Drawing::Region* reg = new Region(path);
button1->Bounds = Rectangle(50, 50, 100, 100); // 按鈕螢幕位置與最大響應矩形
button1->Region = reg; // 關鍵:實際可見/可點擊區域變為圓形
// 注意:Bounds 必須為矩形 (佈局用),Region 可為任意形狀 (點擊/繪製用)
}
// 3. 事件驅動狀態視覺切換 (極簡,無需手動 Invalidate/Repaint)
private: System::Void button1_MouseDown(Object* sender, MouseEventArgs* e)
{
button1->Image = Image::FromFile("bitmap.bmp"); // 按下顯示圖片
}
private: System::Void button1_MouseUp(Object* sender, MouseEventArgs* e)
{
button1->BackColor = SystemColors::AppWorkspace; // 彈起背景色
button1->Image = nullptr;
}
private: System::Void button1_MouseEnter(Object* sender, EventArgs* e)
{
button1->BackColor = SystemColors::AppWorkspace; // 滑鼠進入背景色
button1->Image = nullptr;
}
private: System::Void button1_MouseLeave(Object* sender, EventArgs* e)
{
button1->BackColor = SystemColors::ActiveBorder; // 滑鼠離開背景色
button1->Image = nullptr;
}
| 維度 | MFC (C++) | .NET WinForms (C++/CLI 或 C#) |
|---|---|---|
| 非矩形區域 | CRgn::CreateRoundRectRgn + SetWindowRgn + OnEraseBkgnd 抑制 | GraphicsPath + Control.Region 屬性 (一行搞定) |
| 狀態繪製 | DrawItem + DRAWITEMSTRUCT 手寫狀態機 | 事件處理器 (MouseEnter 等) 直接設屬性 (BackColor, Image) |
| 焦點虛線框 | 手寫 DrawFocusRect | 控制項自動處理 (可覆寫 OnPaint 客製) |
| 雙重緩衝 | 手寫 CMemDC | 控制項預設開啟 DoubleBuffered |
| 字體/文字渲染 | LOGFONT + CFont + TextOut | Font 物件 + DrawString (支援 GDI+ 清晰度) |
GotFocus/LostFocus 事件中切換含虛線框的圖片或覆寫 OnPaint 繪製。CBitmapButton 使用也相對簡單,但其他控制項 (ListView, TreeView 等) 自繪仍較繁瑣。