изменить обои рабочего стола С#

Я хочу создать программу, которая сохраняет файл изображения bmp в драйвере и устанавливает изображение в качестве обоев. Код, который мне удалось написать, сохраняет изображение в правильном месте, но изображение не отображается в качестве обоев. Пожалуйста помоги...

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);
    }





}

person misha312    schedule 04.05.2013    source источник


Ответы (2)


Вы можете попробовать этот класс, написанный здесь:

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);
    }
}

Удачи!

person Obama    schedule 04.05.2013

Вам также необходимо включить SPIF_SENDCHANGE при вызове SystemParametersInfo. Это необходимо, чтобы уведомить систему об изменении фона и привести к тому, что система отреагирует на ваше изменение.

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

Вам нужно будет добавить объявление для SPIF_SENDCHANGE со значением 0x2.

В документации говорится о SPIF_SENDCHANGE:

Рассылает сообщение WM_SETTINGCHANGE после обновления профиля пользователя.


Тем не менее, даже без SPIF_SENDCHANGE фон рабочего стола будет изменен на некоторых системах. Итак, я предполагаю, что ваша основная проблема на самом деле связана с вашим растровым файлом. Вот некоторые возможные проблемы с растровым файлом:

  1. Вы неправильно указали путь к растровому изображению.
  2. Растровое изображение по-прежнему заблокировано кодом, который его сохранил.
  3. Растровое изображение на самом деле не является растровым изображением. Возможно, вы сохранили .jpg в файл с расширением .bmp.

Докажите себе, что приведенный выше код работает, создав простое растровое изображение в Paint и изменив приведенный выше код, чтобы использовать жестко запрограммированный путь к этому файлу. Это убедит вас, что фон рабочего стола можно изменить.

person David Heffernan    schedule 04.05.2013
comment
Извините за невежество, но что это значит - Транслирует сообщение WM_SETTINGCHANGE после обновления профиля пользователя. - person misha312; 04.05.2013
comment
Что происходит, так это то, что функция вызывает SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETDESKWALLPAPER, ...) после внесения изменений. Сообщение доставляется во все окна верхнего уровня. В том числе окно проводника, которое рисует рабочий стол. Затем эти окна отвечают на сообщение, обновляя рабочий стол. - person David Heffernan; 04.05.2013
comment
Мне нужно объявить эту функцию, как я сделал с SystemParametersInfo? - person misha312; 04.05.2013
comment
Нет! Вам просто нужно добавить | SPIF_SENDCHANGE, как сказано в моем ответе. Вы не вызываете SendMessage. Пусть SystemParametersInfo сделает это. - person David Heffernan; 04.05.2013
comment
:-( не работает.... - person misha312; 04.05.2013
comment
Да, это работает. Скорее всего, что-то не так с вашим растровым файлом. Например, возможно, файл не существует. Или, возможно, это неправильный файл .bmp. Возможно, это JPEG. - person David Heffernan; 04.05.2013
comment
Вы правы, это работает, если я использую внешний файл bmp без bmp.Save(D:\\wall.bmp); часть. Но если я использую файл bmp, включенный в программу (в ресурсах), он не работает, почему? - person misha312; 04.05.2013
comment
Я думаю, что моя проблема в том, что растровое изображение заблокировано кодом, который его сохранил. Вы знаете, что мне нужно сделать, чтобы разблокировать файл? Файл 100% растровый, я его трижды проверял. Благодарю вас за помощь... - person misha312; 04.05.2013
comment
Теперь вы спрашиваете о коде, который я не вижу и о котором не идет речь. - person David Heffernan; 04.05.2013
comment
Можете ли вы привести пример того, как разблокировать файл, я никогда не слышал об этой функции - person misha312; 04.05.2013
comment
Блокировка не будет вашей проблемой. - person David Heffernan; 04.05.2013
comment
Как насчет сохранения где-нибудь внутри вашего профиля пользователя? C:\users\‹имя пользователя›\... - person David Heffernan; 04.05.2013
comment
Неужели это единственный вариант? Я бы предпочел не делать этого. Я хотел бы отметить, что если я сохраню растровое изображение в этом месте вручную (d\\:), оно будет работать нормально. - person misha312; 08.05.2013
comment
во-первых, моя догадка верна? - person David Heffernan; 08.05.2013
comment
Неа... не работает... Думаю проблема в файле .bmp. Потому что, когда я использую другой файл, файл, который не получен из ресурсов, он работает отлично. - person misha312; 10.05.2013