C#制作不规则窗口 ( 24bit Color 以上适用 )

    技术2022-05-11  92

    C#制作不规则窗口 ( 24bit Color 以上适用 )時間: 2004/3/17作者: Robert參考: http://www.codeproject.com/csharp/bmprgnform.asp?target=region電郵: zsc771120@yahoo.com.cn關鍵字: Region Gif 不規則 窗口 視窗 GraphicsPath 按鈕 圖片 Form Button目的: 幫助受 C# 不規則窗口困擾的人介紹這篇文章說明怎麼製作圖片按鈕和窗體. Region 技術不但能做不規則窗口, 也能做不規則控件外觀, 比

    如說不規則按鈕.程序介紹說明: 我修改程序介紹中的注釋, 不修改程序列表的說明. 畢竟 E 文我們看起來沒有中文舒服.1. 主函數說明下面的程序用倆個主函數產生 位圖區域 (bitmap regionss ), 源代碼放在 BitmapRegion.cs中, 你可

    以直接導入這個類別, 使用裡面的函數.

    // Create and apply the given bitmap region on the supplied control// 產生支持位圖區域 ( bitmap region ) 控件public static void CreateControlRegion(Control control, Bitmap bitmap){    // 如果控件或者位圖不存在, 直接返回.    if(control == null || bitmap == null)        return;                // 根據位圖大小設置控件尺寸    control.Width = bitmap.Width;    control.Height = bitmap.Height;

        // 處理 窗體 ( Form ) 類別    if(control is System.Windows.Forms.Form)    {        // 強制轉換 control object 到 Form object        Form form = (Form)control;

            // 由於我們的Form邊界類型 ( Form.FormBorderStyle ) 不是 None,         // 所以我們的Form尺寸比位圖大一點        form.Width += 15;        form.Height += 35;                // 設定 Form 邊界類型是 None        form.FormBorderStyle = FormBorderStyle.None;

            // 設定 Form 背景圖片        form.BackgroundImage = bitmap;

            // 計算圖片中不透明部分的邊界 (建議用 Gif 圖片 )        GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);

            // 建立區域 ( Region )        form.Region = new Region(graphicsPath);    }

        // 處理按鈕 ( button 類別 )    else if(control is System.Windows.Forms.Button)    {        // control object 轉成 Button object 類別        Button button = (Button)control;

            // 清除 Button 上面的文字        button.Text = "";                        // 更改鼠標樣式是手狀鼠標        button.Cursor = Cursors.Hand;

            // 設定背景圖樣        button.BackgroundImage = bitmap;                        //計算圖片中不透明部分的邊界 (建議用 Gif 圖片 )        GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);

            // 建立區域 ( Region )        button.Region = new Region(graphicsPath);    }        // 這裡你可以模仿 Form 或者 Button 建立心的類別出歷程序, 比如Panel}

    // 計算圖片不透明區域 返回 GraphicsPath private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap){    // 建立GraphicsPath, 給我們的位圖路徑計算使用    GraphicsPath graphicsPath = new GraphicsPath();

        // 使用左上角 (0,0) 點作為透明色    // 如果這裡是紅色, 那麼我們計算是圖片中不包含紅色區域路徑    Color colorTransparent = bitmap.GetPixel(0, 0);

        // 存儲第一個不透明點, 這個值決定我們開始檢查不透明區域.    int colOpaquePixel = 0;

        // 檢查所有的行 ( Y axis )    for(int row = 0; row < bitmap.Height; row ++)    {        // 重置 colOpaquePixel 值        colOpaquePixel = 0;

            // 檢查所有的列 ( X axis )        for(int col = 0; col < bitmap.Width; col ++)        {            // 如果是不透明點, 標記之後尋這個點之後的位置            if(bitmap.GetPixel(col, row) != colorTransparent)            {                // 找到不透明點, 標記這個位置                colOpaquePixel = col;

                    // 建立新變量保存當前點位置                int colNext = col;

                    // 從找到的不透明點開始繼續搜索不透明點,                 //一直到找到透明點 或者 找到圖片寬度搜索完畢                for(colNext=colOpaquePixel; colNext<bitmap.Width; colNext++)                    if(bitmap.GetPixel(colNext, row) == colorTransparent)                        break;

                    // 把不透明區域加入我們的GraphicsPath                graphicsPath.AddRectangle(new Rectangle(colOpaquePixel,                                            row, colNext - colOpaquePixel, 1));

                    // 找到之後不用搜索不透明點                col = colNext;            }        }    }

        // 返回計算出來的不透明圖片路徑    return graphicsPath;}產生不規則窗體下面這倆行代碼能產生不規則圖形. 你不必改變 Form.FormBorderStyle是None, 程序自己幫你做這件事

    .public class Form1 : System.Windows.Forms.Form{    // 導入背景圖片    private Bitmap bmpFrmBack = new Bitmap(typeof(Form1), "back.bmp");

        public Form1()    {        InitializeComponent();

            // 讓你的床體透明吧        BitmapRegion.CreateControlRegion(this, bmpFrmBack);    }}

    產生不規則按鈕和產生不規則窗體一樣產生不規則按鈕public class Form1 : System.Windows.Forms.Form{    // 導入窗體背景圖片    private Bitmap bmpFrmBack = new Bitmap(typeof(Form1), "back.bmp");        // 導入按鈕背景圖片    private Bitmap bmpBob = new Bitmap(typeof(Form1), "bob.bmp");

        public Form1()    {        InitializeComponent();

            // 產生不規則窗體        BitmapRegion.CreateControlRegion(this, bmpFrmBack);                // 產生不規則按鈕        BitmapRegion.CreateControlRegion(button1, bmpBob);    }}如果你想在鼠標盡入/離開按鈕的時候顯示不同不規則按鈕, 只需要在按鈕的 MouseLeave和MouseEnter

    裡面寫上下面的代碼就可以了.private void button1_MouseEnter(object sender, System.EventArgs e){    // 產生不規則按鈕    BitmapRegion.CreateControlRegion(button1, bmpBobSay);}

    private void button1_MouseLeave(object sender, System.EventArgs e){    // 產生不規則按鈕    BitmapRegion.CreateControlRegion(button1, bmpBob);}移動不規則窗口因為不規則窗口沒有標題欄, 怎麼移動呢? 下面代碼給你答案, 代碼很簡單, 我就不做中文解釋了 ( 我

    做中文的部分就是不規則窗體 )private void Form1_MouseMove(object sender,                                         System.Windows.Forms.MouseEventArgs e){    // Check if dragging of the form has occurred    if(e.Button == MouseButtons.Left)    {        // If this is the first mouse move event for left click dragging         // of the form, store the current point clicked so that we can use         // it to calculate the form's new location in subsequent mouse move         // events due to left click dragging of the form        if(isFirst == true)        {            // Store previous left click position            prevLeftClick = new Point(e.X, e.Y);

                // Subsequent mouse move events will not be treated as first time,            // until the left mouse click is released or other mouse click             // occur            isFirst = false;        }

            // On subsequent mouse move events with left mouse click down.         // (i.e. During dragging of form)        else        {            // This flag here is to do alternate processing for the form             // dragging because it causes serious flicking when u allow             // every such events to change the form's location.            // You can try commenting this out to see what i mean            if(toBlock == false)                this.Location = new Point(this.Location.X + e.X -                     prevLeftClick.X, this.Location.Y + e.Y - prevLeftClick.Y);

                // Store new previous left click position            prevLeftClick = new Point(e.X, e.Y);

                // Allow or deny next mouse move dragging event            toBlock = !toBlock;        }    }

        // This is a new mouse move event so reset flag    else        isFirst = true;}

    完成程序列表BitmapRegion.csusing System;using System.Drawing;using System.Drawing.Drawing2D;using System.Windows.Forms;

    namespace BitmapRegionTest{ /// <summary> /// Summary description for BitmapRegion. /// </summary> public class BitmapRegion {  public BitmapRegion()  {}

      /// <summary>  /// Create and apply the region on the supplied control  /// </summary>  /// <param name="control">The Control object to apply the region to</param>  /// <param name="bitmap">The Bitmap object to create the region

    from</param>  public static void CreateControlRegion(Control control, Bitmap bitmap)  {   // Return if control and bitmap are null   if(control == null || bitmap == null)    return;      // Set our control's size to be the same as the bitmap   control.Width = bitmap.Width;   control.Height = bitmap.Height;

       // Check if we are dealing with Form here   if(control is System.Windows.Forms.Form)   {    // Cast to a Form object    Form form = (Form)control;

        // Set our form's size to be a little larger that the

    bitmap just     // in case the form's border style is not set to none in

    the first place    form.Width += 15;    form.Height += 35;

        // No border    form.FormBorderStyle = FormBorderStyle.None;

        // Set bitmap as the background image    form.BackgroundImage = bitmap;

        // Calculate the graphics path based on the bitmap supplied    GraphicsPath graphicsPath =

    CalculateControlGraphicsPath(bitmap);

        // Apply new region    form.Region = new Region(graphicsPath);   }

       // Check if we are dealing with Button here   else if(control is System.Windows.Forms.Button)   {    // Cast to a button object    Button button = (Button)control;

        // Do not show button text    button.Text = "";        // Change cursor to hand when over button    button.Cursor = Cursors.Hand;

        // Set background image of button    button.BackgroundImage = bitmap;        // Calculate the graphics path based on the bitmap supplied    GraphicsPath graphicsPath =

    CalculateControlGraphicsPath(bitmap);

        // Apply new region    button.Region = new Region(graphicsPath);   }  }

      /// <summary>  /// Calculate the graphics path that representing the figure in the bitmap   /// excluding the transparent color which is the top left pixel.  /// </summary>  /// <param name="bitmap">The Bitmap object to calculate our graphics path

    from</param>  /// <returns>Calculated graphics path</returns>  private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)  {   // Create GraphicsPath for our bitmap calculation   GraphicsPath graphicsPath = new GraphicsPath();

       // Use the top left pixel as our transparent color   Color colorTransparent = bitmap.GetPixel(0, 0);

       // This is to store the column value where an opaque pixel is first

    found.   // This value will determine where we start scanning for trailing

    opaque pixels.   int colOpaquePixel = 0;

       // Go through all rows (Y axis)   for(int row = 0; row < bitmap.Height; row ++)   {    // Reset value    colOpaquePixel = 0;

        // Go through all columns (X axis)    for(int col = 0; col < bitmap.Width; col ++)    {     // If this is an opaque pixel, mark it and search

    for anymore trailing behind     if(bitmap.GetPixel(col, row) != colorTransparent)     {      // Opaque pixel found, mark current

    position      colOpaquePixel = col;

          // Create another variable to set the

    current pixel position      int colNext = col;

          // Starting from current found opaque

    pixel, search for anymore opaque pixels       // trailing behind, until a transparent

    pixel is found or minimum width is reached      for(colNext = colOpaquePixel; colNext <

    bitmap.Width; colNext ++)       if(bitmap.GetPixel(colNext, row) ==

    colorTransparent)        break;

          // Form a rectangle for line of opaque

    pixels found and add it to our graphics path      graphicsPath.AddRectangle(new

    Rectangle(colOpaquePixel, row, colNext - colOpaquePixel, 1));

          // No need to scan the line of opaque

    pixels just found      col = colNext;     }    }   }

       // Return calculated graphics path   return graphicsPath;  } }}///

    //Form1.csusing System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;//using System.Runtime.InteropServices;

    namespace BitmapRegionTest{ /// <summary> /// Summary description for Form1. /// </summary> public class Form1 : System.Windows.Forms.Form {//  [DllImport("user32.dll")]//  private static extern bool PostMessage(IntPtr hWnd, int msg, long wParam,

    long lParam);

      private System.Windows.Forms.Button button1;  private System.Windows.Forms.Button button2;  private System.Windows.Forms.Button button3;  private System.Windows.Forms.Button button4;

      /// <summary>  /// Required designer variable.  /// </summary>  private System.ComponentModel.Container components = null;

      // Load our bitmaps  private Bitmap bmpFrmBack = new Bitmap(typeof(Form1), "back.bmp");  private Bitmap bmpBob = new Bitmap(typeof(Form1), "bob.bmp");  private Bitmap bmpBobSay = new Bitmap(typeof(Form1), "bobsay.bmp");  private Bitmap bmpSmiles = new Bitmap(typeof(Form1), "smiles.bmp");  private Bitmap bmpSmilesAngry = new Bitmap(typeof(Form1),

    "smilesangry.bmp");  private Bitmap bmpGreenBtnUp = new Bitmap(typeof(Form1), "greenbtnup.bmp");  private Bitmap bmpGreenBtnDown = new Bitmap(typeof(Form1),

    "greenbtndown.bmp");  private Bitmap bmpX = new Bitmap(typeof(Form1), "x.bmp");  private Bitmap bmpXSmile = new Bitmap(typeof(Form1), "xsmile.bmp");

      // To store the location of previous mouse left click in the form  // so that we can use it to calculate the new form location during dragging  private Point prevLeftClick;

      // To determine if it is the first time entry for every dragging of the

    form  private bool isFirst = true;

      // Acts like a gate to do allow or deny  private bool toBlock = true;

      public Form1()  {   //   // Required for Windows Form Designer support   //   InitializeComponent();

       // Make our bitmap region for the form   BitmapRegion.CreateControlRegion(this, bmpFrmBack);

       // Make our bitmap regions for the buttons   BitmapRegion.CreateControlRegion(button1, bmpBob);   BitmapRegion.CreateControlRegion(button2, bmpSmiles);   BitmapRegion.CreateControlRegion(button3, bmpGreenBtnUp);   BitmapRegion.CreateControlRegion(button4, bmpX);  }

      /// <summary>  /// Clean up any resources being used.  /// </summary>  protected override void Dispose( bool disposing )  {   if( disposing )   {    if (components != null)     {     components.Dispose();    }   }   base.Dispose( disposing );  }

      #region Windows Form Designer generated code  /// <summary>  /// Required method for Designer support - do not modify  /// the contents of this method with the code editor.  /// </summary>  private void InitializeComponent()  {   this.button1 = new System.Windows.Forms.Button();   this.button2 = new System.Windows.Forms.Button();   this.button3 = new System.Windows.Forms.Button();   this.button4 = new System.Windows.Forms.Button();   this.SuspendLayout();   //    // button1   //    this.button1.Location = new System.Drawing.Point(104, 88);   this.button1.Name = "button1";   this.button1.TabIndex = 0;   this.button1.Text = "button1";   this.button1.Click += new System.EventHandler(this.button1_Click);   this.button1.MouseEnter += new

    System.EventHandler(this.button1_MouseEnter);   this.button1.MouseLeave += new

    System.EventHandler(this.button1_MouseLeave);   //    // button2   //    this.button2.Location = new System.Drawing.Point(328, 80);   this.button2.Name = "button2";   this.button2.TabIndex = 1;   this.button2.Text = "button2";   this.button2.Click += new System.EventHandler(this.button2_Click);   this.button2.MouseEnter += new

    System.EventHandler(this.button2_MouseEnter);   this.button2.MouseLeave += new

    System.EventHandler(this.button2_MouseLeave);   //    // button3   //    this.button3.Location = new System.Drawing.Point(184, 200);   this.button3.Name = "button3";   this.button3.TabIndex = 2;   this.button3.Text = "button3";   this.button3.Click += new System.EventHandler(this.button3_Click);   this.button3.MouseEnter += new

    System.EventHandler(this.button3_MouseEnter);   this.button3.MouseLeave += new

    System.EventHandler(this.button3_MouseLeave);   //    // button4   //    this.button4.Location = new System.Drawing.Point(344, 232);   this.button4.Name = "button4";   this.button4.TabIndex = 3;   this.button4.Text = "button4";   this.button4.Click += new System.EventHandler(this.button4_Click);   this.button4.MouseEnter += new

    System.EventHandler(this.button4_MouseEnter);   this.button4.MouseLeave += new

    System.EventHandler(this.button4_MouseLeave);   //    // Form1   //    this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);   this.ClientSize = new System.Drawing.Size(432, 270);   this.Controls.AddRange(new System.Windows.Forms.Control[] {            

            this.button4,            

            this.button3,            

            this.button2,            

            this.button1});   this.Name = "Form1";   this.Text = "Form1";   this.MouseMove += new

    System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);   this.ResumeLayout(false);

      }  #endregion

      /// <summary>  /// The main entry point for the application.  /// </summary>  [STAThread]  static void Main()   {   Application.Run(new Form1());  }

      private void button1_MouseEnter(object sender, System.EventArgs e)  {   // Make bitmap region for button   BitmapRegion.CreateControlRegion(button1, bmpBobSay);  }

      private void button1_MouseLeave(object sender, System.EventArgs e)  {   // Make bitmap region for button   BitmapRegion.CreateControlRegion(button1, bmpBob);  }

      private void button2_MouseEnter(object sender, System.EventArgs e)  {   // Make bitmap region for button   BitmapRegion.CreateControlRegion(button2, bmpSmilesAngry);  }

      private void button2_MouseLeave(object sender, System.EventArgs e)  {   // Make bitmap region for button   BitmapRegion.CreateControlRegion(button2, bmpSmiles);  }

      private void button3_MouseEnter(object sender, System.EventArgs e)  {   // Make bitmap region for button   BitmapRegion.CreateControlRegion(button3, bmpGreenBtnDown);  }

      private void button3_MouseLeave(object sender, System.EventArgs e)  {   // Make bitmap region for button   BitmapRegion.CreateControlRegion(button3, bmpGreenBtnUp);  }

      private void button4_MouseEnter(object sender, System.EventArgs e)  {   // Make bitmap region for button   BitmapRegion.CreateControlRegion(button4, bmpXSmile);  }

      private void button4_MouseLeave(object sender, System.EventArgs e)  {   // Make bitmap region for button   BitmapRegion.CreateControlRegion(button4, bmpX);  }

      private void button1_Click(object sender, System.EventArgs e)  {   MessageBox.Show("bob");  }

      private void button2_Click(object sender, System.EventArgs e)  {   MessageBox.Show("smiles");  }

      private void button3_Click(object sender, System.EventArgs e)  {   MessageBox.Show("green button");  }

      private void button4_Click(object sender, System.EventArgs e)  {   MessageBox.Show("Exiting now...");   Close();  }/*  protected override void OnMouseDown(MouseEventArgs e)  {   if(e.Button == MouseButtons.Left)   {    const int HTCAPTION = 2;    const int WM_NCLBUTTONDOWN = 161;        int ix = e.X & 0xffff;    int iy = e.Y & 0xffff;    long ll = ix | iy << 16;

        PostMessage(this.Handle, WM_NCLBUTTONDOWN, HTCAPTION, ll);   }  }*/  private void Form1_MouseMove(object sender,

    System.Windows.Forms.MouseEventArgs e)  {   // Check if dragging of the form has occurred   if(e.Button == MouseButtons.Left)   {    // If this is the first mouse move event for left click

    dragging of the form,    // store the current point clicked so that we can use it to

    calculate the form's    // new location in subsequent mouse move events due to left

    click dragging of the form    if(isFirst == true)    {     // Store previous left click position     prevLeftClick = new Point(e.X, e.Y);

         // Subsequent mouse move events will not be treated

    as first time, until the     // left mouse click is released or other mouse

    click occur     isFirst = false;    }

        // On subsequent mouse move events with left mouse click

    down. (During dragging of form)    else    {     // This flag here is to allow alternate processing

    for dragging the form because it     // causes serious flicking when u allow every such

    events to change the form's location.     // You can try commenting this out to see what i

    mean     if(toBlock == false)      this.Location = new Point(this.Location.X +

    e.X - prevLeftClick.X, this.Location.Y + e.Y - prevLeftClick.Y);

         // Store new previous left click position     prevLeftClick = new Point(e.X, e.Y);

         // Allow or deny next mouse move dragging event     toBlock = !toBlock;    }   }

       // This is a new mouse move event so reset flag   else    isFirst = true;  } }}


    最新回复(0)