自定义控件区域和按钮图像

在Windows Forms应用程序中,经常需要对控件的外观进行自定义,以满足特定的设计需求。本文将介绍如何为窗体和按钮创建自定义的位图区域,并实现鼠标悬停时的图像变化效果。

主要函数概览

以下是用于创建位图区域的两个主要函数的代码。这些函数位于名为BitmapRegion.cs的文件中。

创建和应用控件区域的函数:

public static void CreateControlRegion(Control control, Bitmap bitmap) { if (control == null || bitmap == null) return; control.Width = bitmap.Width; control.Height = bitmap.Height; if (control is System.Windows.Forms.Form) { Form form = (Form)control; form.Width += 15; form.Height += 35; form.FormBorderStyle = FormBorderStyle.None; form.BackgroundImage = bitmap; GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap); form.Region = new Region(graphicsPath); } else if (control is System.Windows.Forms.Button) { Button button = (Button)control; button.Text = ""; button.Cursor = Cursors.Hand; button.BackgroundImage = bitmap; GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap); button.Region = new Region(graphicsPath); } }

计算控件图形路径的函数:

private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap) { GraphicsPath graphicsPath = new GraphicsPath(); Color colorTransparent = bitmap.GetPixel(0, 0); int colOpaquePixel = 0; for (int row = 0; row < bitmap.Height; row++) { colOpaquePixel = 0; 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.AddRectangle(new Rectangle(colOpaquePixel, row, colNext - colOpaquePixel, 1)); col = colNext; } } } return graphicsPath; }

为窗体创建位图区域:

要为窗体创建位图区域,只需要以下两行代码。注意,不需要显式地将窗体的边框设置为无,因为这将为完成。

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); } }

实现鼠标悬停效果:

如果想在鼠标悬停在按钮上时改变按钮的位图,不需要创建自定义按钮控件。只需要简单地处理MouseEnter和MouseLeave事件,如下所示。

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); }

拖动窗体:

由于窗体现在没有标题栏,需要使其能够在窗体的任何地方点击并拖动。MFC版本中使用的解决方案是处理WM_LBUTTONDOWN并执行PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y))来欺骗Windows认为点击了标题栏。然而,无法在Windows Forms中实现这一点,因此下面的代码是另一种解决方案。

private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == MouseButtons.Left) { if (isFirst == true) { prevLeftClick = new Point(e.X, e.Y); isFirst = false; } else { if (toBlock == false) { this.Location = new Point(this.Location.X + e.X - prevLeftClick.X, this.Location.Y + e.Y - prevLeftClick.Y); prevLeftClick = new Point(e.X, e.Y); toBlock = !toBlock; } } } else { isFirst = true; } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485