效果图:
最近翻看以前的学习C#的联系代码,无意之中发现一个很有趣的项目。是一个飘动窗体的效果,运行程序之后,在当前屏幕上会像雪花般飘动很多自定义图标,并且它们就像雪花般轻盈地从屏幕上方飘落到屏幕下方,直到消失。在程序运行过程中,屏幕上会维持一定数目的雪花。在系统托盘区域会有一个图标,点击这个图标,可以退出程序。这个联系代码联系了如何使用不规则窗体和系统托盘控件。
程序中核心部分源代码:
  1.using System;  
  2.using System.Drawing;  
  3.using System.Drawing.Drawing2D;  
  4.using System.Windows.Forms;  
  5. 
  6.namespace FallingGold  
  7.{  
  8.    /// <SUMMARY></SUMMARY>  
  9.    /// 说明:图片轮廓类,通过这个类提供的方法得到图片的外围轮廓  
 10.    /// 作者:周公  
 11.    /// 原创地址:<A href="http://blog.csdn.net/zhoufoxcn/archive/2008/06/06/2515753.aspxhttp://blog.csdn.net/zhoufoxcn/archive/2008/06/06/2515753.aspx">http://blog.csdn.net/zhoufoxcn/archive/2008/06/06/2515753.aspx</A>  
 12.    ///   
 13.    public class BitmapRegion  
 14.    {  
 15.        public BitmapRegion()  
 16.        { }  
 17. 
 18.        public static void CreateControlRegion(Control control, Bitmap bitmap)  
 19.        {  
 20.            //如果控件或者图象为空  
 21.            if (control == null || bitmap == null)  
 22.            {  
 23.                return;  
 24.            }  
 25.            //将控件设置成图象一样的尺寸  
 26.            control.Width = bitmap.Width;  
 27.            control.Height = bitmap.Height;  
 28.            //如果处理的是一个窗体对象  
 29.            if (control is System.Windows.Forms.Form)  
 30.            {  
 31.                Form form = control as Form;//强制转换为Form实例  
 32.                //将窗体的尺寸设置成比图片稍微大一点,这样就不用显示窗体边框  
 33.                form.Width += 15;  
 34.                form.Height += 35;  
 35.                //设置窗体无边框  
 36.                form.FormBorderStyle = FormBorderStyle.None;  
 37.                //设置窗体背景  
 38.                form.BackgroundImage = bitmap;  
 39.                //根据图片计算路径  
 40.                GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);  
 41.                //应用区域  
 42.                form.Region = new Region(graphicsPath);  
 43.            }  
 44.            //如果处理的是一个按钮对象  
 45.            else if (control is System.Windows.Forms.Button)  
 46.            {  
 47.                Button button = control as Button;//强制转换为Button实例  
 48.                //不显示文字  
 49.                button.Text = "";  
 50.                //当鼠标处在上方时更改光标状态  
 51.                button.Cursor = Cursors.Hand;  
 52.                //设置背景图片  
 53.                button.BackgroundImage = bitmap;  
 54.                //根据图片计算路径  
 55.                GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);  
 56.                //应用区域  
 57.                button.Region = new Region(graphicsPath);  
 58.            }  
 59.             
 60.        }  
 61.        /// <SUMMARY></SUMMARY>  
 62.        /// 通过逼近的方式扫描图片的轮廓  
 63.        ///   
 64.        /// <PARAM name="bitmap" />要扫描的图片  
 65.        /// <RETURNS></RETURNS>  
 66.        private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)  
 67.        {  
 68.            GraphicsPath graphicsPath = new GraphicsPath();  
 69.            //将图片的(0,0)处的颜色定义为透明色  
 70.            Color transparentColor = bitmap.GetPixel(0, 0);  
 71.            //存储发现的第一个不透明的象素的列值(即x坐标),这个值将定义我们扫描不透明区域的边缘  
 72.            int opaquePixelX = 0;  
 73.            //从纵向开始  
 74.            for (int y = 0; y < bitmap.Height; y++)  
 75.            {  
 76.                opaquePixelX = 0;  
 77.                for (int x = 0; x < bitmap.Width; x++)  
 78.                {  
 79.                    if (bitmap.GetPixel(x, y) != transparentColor)  
 80.                    {  
 81.                        //标记不透明象素的位置  
 82.                        opaquePixelX = x;  
 83.                        //记录当前位置  
 84.                        int nextX = x;  
 85.                        for (nextX = opaquePixelX; nextX < bitmap.Width; nextX++)  
 86.                        {  
 87.                            if (bitmap.GetPixel(nextX, y) == transparentColor)  
 88.                            {  
 89.                                break;  
 90.                            }  
 91.                        }  
 92. 
 93.                        graphicsPath.AddRectangle(new Rectangle(opaquePixelX, y, nextX - opaquePixelX, 1));  
 94.                        x = nextX;  
 95.                    }  
 96.                }  
 97.            }  
 98.            return graphicsPath;  
 99.        }  
