Page 2 of 2

Re: Set as desktop background

Posted: 26 May 2017 21:42
by SammaySarkar
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.

Re: Set as desktop background

Posted: 27 May 2017 16:43
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") ;

Re: Set as desktop background

Posted: 28 May 2017 08:35
by SammaySarkar
Nice!
Those registry keys are the ... key. My settings were already optimum so didn't think of supporting them in the code.