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

C# WinForms 任意形狀窗體製作—— 心形窗體完整實現

     編輯:關於C#

繼字形窗體後,本文演示如何用同樣技術製作「心形」等任意非矩形窗體。核心同樣是 FormBorderStyle.None + TransparencyKey + OnPaint 繪製帶透明通道的圖片,區別僅在於素材圖片形狀不同。提供完整代碼、設計器配置、素材準備與拖動補丁。

一、核心代碼(僅 50 行)

using System;
using System.Drawing;
using System.Windows.Forms;

namespace ArbitraryShapeForm
{
    public partial class Form1 : Form
    {
        private Bitmap _shapeBmp;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 1. 載入心形圖片(建議 PNG 透明背景)
            _shapeBmp = new Bitmap("heart.png"); // 或 heart.bmp + MakeTransparent
            // _shapeBmp.MakeTransparent(Color.Magenta); // 若用 BMP,指定洋紅為透明色

            // 2. 窗體大小跟隨圖片
            this.ClientSize = _shapeBmp.Size;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.DrawImage(_shapeBmp, Point.Empty);
        }

        // 標籤作為關閉鍵(右上角小圓點)
        private void label1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        // 拖動無邊框窗體
        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);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && _shapeBmp != null)
                _shapeBmp.Dispose();
            base.Dispose(disposing);
        }
    }
}

二、設計器關鍵配置

private void InitializeComponent()
{
    this.label1 = new System.Windows.Forms.Label();
    this.SuspendLayout();
    // label1:關閉按鈕,置於心形右上曲線處
    this.label1.BackColor = Color.Transparent;
    this.label1.Location = new Point(280, 42);
    this.label1.Size = new Size(17, 16);
    this.label1.Click += label1_Click;

    this.AutoScaleDimensions = new SizeF(6F, 12F);
    this.AutoScaleMode = AutoScaleMode.Font;
    this.BackColor = SystemColors.Control;      // 必須與 TransparencyKey 一致
    this.ClientSize = new Size(393, 317);       // 會在 Load 中被圖片尺寸覆蓋
    this.Controls.Add(this.label1);
    this.FormBorderStyle = FormBorderStyle.None;
    this.Name = "Form1";
    this.StartPosition = FormStartPosition.CenterScreen;
    this.Text = "任意形狀窗體";
    this.TransparencyKey = SystemColors.Control; // 關鍵:將背景色設為透明
    this.Load += Form1_Load;
    this.ResumeLayout(false);
}

三、素材準備規範

格式透明方式優點缺點
PNG (32-bit)原生 Alpha 通道邊緣抗鋸齒完美、無需代碼處理文件稍大
BMP (24-bit)MakeTransparent(Color)無壓縮、載入快邊緣鋸齒、需純色背景
GIF單一透明色支持動畫256 色、邊緣鋸齒

建議:PS/AI 導出 PNG,背景勾選透明,邊緣羽化 0.5-1px,尺寸即窗體 ClientSize。

四、進階:點擊穿透控制

預設透明區域點擊會穿透到下層窗體。若需「只有心形區域可點擊」,兩種方案:

  1. Region 裁剪(簡單、無半透明支持):
    using System.Drawing.Drawing2D;
    // 在 Load 中
    GraphicsPath path = new GraphicsPath();
    path.AddEllipse(0, 0, _shapeBmp.Width, _shapeBmp.Height); // 簡易橢圓
    // 或用圖片非透明像素構建精確路徑(較複雜)
    this.Region = new Region(path);
  2. WS_EX_LAYERED + HitTest(支持半透明、漸變):
    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    const int GWL_EXSTYLE = -20;
    const int WS_EX_LAYERED = 0x80000;
    const int WS_EX_TRANSPARENT = 0x20;
    
    // 啟用分層窗體
    int exStyle = GetWindowLong(this.Handle, GWL_EXSTYLE);
    SetWindowLong(this.Handle, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
    // 設置透明度 200/255
    SetLayeredWindowAttributes(this.Handle, 0, 200, 2); // LWA_ALPHA

五、完整項目結構

HeartShapeForm/
├── Form1.cs
├── Form1.Designer.cs
├── Program.cs
├── Resources/
│   └── heart.png   // 32-bit PNG,透明背景
└── HeartShapeForm.csproj

六、總結

任意形狀窗體本質是「矩形窗體 + 透明色鍵 + 非矩形圖片繪製」。掌握 TransparencyKey、OnPaint、Region/Layered Window 三大技術點,即可實現從簡單心形到複雜遊戲啟動器皮膚的各種異形界面。記住:素材決定上限,代碼決定下限。

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