100.    }  
101.} 
 
  1.<PRE class=csharp name="code">using System;  
  2.using System.Collections.Generic;  
  3.using System.ComponentModel;  
  4.using System.Data;  
  5.using System.Drawing;  
  6.using System.Text;  
  7.using System.Windows.Forms;  
  8. 
  9.namespace FallingGold  
 10.{  
 11.    /// <SUMMARY></SUMMARY>  
 12.    /// 说明:飘动的窗体  
 13.    /// 作者:周公  
 14.    /// 原创地址:<A href="http://blog.csdn.net/zhoufoxcn/archive/2008/06/06/2515753.aspxhttp://blog.csdn.net/zhoufoxcn/archive/2008/06/06/2515753.aspx">http://blog.csdn.net/zhoufoxcn/archive/2008/06/06/2515753.aspx</A>  
 15.    ///   
 16.    public partial class GoldForm : Form  
 17.    {  
 18.        private int currentX;//图片的当前横坐标  
 19.        private int currentY;//图片的当前纵坐标  
 20.        private int screenHeight;//屏幕高度  
 21.        private int screenWidth;//屏幕宽度  
 22.        private int counter;//图片数量  
 23.        private int increment;//移动增量  
 24.        private int interval;//移动时间间隔  
 25. 
 26.        private Bitmap bmpFlake = Properties.Resources.snow;  
 27.        /// <SUMMARY></SUMMARY>  
 28.        /// 构造函数  
 29.        ///   
 30.        /// <PARAM name="interval" />移动间隔  
 31.        /// <PARAM name="currentX" />飘动窗体的横坐标  
 32.        public GoldForm(int interval, int currentX)  
 33.        {  
 34.            this.interval = interval + 10;  
 35.            this.currentX = currentX;  
 36.            InitializeComponent();  
 37. 
 38.            BitmapRegion.CreateControlRegion(this, bmpFlake);  
 39.        }  
 40. 
 41.        private void GoldForm_Load(object sender, EventArgs e)  
 42.        {  
 43.            //获取屏幕的工作区域,不包括状态栏  
 44.            Rectangle rectangleWorkArea = Screen.PrimaryScreen.WorkingArea;  
 45.            screenHeight = rectangleWorkArea.Height;  
 46.            screenWidth = rectangleWorkArea.Width;  
 47.            timerMove.Interval = interval;//设置timer的间隔  
 48.            this.Left = currentX;//设置窗体的起始横坐标  
 49.            timerMove.Start();//运行timer  
 50.        }  
 51.        //timer的事件  
 52.        private void timerMove_Tick(object sender, EventArgs e)  
 53.        {  
 54.            timerMove.Stop();  
 55.            currentY += 5;  
 56.            counter++;  
 57. 
 58.            Random random = new Random();  
 59.            if (counter == 15)  
 60.            {  
 61.                if ((random.Next(10) - 5) > 0)  
 62.                {  
 63.                    increment = 1;  
 64.                }  
 65.                else 
 66.                {  
 67.                    increment = -1;  
 68.                }  
 69.                counter = 0;  
 70.            }  
 71. 
 72.            currentX += increment;  
 73.            if (currentY > screenHeight)  
 74.            {  
 75.                currentY = 0;  
 76.                currentX = random.Next(screenWidth);  
 77.                interval = random.Next(50,100);  
 78.            }  
 79.            //设置窗体位置,相当于移动窗体  
 80.            this.Location = new Point(currentX, currentY);  
 81. 
 82.            timerMove.Interval = interval;  
 83.            timerMove.Start();  
 84.        }  
 85.    }  
 86.}</PRE>  
 87.<PRE class=csharp name="code"> </PRE>  
 88.<PRE class=csharp name="code">整个程序的源代码请到<A href="http://download.csdn.net/source/484535http://download.csdn.net/source/484535">http://download.csdn.net/source/484535</A>下载。</PRE>