谷歌谈话风格的Windows窗体
介绍 本文主要解释如何使用自定义绘制事件处理程序来绘制自己的Windows控件(在本例中为窗体控件)。GoogleTalkForm类继承和扩展System.Windows.Forms。表单控件(由Microsoft . net框架提供),用于提供谷歌Talk Windows窗体的外观和感觉。 类属性是windowsnappable, IsResizable, ResizableColor, TitleColor, TitleFont, TitleBackColor, TitleForeColor, TitleStyle, BodyBackColor, BodyStyle, OutlineColor, OutlineSize, IconsNormalColor, IconsHiLiteColor, MinimumHeight,和MinimumWidth可以用来改变表单的标准外观和感觉,以及行为。 GoogleTalkForm类提供: 绘制窗口窗体。 绘图使用双缓冲。 窗体快照到特定的客户端桌面区域。 鼠标事件处理。 绘制系统上下文菜单项。 它是如何工作的 首先,我们需要覆盖表单事件,如OnPaint, OnMouseDown, OnMouseUp, OnMouseMove, OnDoubleClick来处理表单绘制事件和鼠标事件。隐藏,复制Code
protected override void OnPaint(PaintEventArgs e) { ... } protected override void OnMouseDown(MouseEventArgs e) { ... }
表单的样式必须使用GoogleTalkForm类构造函数中的SetStyle方法来设置,以反映所需的行为。隐藏,复制Code
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.StandardClick, true); this.SetStyle(ControlStyles.StandardDoubleClick, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Opaque, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, false); this.UpdateStyles();
isMousePointerInArea方法用于检查当前鼠标位置是否在特定的客户端矩形区域内。必须计算出鼠标相对于Windows窗体的位置,因为控件。鼠标位置返回鼠标相对于桌面的位置。隐藏,复制Code
private bool isMousePointerInArea(Point mousePosition, Rectangle area) { Point relativePoint = new Point(0, 0); relativePoint.X = mousePosition.X - this.Location.X; relativePoint.Y = mousePosition.Y - this.Location.Y; return area.Contains(relativePoint); }
自定义的窗体绘制都是通过方法OnFormPaint在一个新创建的具有窗体的精确宽度和高度的位图对象上完成的。从位图创建图形对象,并使用DrawString、DrawImage、DrawLine和DrawArc等方法。一旦所有的绘制完成,缓冲的位图就会被复制到窗体图形实例中,使用drawimageunscaling方法。隐藏,复制Code
// Create a new Pen object p = new Pen(this.OutlineColor, this.OutlineSize); // Draw the form outline g.DrawArc(p, rectLeftCorner, 180, 90); g.DrawArc(p, rectRightCorner, 270, 90); g.DrawLine(p, edgeRadius, 0, this.Width - edgeRadius, 0); g.DrawLine(p, 0, edgeRadius, 0, this.Height); g.DrawLine(p, this.Width - 1, edgeRadius, this.Width - 1, this.Height); g.DrawLine(p, 0, this.Height - 1, this.Width, this.Height - 1); // Dispose the Pen object p.Dispose(); p = null;
创建一个自定义区域并应用于窗体,以产生圆角边缘效果。要创建所需的区域,我们必须逐像素迭代,并在当前选择的像素与透明颜色不相同时向GraphicsPath对象(将用于创建区域对象)添加一个1x1的矩形。为了优化代码,只检查窗体的顶部角是否有透明的彩色像素。隐藏,收缩,复制Code
// Create GraphicsPath to be used to crop the region required gpRegion = new GraphicsPath(); // Loop through every pixel in the top left corner. // Create a 1 x 1 rectangle regions of pixels // that do not match the transparent color for (int x = rectLeftCorner.X; x < rectLeftCorner.Width; x++) { for (int y = rectLeftCorner.Y; y < rectLeftCorner.Height / 2; y++) { if (isSameColor(bmp.GetPixel(x, y), this.transparentColor) == false) { gpRegion.AddRectangle(new Rectangle(x, y, 1, 1)); } } } // Loop through every pixel in the top right corner. // Create a 1 x 1 rectangle regions of pixels // that do not match the transparent color for (int x = rectRightCorner.X + 1; x < rectRightCorner.X + rectRightCorner.Width + 1; x++) { for (int y = rectRightCorner.Y; y < rectRightCorner.Y + rectRightCorner.Height / 2; y++) { if (isSameColor(bmp.GetPixel(x, y), this.transparentColor) == false) { gpRegion.AddRectangle(new Rectangle(x, y, 1, 1)); } } } // Create the remaining rectangular regions // to complete cover all the windows form area gpRegion.AddRectangle(new Rectangle(rectLeftCorner.Width, 0, this.Width - (edgeRadius * 4), rectLeftCorner.Height / 2)); gpRegion.AddRectangle(new Rectangle(0, rectLeftCorner.Height / 2, this.Width, this.Height)); // Apply region this.Region = new Region(gpRegion);
历史 第一个版本(2006年5月9日)。 1.1 -(二零零六年五月十一日) 创建窗体设计器以控制窗体(和子控件)行为。 修正了托管在MDI容器中的表单行为。 本文转载于:http://www.diyabc.com/frontweb/news6810.html