用C#实现动态桌面墙纸(转)

转自:http://www.edu1995.com/jysy/ReadNews.asp?TypeId=16&NewsId=617

用C#实现动态桌面墙纸

发表日期:2009年4月27日编辑:

四川省卫生学校(610100)  陈建丽

 

摘要    本文主要通过运用C#语言Bitmap类的Clone和Save方法,以及API函数SystemParametersInfo,实现了动态修改当前桌面墙纸文件和动态移动大于桌面的墙纸文件两大功能,从而克服了需要用户手工改变桌面墙纸文件和桌面墙纸文件只能静态显示的缺点,使得用户的桌面更加生动和美观。

关键词    桌面  墙纸  动态  C#语言

    常言道:爱美之心,人皆有之。因此,很多人都喜欢到网络上找一些好看的图片作为自己电脑的桌面墙纸。但是在使用的过程中往往会发现以下两个问题:1、每次都必须自己手工更改当前的墙纸文件,非常麻烦。2、图片的大小不一定都和桌面的大小一致,不管是选择居中、平铺还是拉伸方式都显得不是那么好看。基于此,设计了下面的这个程序:一是可以定时改变桌面墙纸的图片文件,二是可以将大于桌面大小的图片往上、往左或往左上方进行移动。下面就是具体的实现过程和相关信息的解释说明。

    一、启动MicrosoftVisual Studio 2005,选择命令“文件-新建-项目”,在“新建项目”对话框中选择项目类型为“Visual C#---Windows---Windows应用程序”并设置项目名称为DynamicWallPaper。

二、在默认窗体Form1上添加如下表所示控件,并设置相应的属性,最后窗体界面如下图所示。

控件

属性名称

属性值

说明

Label

Name

LabelTime

显示提示信息

Text

更换墙纸的间隔时间(分钟)

NumericUpDown

Name

HowLongChangeWallPaper

设置更换墙纸的时间间隔

Maximum

10

更换墙纸的最大时间间隔

Minimum

1

更换墙纸的最小时间间隔

Button

Name

btnBrowse

通过该按钮可将对应文件夹中的图片文件加入列表

Text

添加图片所在文件夹(&B)

Button

Name

btnApply

通过该按钮可以使得设置的更换时间起作用

Text

应用当前所作修改(&A)

ListBox

Name

listBoxPictureFile

显示可以作为墙纸的文件

FolderBrowserDialog

Name

FolderBrowserForPicture

显示”浏览文件夹”对话框

Timer

Name

timerChangeCurrentWallPaper

定时改变当前的墙纸文件

Timer

Name

timerMoveWallPaper

定时移动当前的墙纸文件

InterVal

1000

每1秒钟移动一次


三、在程序中加入以下引用和代码。当然,其中的注释信息在程序中可以省略。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualBasic;//添加引用,为了使用文件操作的相关方法(同时要通过菜单命令"项目-添加引用-Microsoft.VisualBasic")
using System.Runtime.InteropServices;//为了使用API
using Microsoft.Win32;//为了使用注册表的相关方法
 
namespace dynamicwallpaper
{   
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni); //该API可用于设置桌面墙纸
        //以下3个为SystemParametersInfo设置墙纸时用常量
        public const int SPI_SETDESKWALLPAPER = 20; //设置桌面墙纸
        public const int SPIF_UPDATEINIFILE = 1; //将新的参数写入用户Profile文件
        public const int SPIF_SENDWININICHANGE = 2;//广播WM_SETTINGCHANGE消息
 
        public int FileWidth;//图像文件的宽度
        public int FileHeight;//图像文件的高度
        public int CurrX;//显示在屏幕上的图像文件左上角的X坐标
        public int CurrY;//显示在屏幕上的图像文件左上角的Y坐标
       
        public int CurrentPictureFileIndex;//存放当前显示的图像文件的Index号
        public Boolean HaveShown;//当前墙纸的显示过程是否已经结束
               
        public Form1()
        {
         InitializeComponent();
        }
 
        private void btnBrowse_Click(object sender, EventArgs e)//打开"浏览文件夹"对话框,将选定文件夹中的图片文件添加到列表框中
        {
            string TempStr;//临时变量:用于保存文件名
            Boolean BeenAdded;//临时变量:判断当前文件是否已经加入列表框中
            TempStr = "";
            FolderBrowserForPicture.ShowDialog();
            if (FolderBrowserForPicture.SelectedPath!= "")//选择了文件夹
            {             
TempStr =
Microsoft.VisualBasic.FileSystem.Dir(FolderBrowserForPicture.SelectedPath + "\\*.*", Microsoft.VisualBasic.FileAttribute.Directory);
               while (TempStr != null)//该文件夹有文件
               {
if (((TempStr.Substring(TempStr.LastIndexOf
(".")).ToUpper())==".BMP")|| ((TempStr.Substring(TempStr.LastIndexOf
(".")).ToUpper())==".GIF") || ((TempStr.Substring(TempStr.LastIndexOf
(".")).ToUpper())==".JPG") || ((TempStr.Substring(TempStr.LastIndexOf
(".")).ToUpper())==".JPEG"))//如果为常见的图像文件
                   {
                   //下面判断该文件是否已经在列表框中
                   BeenAdded = false;
                   if (listBoxPictureFile.Items.Count >= 1)//列表框中有文件名
                   {
                       for (int j = 1; j <= listBoxPictureFile.Items.Count; j++)
                       {
                           if (listBoxPictureFile.Items[j - 1].ToString() == FolderBrowserForPicture.SelectedPath + "\" + TempStr)
                           {
                               BeenAdded = true;//已经在列表框中
                               break;
                           }
                       }
                   }
 
                   if (!BeenAdded)//还没有加入列表框中
                   {
                       listBoxPictureFile.Items.Add(FolderBrowserForPicture.SelectedPath + "\" + TempStr);//将其加入列表框中
                   }
 
               }
                   TempStr = Microsoft.VisualBasic.FileSystem.Dir();//继续查找下一个文件
               }
 
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)//程序启动时设置墙纸的显示方式为“居中”
        {
            //通过修改注册表实现
            RegistryKey TRegKey;
            TRegKey = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);
            if (TRegKey != null)
            {
                TRegKey.SetValue("WallpaperStyle", "0");
                TRegKey.SetValue("TileWallpaper", "0");
            }
            timerChangeCurrentWallPaper.Interval = (int)HowLongChangeWallPaper.Value * 1000 * 60;
            timerChangeCurrentWallPaper.Enabled = true;
            CurrentPictureFileIndex = 0;
            HaveShown = true;
        }
 
         private void timerChangeCurrentWallPaper_Tick(object sender, EventArgs e)//定时改变当前的墙纸文件
        {
            //设置列表框中下一个文件为当前的桌面墙纸文件
            if (listBoxPictureFile.Items.Count > 0 && HaveShown)
            {
                if (CurrentPictureFileIndex < listBoxPictureFile.Items.Count - 1)
                {
                    CurrentPictureFileIndex += 1;
                }
                else
                {
                    CurrentPictureFileIndex = 0;
                }
 
                HaveShown = false;
 
                Bitmap tBmp1 = new Bitmap(listBoxPictureFile.Items[CurrentPictureFileIndex].ToString());//根据选择的图像文件建立一个bitmap对象
                FileWidth = tBmp1.Width; //获得图片文件的宽度和高度
                FileHeight = tBmp1.Height;
                if (tBmp1.Width <= Screen.PrimaryScreen.Bounds.Width & tBmp1.Height <= Screen.PrimaryScreen.Bounds.Height)
                {//图片的宽度和高度都小于桌面时,则直接显示
                    SetWallPaper(listBoxPictureFile.Items[CurrentPictureFileIndex].ToString(), 0, 0, tBmp1.Width, tBmp1.Height);
                    HaveShown = true;
                }//否则,启动定时器并进行动态显示
                else
                {
                    CurrX = 0; //从图片的左上角开始
                    CurrY = 0;
                  
                    timerMoveWallPaper.Enabled = true;//启动定时器
                }
                tBmp1.Dispose();
               
            }
        }
 
        private void timerMoveWallPaper_Tick(object sender, EventArgs e)//定时移动当前的墙纸文件
        {
           
            Boolean CanMoveLeft; //图片是否可以左移
            Boolean CanmoveUp; //是否可以上移
            if (FileWidth - CurrX >= Screen.PrimaryScreen.Bounds.Width)
            {//可以左移图片
                CanMoveLeft = true;
                CurrX += Math.Min(12, FileWidth - CurrX); //每次横向向左最多移动12像素
            }
            else
            {
                CanMoveLeft = false;
            }
 
            if (FileHeight - CurrY >= Screen.PrimaryScreen.Bounds.Height)
            {//可以上移图片
                CanmoveUp = true;
                CurrY += Math.Min(9, FileHeight - CurrY); //每次纵向向上最多移动9像素
            }
            else
            {
                CanmoveUp = false;
            }
 
            if (CanMoveLeft == false & CanmoveUp == false)//图片已不能上移和左移
            {
              
                timerMoveWallPaper.Enabled = false;//停止定时器
                HaveShown = true ;
 
            }
 
            int DisplayPicWidth;//屏幕上显示的图片区域的宽度和高度
            int DisplayPicHeight;
            if (CurrX + Screen.PrimaryScreen.Bounds.Width <= FileWidth)
            {
                DisplayPicWidth = Screen.PrimaryScreen.Bounds.Width;
            }
            else
            {
                DisplayPicWidth = FileWidth - CurrX;
            }
 
            if (CurrY + Screen.PrimaryScreen.Bounds.Height <= FileHeight)
            {
                DisplayPicHeight = Screen.PrimaryScreen.Bounds.Height;
            }
            else
            {
                DisplayPicHeight = FileHeight - CurrY;
            }
 
            SetWallPaper(listBoxPictureFile.Items[CurrentPictureFileIndex].ToString(), CurrX, CurrY, DisplayPicWidth, DisplayPicHeight);//调用设置墙纸过程
 
 
        }
 
        //本段程序的基本原理:使用Bitmap类的Clone和Save方法将图片的指定区域保存为临时文件,再使用SystemParametersInfo将临时文件设置为桌面墙纸。
        private void SetWallPaper(string SelectedPicFile, int CurrX, int CurrY, int PicWidth, int PicHeight)
        {//将图片文件的指定区域保存为BMP文件,并设置为墙纸文件
            Bitmap tBmp1 = new Bitmap(SelectedPicFile);//根据选择的图像文件建立一个Bitmap对象
            System.Drawing.Imaging.PixelFormat format = tBmp1.PixelFormat;
            Rectangle cloneRect = new Rectangle(CurrX, CurrY, PicWidth, PicHeight);
            Bitmap cloneBitmap = tBmp1.Clone(cloneRect, format);//根据源图片文件和指定区域,建立bitmap对象
            cloneBitmap.Save("C:\\Temp.bmp", System.Drawing.Imaging.ImageFormat.Bmp);//将bitmap对象保存为BMP文件,因为程序中只能使用BMP图像
            SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "C:\\Temp.bmp", SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);//设置为墙纸
            tBmp1.Dispose();
        }
 
        private void btnApply_Click(object sender, EventArgs e)//应用当前的设置
        {
            timerChangeCurrentWallPaper.Interval = (int)HowLongChangeWallPaper.Value * 1000 * 60;
            timerChangeCurrentWallPaper.Enabled = true;
        }
                       
    }
} 

