代码改变世界

C#制作简易屏保[原创]

2006-10-06 16:25  老博客哈  阅读(7787)  评论(7编辑  收藏  举报

下载源代码:ScreenSaver.rar
初学C#的时候就曾想过写屏幕保护,当时觉得很深奥,摸不着头绪,就放弃了。今日又重新拾起,突然觉得也就是那么一回事,知道了就很简单了。好的,下面就介绍一下如何利用C#制作屏幕保护。
打开Visual Studio.net2005(其他版本也差不多),建立一个windows项目。这次的屏保是模仿Windows XP自带的一个屏幕保护。

把窗口的属性设置一下:
1.首先把 WindowState 设置为 FormWindowState.Maximized 这样窗口就可以在打开之后呈现最大化的状态。
2.把TopMost 设置为true,这样使得窗口处于最顶层,就是所谓的“永远在前”,相信用过千千静听,金山词霸等软件的朋友应该熟悉。
3.把FormBorderStyle 设置为FormBorderStyle.None ,这样窗口就没有边框,即没有了标题栏,周围的一圈边框。也就省去了一个个去掉MaximizeBox ,MinimizeBox了。
4.把BackColor设置为Color.Black, 这样窗口背景色就变成黑色了
5.ShowInTaskBar 设置为false,(这个步骤可以省去,本身最大化就看不到任务栏了)
其他的属性修改都是多余了,当然把name等等类似改改也行,总之,上面5个(严格的说4个)弄好了,UI方面就设计完毕了。


下面拖动一个timer控件进来,将其Enabled属性设置为true,Interval设置为10000(因为以milliseconds为单位,所以这里设置为10,000,也就是10s)。
加timer控件是为了每隔一定的事件触发一个事件。因此给timer加一个事件,点击Solution Explorer 上面的闪电图标,添加唯一的一个Tick事件。
下面就开始设计算法了,其实也是再简单不过了,随机产生一个点,然后再该处绘制预先准备好的图片。(如果为了好看点,可以设置坐标之间的关系)

        private readonly int screenWidth;
        
private readonly int screenHeight;
        
private Bitmap bitmap = new Bitmap("ms.bmp");
        
private Random random = new Random();
        
private int x = 0;
        
private int y = 0;


增加若干成员变量, 挺有self-documenting的味道,我就不过多解释了,前两个是标志屏幕的宽度和高度,
然后是一个位图对象,存储预先准备的图片,这里是一张bitmap。random是一个随机类对象,用来产生随机点的。再下面分别是产生的随机点的x,y坐标。
 构造函数内添加

 

Rectangle rect = Screen.PrimaryScreen.Bounds;
screenWidth 
= rect.Width;
screenHeight 
= rect.Height;


 第一句话是用来获得整个显示器的边界范围。然后分别把宽度和高度赋值给成员变量。
 注:Screen类提供了一些与显示器相关的属性,感兴趣的朋友可以参阅MSDN
 下面填补Tick事件
 

private void timer1_Tick(object sender, EventArgs e)
        
{
            x 
= random.Next(screenWidth);
            y 
= random.Next(screenHeight);
            
if (x + bitmap.Width > screenWidth)
            
{
                x 
= screenWidth - bitmap.Width;
            }

            
if (y + bitmap.Height > screenHeight)
            
{
                y 
= screenHeight - bitmap.Height;
            }

            
this.Invalidate();
        }

 
 上面是获取一个x,y坐标分别不大于显示器的宽度和高度的点。为了美观一点,判断图片是否超过屏幕边界,对x,y进行了一些处理, 不是很难,相信大家都能看懂。最后刷新屏幕,调用paint事件。
 我想您一定知道了,对, 在Form的paint事件里面有了一句画图的语句,回答正确!

 e.Graphics.DrawImage(bitmap, x, y, bitmap.Width,bitmap.Height);


 注: 我在编写程序测试的过程中,发现了一个非常细微也很重要的地方。也正是因为它,才引起了我写这篇文章的欲望。 要指出的是: Graphics类下面有一系列的DrawImage重载函数。
 特别关注这两个(我仅仅来出来举例,其他相应的大家自会明白)

 public void DrawImage( Image image, Point point);


 和

 public void DrawImage(Image image,int x,int y,int width,int height);


 
 前者是在指定点绘制物理大小的图片,而后者是在指定点绘制指定缩放大小的图片。
 两者有什么不同呢? 给大家看一段话应该就懂了!
 
 Image 对象存储像素宽度值及水平分辨率值(每英寸点数)。图像的物理宽度(以英寸为单位)等于像素宽度除以水平分辨率。例如,像素宽度为 216、水平分辨率为 72 点/英寸的图像的物理宽度为 3 英寸。此说明同样适用于像素高度和物理高度。
 
 此方法使用图像的物理大小绘制图像,因此无论显示设备的分辨率(每英寸点数)是多少,图像大小(以英寸为单位)都是正确的。例如,假定图像的像素宽度为 216,水平分辨率为 72 点/英寸。如果调用此方法在分辨率为 96 点/英寸的设备上绘制该图像,则所呈现图像的像素宽度是 (216/72)*96 = 288。
 
 哈哈, 也就是说前者在用图片的物理大小,后者使用指定大小。物理大小在不同的水平分辨率的显示器上显示的始终是图片的真实大小。(注意,bitmap 的width和height返回的大小都是以 pixel(像素)为单位的)。疑云顿时解开了!
 
 最后添加一个程序退出的操作,这里我使用的是键盘按下或者鼠标焦点变换。
 这个不难,略过。
 
 到此为止,把程序执行一下就可以看到预期的效果了。最后把bin/debug或者
 bin/release下的可执行程序后缀改成scr,并拷贝到系统盘Windows的system32下(图片也拷贝进去哦!)
 这样通过桌面属性的屏幕保护程序设置一下就可以投入使用了,是不是很炫呢!赶紧试试吧!
 
 
 
 
 
 程序在 Windows XP SP2 + Visual Studio.net 2005 下编译通过。
 

后记:
1.笔者发现,在Visual Studio.net2005下面建C#项目的时候有一项就是。是在屏保里面显示Rss内容的。待我研究一阵子再向大家汇报吧。
2.关于图片,拷贝到system32下委实不方便,我们可以使用内嵌资源编译进exe文件里面。下篇文章再介绍了,呵呵,睡觉去咯。