×

用GDI+创建无边框窗体

Kalet Kalet 发表于2009-03-20 12:00:13 浏览315 评论0

抢沙发发表评论


用GDI+创建无边框窗体

2007-03-31 18:03
用GDI+创建无边框窗体








介绍


          这篇文章中,我将向你展晃用不同的方法去创建一个无边框的窗体,它将会使你的应用程序变的更加吸 引但不会花费你的时间,因为这是个一很简单的任务。




背景


          虽然我不清楚如何用Visual Studio 6.0 去创建一个无框的窗体,但我确定它是一个不简单的任务,它将涉及到一些API的调用。但用Visual Studio.Net,你将会发现,通过一些预定的步骤是非常容易做到的。这儿有两种不同的方法:

1、设置Windows Form的 transparency key 属性

2、运用GDI+技术




设置Windows Form的 transparency key 属性

  

       这是一个普通的解决方法,只需要以下几步:


  • 设置FormBorderStyle属性为None(去掉窗体的边框)
  • 创建一个bitmap(位图)作为你窗体的背景。
  • 用一种特殊的颜色(如:黑色[black])去填充你想显示出透明色的地方
  • 设置BackgroundImage属性的图片为你的准备的位图文件
  • 设置TransparencyKey属性为一种你准备的特殊的颜色(例:上文件我们例子中提到的黑色[back])

       因为我们去掉了窗体的边框,你将会发现我们无法关闭或移动我们的窗体,所以我们必须创建一些鼠标事件去现实,这将在这篇文章的后续部分去讨论。


       如果这个方法不奏效,你能看到整个背景图,这是因为你要检查你的监视器的颜色质量是否低于32位。如果你用一种特别的颜色去改变BackColor属性,再将TransparencyKey属性改成相应的色彩,你将会发现你的窗体消失了,但用这种方法需要依靠系统的设置。 检索MSDN发现一个有效的解决的途径 。











// The namesapces used
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
然后,我们必须覆盖所要调用窗体的onpaint事件,以便重绘被调用窗体。












protected override void OnPaint(PaintEventArgs e)
{
      // 首先我们创建一个Graphics对象
      // 参数PiantEventArgs    e是本方法所作用的窗体
      Graphics grfx = e.Graphics;

      // 寻找一个你所需要的曲线轨道
      // 使用SmoothingMode.AntiAlias
      grfx.SmoothingMode = SmoothingMode.HighQuality;


      // GraphicsPath 类是一个sealed 类
      // 它是用于一些连接线和曲线联合成闭合的路经
      // 它是透明的
      GraphicsPath grfxPath1 = new GraphicsPath();


      // 我们将会画一个圆形的窗体
      // 如位于一个正方形的窗体中,则只须画一个简单的圆
      // 如位于一个长方形的窗体中,则需画成一个椭圆
      // 为了形成一个窗体,需要用两个圆组成
      Rectangle rec1 = new Rectangle(0,0,300,100);用GDI+创建无边框窗体
      grfxPath1.AddEllipse(rec1);
      Rectangle rec2 = new Rectangle(120,99,60,40);
      grfxPath1.AddEllipse(rec2);


      // 用SetClip方法设置当前图形对象的区域
      // 替换为上面我们所组合后的区域
      grfx.SetClip(grfxPath1,CombineMode.Replace);


      // 现在我们将用这个图片中的图片路径去
      // 替换当前的区别的的
      // 我们能够用一种颜色去填充此区域
      // 甚至所要填充的颜色是一种TransparensyKey
      // TransparensyKey不会探查到它
      Brush b = new SolidBrush(Color.Green);
      grfx.FillEllipse(b,rec1);
      grfx.FillEllipse(b,rec2);


      // 你可以用下面2步去将一个图片做为背景
      // 以代替用普通颜色填充窗体
      // 注:背景图片中不能有与TransparensyKey一样的颜色
      // 因为它会被TransparensyKey探测出来
      // Rectangle frmRectangle = new Rectangle(0,0,this.Width,this.Height);
      // grfx.DrawImage(Image.FromFile("zerosones.jpg"), frmRectangle);


      // 我们用下面这个方法为我们的窗体制作一个边框
      Pen p = new Pen(Color.Yellow,5f);
      grfx.DrawPath(p,grfxPath1);
}


鼠标事件


因为我们除去了边框,所以,我们不能移动我们的窗体,所以我们必须添加鼠标事件去处理它们。












// 定义Point对象去存放窗体位置、鼠标当前位置以及鼠标新位置
Point MouseCurrrnetPos,MouseNewPos,formPos,formNewPos;


bool mouseDown=false;



private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
      // 当鼠标被按下时,我们要设置标志以说明鼠标左键被按下
      // 并存放当前鼠标的位置以及窗体的位置
      // 我们将用这些位置去计算窗体所移动的距离
      if(e.Button==MouseButtons.Left)
      {
          mouseDown = true;
          MouseCurrrnetPos = Control.MousePosition;
          formPos = Location;
      }
}


// 当用户释放鼠标按键时,我们必须更新标示
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
      if(e.Button==MouseButtons.Left)
          mouseDown=false;
}


// 当鼠标移动时,我们获得它的新位置
// 来后计算出一窗体将会移动到的新位置
// 来后设置当前位置为窗体的新位置
// 并存放更新当前鼠标的位置
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
      if(mouseDown==true)
      {
          // 获得屏幕中当前鼠标的位置
          MouseNewPos=Control.MousePosition;
          formNewPos.X=MouseNewPos.X-MouseCurrrnetPos.X+formPos.X;
          formNewPos.Y=MouseNewPos.Y-MouseCurrrnetPos.Y+formPos.Y;
          Location=formNewPos;
          formPos=formNewPos;
          MouseCurrrnetPos=MouseNewPos;
      }用GDI+创建无边框窗体
}



群贤毕至

访客