四、现在运行程序,选择一个文件夹,则该文件夹中所有图片文件将加入列表框中。然后,每隔一段时间,程序会自动改变当前的墙纸文件:如果墙纸图片文件宽度和高度都大于桌面,则可以往左上角移动;如果只是宽度大于桌面,或高度大于桌面,则只能左移或上移;如果图片宽度和高度都小于等于桌面,则静止显示在桌面上。

本程序用C# 2.0语言实现,在Windows XP环境下编译通过。

参考文献

1.Karli Watson等著.杨浩译.Visual C#入门经典.清华大学出版社,2006

2.用VB更换桌面墙纸DIY.http://www.mscto.com/vb/2009020122541_2.html

3.冉林仓.用Visual C#调用Windows API函数.北京机械工业学院研00级,http://www.book52.com/article/sort02/sort0160/info- 13576.html

4.MSDN Library for Visual Studio2005,Microsoft Corp.2005


===================以下部分为本人添加===================
十分感谢原作者 陈建丽
贴一张截图,编译成功后是这样的。(注:控件属性没有完全使用上表的,只有name属性是对应的)



上面的按钮可以添选择目录,选择完毕后,自动回搜索目录下所有图片文件,显示在列表中。
下面的按钮是应用按钮,点击后生效,循环切换列表中的每一个图片作为背景。

实际上本文是从http://blog.sina.com.cn/s/blog_65e635ee0100nv03.html看到的,写博时原地址已经失效,又对原文格式稍加了整理。
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值