zoukankan      html  css  js  c++  java
  • 谷歌谈话风格的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

  • 相关阅读:
    mybatis新增insert返回主键id,与解决新增主键id一直为1的问题。
    Mysql SQL语句查询今天、昨天、N天内、第N天的数据
    记录实时问题:java 出现unreachable statement异常
    java代码读取properties配置文件实例
    java设计模式详解
    java自用代码(包括:新建单线程、创建文件夹及文件、map转为json并将json写入txt、文件剪切或改名)
    ssm框架之持久层mybatis动态sql标签属性大全
    从onclick到function到ajax的url问号传多个参数(更多的话以此类推)问题
    TortoiseGit右击不显示图标或不显示状态图标等处理方法(win10、win7)
    Delphi 在写Ini文件时报错,Access violation at address 774D6EC8 in module 'ntdll.dll' write of address 004044CD
  • 原文地址:https://www.cnblogs.com/Dincat/p/13467445.html
Copyright © 2011-2022 走看看