首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# WinForms 打造非矩形字形窗體完整指南

     編輯:關於C#

Windows 預設窗體永遠是矩形,但許多炫酷應用(如音樂播放器皮膚、啟動畫面、浮動工具)都需要「異形窗體」。本文詳細講解如何利用 TransparencyKey、FormBorderStyle.None 以及重寫 OnPaint 繪製位圖,輕鬆實現任意形狀、甚至字形窗體,並提供完整可運行代碼。

一、核心原理三步走

  1. 移除邊框:FormBorderStyle = FormBorderStyle.None
  2. 指定透明色:TransparencyKey = BackColor,將背景色設為透明
  3. 繪製不規則圖像:重寫 OnPaint,用 Graphics.DrawImage 畫載入的 PNG/BMP,圖像中透明色區域即成「挖空」效果

二、設計器代碼關鍵點

private void InitializeComponent()
{
    this.label1 = new System.Windows.Forms.Label();
    this.SuspendLayout();
    // label1:作為關閉按鈕,背景透明
    this.label1.BackColor = System.Drawing.Color.Transparent;
    this.label1.Location = new System.Drawing.Point(261, 56);
    this.label1.Size = new System.Drawing.Size(17, 16);
    this.label1.Click += new System.EventHandler(this.label1_Click);

    // Form1 關鍵屬性
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.BackColor = System.Drawing.SystemColors.Control;   // 必須與 TransparencyKey 一致
    this.ClientSize = new System.Drawing.Size(393, 317);
    this.Controls.Add(this.label1);
    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; // 無邊框
    this.Name = "Form1";
    this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
    this.Text = "非矩形窗體";
    this.TransparencyKey = System.Drawing.SystemColors.Control; // 透明色鍵
    this.Load += new System.EventHandler(this.Form1_Load);
    this.ResumeLayout(false);
}

三、核心業務邏輯代碼

public partial class Form1 : Form
{
    private Bitmap _shapeBitmap;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // 1. 載入圖片(建議 PNG 透明通道,或 BMP + MakeTransparent)
        _shapeBitmap = new Bitmap("wordImage.bmp");
        // 2. 若用 BMP,指定藍色為透明色(圖片設計時背景填純藍 #0000FF)
        _shapeBitmap.MakeTransparent(Color.Blue);

        // 3. 讓窗體大小跟隨圖片(可選)
        this.ClientSize = _shapeBitmap.Size;
    }

    // 4. 核心:重寫 OnPaint 繪製圖片
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.DrawImage(_shapeBitmap, Point.Empty);
    }

    // 5. 標籤點擊關閉窗體
    private void label1_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    // 6. 釋放資源
    protected override void Dispose(bool disposing)
    {
        if (disposing && _shapeBitmap != null)
            _shapeBitmap.Dispose();
        base.Dispose(disposing);
    }
}

四、圖片素材準備技巧

  • 推薦 PNG:原生支持 Alpha 通道,邊緣抗鋸齒自然,無需 MakeTransparent。
  • 若用 BMP:背景填滿純藍 (RGB(0,0,255)),代碼中 MakeTransparent(Color.Blue)。
  • 尺寸建議:圖片寬高即窗體 ClientSize,避免拉伸失真。

五、進階:拖動無邊框窗體

無標題欄後無法拖動,需攔截 WM_NCHITTEST:

protected override void WndProc(ref Message m)
{
    const int WM_NCHITTEST = 0x84;
    const int HTCLIENT = 1;
    const int HTCAPTION = 2;

    if (m.Msg == WM_NCHITTEST)
    {
        base.WndProc(ref m);
        if ((int)m.Result == HTCLIENT)
            m.Result = (IntPtr)HTCAPTION; // 告訴系統這是標題欄,可拖動
        return;
    }
    base.WndProc(ref m);
}

六、常見坑點速查

現象原因解決
窗體顯示為矩形TransparencyKey 與 BackColor 不一致兩者設為同一顏色
圖片邊緣鋸齒明顯用 BMP + MakeTransparent,邊緣無半透明改用 PNG 32位帶 Alpha 通道
點擊穿透(點不到控件)透明區域被視為「不存在」在透明區放置透明 Label/Panel 接收點擊,或用 Region 裁剪
高 DPI 模糊圖片未按 DPI 縮放啟用 SetProcessDpiAwareness 或提供多倍圖

七、完整項目結構

IrregularFormDemo/
├── Form1.cs           // 主窗體邏輯
├── Form1.Designer.cs  // 設計器代碼
├── Program.cs         // 入口
├── Resources/
│   └── wordImage.png  // 字形圖片(建議 PNG)
└── IrregularFormDemo.csproj

八、總結

掌握 TransparencyKey + OnPaint 組合,即可打造任意形狀窗體。進階可結合 Region、Layered Window (WS_EX_LAYERED) 實現半透明、漸變、點擊穿透控制等更豐富效果。本文代碼已在 .NET Framework 4.8 / .NET 6+ WinForms 驗證通過,直接複製即用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved