Google Talk styled Windows Form(翻译)

Print Broken Article? Bookmark Discuss
6 votes for this article.
Popularity: 3.35. Rating: 4.3 out of 5.
  • Download demo project - 22 Kb
  • Download source - 12 Kb

介绍

This article mainly explains how to use a custom Paint event handler to draw your own Windows Control (in this case a form control). The GoogleTalkForm class inherits and extends the System.Windows.Forms.Form control (provided by the Microsoft .NET Framework) to provide the look & feel of the Google Talk windows form.

这篇文章主要是解释了如何使用用户自定义PAINT事件句柄来绘制自己的窗口控件(这个例子是FORM控件)GoogleTalkForm 类继承和扩展了System.Windows.Forms.Form 控件(系统控件),以便提供Google Talk 窗口表单的样式和风格。

The class properties IsWindowSnappable, IsResizable, ResizableColor, TitleColor, TitleFont, TitleBackColor, TitleForeColor, TitleStyle, BodyBackColor, BodyForeColor, BodyStyle, OutlineColor, OutlineSize, IconsNormalColor, IconsHiLiteColor, MinimumHeight, MinimumWidth can be used to alter the form's standard look & feel and behaviour.

类的属性IsWindowSnappable, IsResizable, ResizableColor, TitleColor, TitleFont, TitleBackColor, TitleForeColor, TitleStyle, BodyBackColor, BodyForeColor, BodyStyle, OutlineColor, OutlineSize, IconsNormalColor, IconsHiLiteColor, MinimumHeight, MinimumWidth 可以被用来调整表单的标准风格和行为。


The GoogleTalkForm class provides

这个类做了什么?

  • drawing of the Windows Form   //重新绘制了窗口表单
  • drawing using a double buffering  //使用双缓冲来绘制界面
  • form snapping to specific client desktop regions  //??
  • mouse event handling  //处理了鼠标事件
  • system context menu item drawing //系统上下文菜单项

How it works

这个类的工作原理

First of all we need to add custom event handlers for the form paint event and mouse events. The following code is added to the InitializeComponent method

首先我们需要给PAINT事件和鼠标事件添加一些处理函数,下面的代码被加入到了InitializeComponent 方法

this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OnMouseUp);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove);
this.DoubleClick += new System.EventHandler(this.OnMouseDoubleClick);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.OnFormPaint);

The form's style must be set using the method SetStyle in the GoogleTalkForm class constructor to reflect the required behaviour.

窗口的风格必须要在GoogleTalkForm 类的构造函数里调用SetStyle方法,才能起到作用

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

The method isMousePointerInArea is used to check if the current mouse position is within a specific client rectangle area. The mouse location with respect to the windows form has to be worked out because the Control.MousePosition return the mouse position relative to the desktop.

isMousePointerInArea 方法用来检查特定区域内的鼠标位置。MousePosition 返回鼠标相对于桌面的位置。

 

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;

    if (relativePoint.X < area.X)
    {
        return false;
    }
    else if(relativePoint.Y < area.Y)
    {
        return false;
    }
    else if(relativePoint.X > area.X + area.Width)
    {
        return false;
    }
    else if(relativePoint.Y > area.Y + area.Height)
    {
        return false;
    }

    return true;
}

The custom form painting is all done by the method OnFormPaint onto a newly create Bitmap object having the exact width and height of the form. A Graphics object is created from the Bitmap and methods such as DrawString, DrawImage, DrawLine, DrawArc are used. As soon as all painting is complete the buffered bitmap is copied onto the form graphics instance using the method DrawImageUnscaled

自定义的界面绘制是在OnFormPaint 中创建了一个和FORM同样大小的位图对象,然后再利用这个位图创建一个Graphics对象,并且使用了画线,画字符串等函数来实现的。在画完之后,利用DrawImageUnscaled方法 把这个位图复制到graphics实例。

// 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;

A custom Region is created and applied to the form to make a rounded edge effect. To create the required region we have to iterate pixel by pixel and add a 1x1 rectangle to the GraphicsPath object (that will be used to create the region object) when the current selected pixel is not the same color as the transparent color. To optimise the code only the top corners of the form are checked for transparent colored pixels.

自定义区域创建并应用到窗体,可以形成非矩形的窗口效果。为了创建我们需要的形状,我们不得不把非透明色的点一个一个添加到GraphicsPath 对象。窗口左右上角的颜色被认为是要被透明的颜色。

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

History

  • 09 May 2006 - First version

NiaWs


Click here to view NiaWs's online profile.


Other popular articles:

  • Getting a "Handle" on the MDI Client
    A component to customize the MDI area of a Form with color, images, border styles, and more.
  • On tree diagrams and XML
    A control to edit tree structures is described with an emphasis on its XML capabilities and the underlying layout algorithms.
  • XPTable - .NET ListView meets Java's JTable
    A fully customisable ListView style control based on Java's JTable.
  • Inserting images into a RichTextBox control (the OLE way)
    This article shows how you can insert images, controls and ActiveX objects into a .NET RichTextBox control by using the OLE way. There are several samples about how it could be done, but all of them are in C++ and I needed it for managed code (C#).

你可能感兴趣的:(windows,ListView,object,Microsoft,Google,download)