2

I want to create a program that saves a bmp image file on the driver and sets the image as wallpaper. The code i managed to write saves the image in the correct place but the image doesn't appear as the wallpaper. Please help...

class Program
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32
    uiParam,String pvParam, UInt32 fWinIni);
    private static UInt32 SPI_SETDESKWALLPAPER = 20;
    private static UInt32 SPIF_UPDATEINIFILE = 0x1;
    private String imageFileName = "D:\\wall.bmp";


    static void Main(string[] args)
    {
        Bitmap bmp = new Bitmap(Properties.Resources.wall);
        bmp.Save("D:\\wall.bmp");
        SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "D:\\wall.bmp", SPIF_UPDATEINIFILE);
    }





}
misha312
  • 1,443
  • 4
  • 18
  • 27

2 Answers2

4

You can try this Class written Here :

public sealed class Wallpaper
{
    Wallpaper() { }

    const int SPI_SETDESKWALLPAPER = 20;
    const int SPIF_UPDATEINIFILE = 0x01;
    const int SPIF_SENDWININICHANGE = 0x02;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

    public enum Style : int
    {
        Tiled,
        Centered,
        Stretched
    }

    public static void Set(Uri uri, Style style)
    {
        System.IO.Stream s = new System.Net.WebClient().OpenRead(uri.ToString());

        System.Drawing.Image img = System.Drawing.Image.FromStream(s);
        string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
        img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);

        RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);
        if (style == Style.Stretched)
        {
            key.SetValue(@"WallpaperStyle", 2.ToString());
            key.SetValue(@"TileWallpaper", 0.ToString());
        }

        if (style == Style.Centered)
        {
            key.SetValue(@"WallpaperStyle", 1.ToString());
            key.SetValue(@"TileWallpaper", 0.ToString());
        }

        if (style == Style.Tiled)
        {
            key.SetValue(@"WallpaperStyle", 1.ToString());
            key.SetValue(@"TileWallpaper", 1.ToString());
        }

        SystemParametersInfo(SPI_SETDESKWALLPAPER,
            0,
            tempPath,
            SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
    }
}

Good luck!

Community
  • 1
  • 1
Obama
  • 2,586
  • 2
  • 30
  • 49
1

You also need to include SPIF_SENDCHANGE when you call SystemParametersInfo. That's needed to notify the system that the background has been changed and will result in the system responding to your change.

SystemParametersInfo(
    SPI_SETDESKWALLPAPER, 
    0, 
    @"D:\wall.bmp", 
    SPIF_UPDATEINIFILE | SPIF_SENDCHANGE
);

You'll need to add a declaration for SPIF_SENDCHANGE which has the value 0x2.

The documentation says this about SPIF_SENDCHANGE:

Broadcasts the WM_SETTINGCHANGE message after updating the user profile.


That said, even without SPIF_SENDCHANGE, the desktop background will be changed on some systems. So my guess is that your main problem is actually with your bitmap file. Here are some possible problems with your bitmap file:

  1. You've specified the path to the bitmap incorrectly.
  2. The bitmap is still locked by the code that saved it.
  3. The bitmap is not in fact a bitmap. Perhaps you saved a .jpg to a file with a .bmp extension.

Prove to yourself that the code above works by creating a simple bitmap in Paint and changing the code above to use the hard coded path to that file. That will convince you that the desktop background can be changed.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Sorry for the ignorance but what does it mean - "Broadcasts the WM_SETTINGCHANGE message after updating the user profile." – misha312 May 04 '13 at 16:39
  • 1
    What happens is that the function calls `SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETDESKWALLPAPER, ...)` after making the change. The message is delivered to all top level windows. Including the explorer window that paints the desktop. That windows then responds to the message by refreshing the desktop. – David Heffernan May 04 '13 at 16:42
  • I need to declare this function like i did with the SystemParametersInfo? – misha312 May 04 '13 at 16:50
  • No! You just need to add `| SPIF_SENDCHANGE` like it says in my answer. You don't call SendMessage. Let SystemParametersInfo do it. – David Heffernan May 04 '13 at 16:52
  • :-( it doesn't work.... – misha312 May 04 '13 at 16:56
  • Yes it does work. Most likely there's something wrong with your bitmap file. For example, perhaps the file dos not exist. Or perhaps it's not actually a valid .bmp file. Maybe it's a JPEG. – David Heffernan May 04 '13 at 17:03
  • You right, it does work if I use an external bmp file without the "bmp.Save("D:\\wall.bmp");" part. But, if i use the bmp file that is included in the program (in the resources) it doesn't work any idea why? – misha312 May 04 '13 at 17:23
  • I think my problem is that the bitmap is locked by the code that saved it. Do you know what i need to do to unlock the file? The file is 100% bitmap I triple checked it. Appreciate you help... – misha312 May 04 '13 at 17:27
  • Now you are asking about code that I cannot see and is not in the question. – David Heffernan May 04 '13 at 17:32
  • Can you give me an example to how to unlock a file I have never heard about this function – misha312 May 04 '13 at 19:03
  • Locking won't be your problem. – David Heffernan May 04 '13 at 19:06
  • How about saving somewhere inside your user profile? C:\users\\... – David Heffernan May 04 '13 at 19:11
  • Really is this the only option? I would rather not do this. I would like to point that if i save a bitmap pic in this location manually(d\\:) it works fine. – misha312 May 07 '13 at 20:14
  • firstly, is my hunch correct? – David Heffernan May 07 '13 at 21:06
  • Nope... doesn't work... I think the problem is with the file.bmp. Because when i use a different file, a file that didn't come from the resources it works perfectly. – misha312 May 10 '13 at 18:16