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

C# 建立不規則視窗:使用 GDI+ Region 實作自訂表單形狀

     編輯:關於C#

核心原理:SetWindowRgn + CreatePolygonRgn

Windows 允許視窗擁有非矩形區域(Region)。透過 gdi32.dll 的 CreatePolygonRgn 建立多邊形區域,再以 user32.dll 的 SetWindowRgn 套用至視窗控制代碼,即可實現任意形狀視窗。

完整程式碼

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace IrregularFormDemo
{
    public partial class Form1 : Form
    {
        [StructLayout(LayoutKind.Sequential)]
        private struct POINT { public int X, Y; }

        [DllImport("gdi32.dll")]
        private static extern IntPtr CreatePolygonRgn(ref POINT lpPoint, int nCount, int nPolyFillMode);

        [DllImport("user32.dll")]
        private static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, ref bool bRedraw);

        public Form1()
        {
            InitializeComponent();
            CreateIrregularShape();
        }

        private void CreateIrregularShape()
        {
            POINT[] pts = new POINT[5];
            pts[0] = new POINT { X = 90, Y = 90 };
            pts[1] = new POINT { X = Width, Y = 0 };
            pts[2] = new POINT { X = Width, Y = Height / 2 };
            pts[3] = new POINT { X = Width / 2, Y = Height / 2 };
            pts[4] = new POINT { X = 0, Y = Width }; // 注意:此處 Y=Width 可能為筆誤,建議改為 Height

            bool redraw = true;
            IntPtr hRgn = CreatePolygonRgn(ref pts[0], pts.Length, 1); // ALTERNATE 模式
            SetWindowRgn(Handle, hRgn, ref redraw);
            BackColor = Color.BurlyWood;
        }

        // 額外:置頂/取消置頂示範
        [DllImport("user32.dll")]
        private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int uFlags);

        private void btnTopMost_Click(object sender, EventArgs e)
            => SetWindowPos(Handle, -1, 0, 0, 0, 0, 1); // HWND_TOPMOST

        private void btnNormal_Click(object sender, EventArgs e)
            => SetWindowPos(Handle, -2, 0, 0, 0, 0, 0); // HWND_NOTOPMOST
    }
}

關鍵點補充

  • 多邊形頂點順序:須按順時針或逆時針排列,首尾不需重複。
  • 填充模式:CreatePolygonRgn 最後一個參數:1 = ALTERNATE(交替),2 = WINDING(繞數)。
  • 記憶體釋放:SetWindowRgn 成功後,系統擁有 Region,不可自行 DeleteObject,否則視窗會殘留舊區域。
  • 點擊穿透:若需點擊穿透非繪製區域,需處理 WM_NCHITTEST 回傳 HTTRANSPARENT。

進階:任意圖片形狀視窗

若要依據 PNG 透明通道生成 Region,可掃描每一行像素,將不透明區段加入 GraphicsPath,再 new Region(path) 套用至 Form.Region(Managed 方式),無需 P/Invoke。

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