Обновить

Комментарии 13

Отличный школьный проект (я же угадал?), неплохое начало. На будущее, чтобы хабровчане совсем уж не захейтили, делай хотя бы дисклеймер "Я не волшебник, но только учусь")

По поводу утилиты, в винде (по крайней мере по семёрку включительно, плохо знаком с актуальными версиями) есть нативная поддержка одноцветного фона рабочего стола, картинки для этого не нужны. Попробуй разобраться, как этим функционалом манипулировать программно, и используй его.

Спасибо за подсказку

Мда, статья по уровню, действительно, не совсем для хабра, но даже рука не поднимается ставить минус.

Нахлынули воспоминания как я 30 лет назад делал это на bat-файлах, на Паскале и на С++, для Windows 95.. Менял не только обои, но и загрузочные картинки - писал на них всякие напоминания типа ближайших праздников и дней рождения. Ох как я стар...

Да, статья конечно (с технической точки зрения) ..., , но иногда воспоминания нас делают моложе, возвращают нас во времена, когда мы были огого !!!

Держи на Паскале)

program ChangeDesktopColor;

{$APPTYPE CONSOLE} // можно убрать и будет без консоли
//{$DEFINE USE_COM}
{$DEFINE TEST_MODE}

uses
  Winapi.Windows, Winapi.ActiveX, System.SysUtils, System.IOUtils, Winapi.ShlObj;

function ChangeDesktopBackgroundColor(Color: COLORREF): Boolean;
begin
  {$IFDEF USE_COM} // Установка цвета через COM
  var HRES := CoInitialize(nil);
  if Succeeded(HRES) then
  try
    var Wallpaper: IDesktopWallpaper;
    if Succeeded(CoCreateInstance(CLSID_DesktopWallpaper, nil, CLSCTX_ALL, IDesktopWallpaper, Wallpaper)) then
      HRES := Wallpaper.SetBackgroundColor(Color);
  finally
    CoUninitialize;
  end;
  Result := Succeeded(HRES);
  {$ELSE} // Установка цвета через WinAPI
  Result := False;
  if SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, SPIF_UPDATEINIFILE or SPIF_SENDCHANGE) then
  begin
    var Element: Integer := COLOR_DESKTOP;
    Result := SetSysColors(1, Element, Color);
  end;
  {$ENDIF}
end;

begin
  {$IFDEF TEST_MODE}
  var Dir := TPath.GetLibraryPath;
  {$ELSE}
  var Dir := 'C:\folder\subfolder\subfolder\';
  {$ENDIF}
  var FilePath := TPath.Combine(Dir, '0.jpg');
  var FileName := '0.jpg';

  // обработка аргумента
  if ParamCount = 1 then
  begin
    FileName := ParamStr(1) + '.jpg';
    FilePath := TPath.Combine(Dir, FileName);
  end;

  // текущие обои
  var WallFile: string;
  Setlength(WallFile, MAX_PATH);
  SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, PChar(WallFile), 0);

  // логика переключения
  if (WallFile <> FileName) and TFile.Exists(FilePath) then
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, PChar(FilePath), SPIF_UPDATEINIFILE or SPIF_SENDWININICHANGE)
  else
  begin
    if ChangeDesktopBackgroundColor(RGB(0, 0, 0)) then
      SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, SPIF_SENDWININICHANGE);
  end;
end.

Правда я тут улучшил немного. Дублирование кода убрал. И читается раз в 15 легче

За код спасибо.
При запуске ChangeDesktopColor.exe 999 будет черный цвет, не будет файла обоев по умолчанию. FileName будет ="999.jpg", такого файла нет. На мой взгляд надо писать более хитрый if или использовать case.
такой if

  if ParamCount = 1 then
  begin
    FileName := ParamStr(1) + '.jpg';
    FilePath := TPath.Combine(Dir, FileName);
  end;

будет создавать FileName=ParamStr(1).jpg, в ParamStr(1) может быть (в общем случае) любое выражение "ф", "вася","море", и тд и тп.

И еще 1 момент, файлы 1.jpg ... 4.jpg для конфигурации TEST лежат в папке программы. Файлы обоев с именами filename0.jpg ... filename4.jpg (например) могут находится по разным путям и не обязательно путь к файлу, например, filename3.jpg будет совпадать с путем в Dir. Но это моя оплошность. Выражение C:\\folder\\subfolder\\subfolder\\ можно было понять как один путь к папке, я имел ввиду, что это разные пути. Надо было писать C:\\folder1\\subfolder1\\subfolder1\\, C:\\folder2\\subfolder2\\subfolder2\\

Про любое значение - это специально, так же удобнее. А если при указании несуществующего файла нужен не черный цвет, то достаточно добавить просто ещё одно условие.

Да, про это я и написал. Вариантов реализации и логики может быть много. например после
FileName := ParamStr(1) + '.jpg'; FilePath := TPath.Combine(Dir, FileName); проверяем, существует ли файл FilePath. Если существует, оставляем все как есть, если не существует - присваиваем FileName и FilePath то что нам надо.
При такой логике, функционал программы немного расширится )))

Неявное преобразование параметра в имя файла путем дописывания .jpg - ужасно. Если ожидается файл - нужно выдавать ошипку если файл не читается. И никакой магии.

В параметрах файл не ожидается (по моей логике). Пути к файлам прописаны в самой программе. EXE файл будет содержать пути к файлам..
ЗЫ: я исхожу из того, что программа строго персональная, и тот, кто ей будет (теоретически) пользоваться изменит пути к своим проверенным файлам.

Я стар, я стар, я ... Superstar! ;)

Кста, ты единственный живой чел щас на хабре, пушто остальные статьи делают нейронки

Спасибо, приятно )))

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации