Pull to refresh

Comments 8

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

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

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

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

Нахлынули воспоминания как я 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 то что нам надо.
При такой логике, функционал программы немного расширится )))

Sign up to leave a comment.

Articles