Set as desktop background

Features wanted...
bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: Set as desktop background

Post by bdeshi »

Suddenly I've sourly/sorely discovered this feature's absence in the info pane and floating preview context menus.

In fact, I very quickly created a dirty little helper util in FreeBASIC. (The code is dirty as said and does no checks anywhere.)

Code: Select all

' setWallpaper.bas: sets desktop wallpaper to jpg/bmp image file passed as first argument

#Include "windows.bi"
' BOOL WINAPI SystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);
' https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx
Dim As UINT  uiAction 
Dim As UINT  uiParam   = 0    ' 0 If not otherwise indicated by uiAction
Dim As PVOID pvParam   = NULL ' NULL If not otherwise indicated by uiAction
Dim As UINT  fWinIni  

If (Command(1) <> "") Then    ' set wall if 1st arg exists. No sanity check
  uiAction = SPI_SETDESKWALLPAPER
  'pvParam parameter is a pointer to a buffer containing image path as null-terminated string.
  Dim As String  imgPath = Command(1) ' get 1st cmd argument
  Dim As ZString Ptr Img              ' pointer to a null-terminated string var
  Img      = Allocate(Len(ImgPath))   ' set Img size to the string it will carry
  *Img     = ImgPath                  ' put imgpath at Img pointer address
  pvParam  = Img                      ' update pvParam (note: Img is already a pointer)
  fWinini  = SPIF_UPDATEINIFILE       ' signals user profile update
  /'only bmp is supported in pre-Vista
  but IsWindowsVersionOrGreater() apparently unimplemented in fbc
  If (IsWindowsVersionOrGreater(6, 0, 0)) Then
  	 If (InStr(ImgPath, ".bmp") <> Len(ImgPath) - 3) Then End
  EndIf '/
  SystemParametersInfo(uiAction, uiParam, pvParam, fWinIni)
EndIf
I use this script to call setWallper.exe on the selected image in the floating preview script button:

Code: Select all

run """<xyscripts>\utils\setWallpaper.exe"" ""<curitem>""";
Really hope this gives you some incentive, Don.
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

klownboy
Posts: 4109
Joined: 28 Feb 2012 19:27

Re: Set as desktop background

Post by klownboy »

Hi Sammay, I hope all is well. I downloaded FreeBasicWin64 version and compiled the setWallpaper.bas and it worked fine. Any ideas though on how I could modify the parameters and then compile such that the resultant wallpaper would be stretched proportionally (i.e., fit to screen). I always use images that are in the proper aspect ratio for my computer screen but they are usually much larger higher resolution photos. No big deal if not. The following also works as an XY script using PowerShell but unfortunately in the same way - not proportionally fit to screen. The parameters seem to match up with your bas code. Thanks.

Code: Select all

 $PS = <<<HEREDOC
Add-Type @"
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Wallpaper
{
   public enum Style : int
   {
       Fit, Center, Stretch, NoChange
   }
   public class Setter {
      public const int SetDesktopWallpaper = 20;
      public const int UpdateIniFile = 0x01;
      public const int SendWinIniChange = 0x02;
      [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      private static extern int SystemParametersInfo (int uAction, int uParam, string lpvParam, int fuWinIni);
      public static void SetWallpaper ( string path, Wallpaper.Style style ) {
         SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
         RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);
         switch( style )
         {
            case Style.Stretch :
               key.SetValue(@"WallpaperStyle", "2") ; 
               key.SetValue(@"TileWallpaper", "0") ;
               break;
            case Style.Center :
               key.SetValue(@"WallpaperStyle", "0") ; 
               key.SetValue(@"TileWallpaper", "0") ; 
               break;
            case Style.Fit :
               key.SetValue(@"WallpaperStyle", "6") ; 
               key.SetValue(@"TileWallpaper", "0") ;
               break;
            case Style.NoChange :
               break;
         }
         key.Close();
      }
   }
}
"@

[Wallpaper.Setter]::SetWallpaper( '<curitem>', 'Stretch' )

HEREDOC;

  writefile("<xyscripts>\tempPS.ps1", $PS);
  run ("%winsysdir%\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -File ""<xyscripts>\tempPS.ps1"""), ,2,0;
Edit: Updated script to provide a style parameter; Center, Fit, Stretch, or NoChange. Change the second parameter to suit. If you never use the 'tile' style you could delete the 3 lines: key.SetValue(@"TileWallpaper", "0") ;
Windows 11, 22H2 Build 22621.1555 at 100% 2560x1440

bdeshi
Posts: 4249
Joined: 12 Mar 2014 17:27
Location: Asteroid B-612 / Dhaka
Contact:

Re: Set as desktop background

Post by bdeshi »

Nice!
Those registry keys are the ... key. My settings were already optimum so didn't think of supporting them in the code.
Icon Names | Onyx | Undocumented Commands | xypcre
[ this user is asleep ]

Post Reply