Skip to content

Instantly share code, notes, and snippets.

@hinchley
Last active June 6, 2023 08:50
Show Gist options
  • Save hinchley/f5b10253da11de50431a384918e68839 to your computer and use it in GitHub Desktop.
Save hinchley/f5b10253da11de50431a384918e68839 to your computer and use it in GitHub Desktop.
Add-Type -TypeDefinition @"
using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Linq;
using Microsoft.Win32;
namespace WinAPI {
class DesktopWallpaper
{
[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public enum DesktopSlideshowOptions
{
ShuffleImages = 0x01
}
public enum DesktopSlideshowState
{
Enabled = 0x01,
Slideshow = 0x02,
DisabledByRemoteSession = 0x04
}
public enum DesktopSlideshowDirection
{
Forward = 0,
Backward = 1
}
public enum DesktopWallpaperPosition
{
Center = 0,
Tile = 1,
Stretch = 2,
Fit = 3,
Fill = 4,
Span = 5
}
[ComImport, Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDesktopWallpaper
{
void SetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.LPWStr)] string wallpaper);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetMonitorDevicePathAt(uint monitorIndex);
[return: MarshalAs(UnmanagedType.U4)]
uint GetMonitorDevicePathCount();
[return: MarshalAs(UnmanagedType.Struct)]
Rect GetMonitorRECT([MarshalAs(UnmanagedType.LPWStr)] string monitorID);
void SetBackgroundColor([MarshalAs(UnmanagedType.U4)] uint color);
[return: MarshalAs(UnmanagedType.U4)]
uint GetBackgroundColor();
void SetPosition([MarshalAs(UnmanagedType.I4)] DesktopWallpaperPosition position);
[return: MarshalAs(UnmanagedType.I4)]
DesktopWallpaperPosition GetPosition();
void SetSlideshow(IntPtr items);
IntPtr GetSlideshow();
void SetSlideshowOptions(DesktopSlideshowDirection options, uint slideshowTick);
[PreserveSig]
uint GetSlideshowOptions(out DesktopSlideshowDirection options, out uint slideshowTick);
void AdvanceSlideshow([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.I4)] DesktopSlideshowDirection direction);
DesktopSlideshowDirection GetStatus();
bool Enable();
}
public class WallpaperWrapper
{
static readonly Guid CLSID_DesktopWallpaper = new Guid("{C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD}");
public static IDesktopWallpaper GetWallpaper()
{
Type typeDesktopWallpaper = Type.GetTypeFromCLSID(CLSID_DesktopWallpaper);
return (IDesktopWallpaper)Activator.CreateInstance(typeDesktopWallpaper);
}
}
}
public class DPI {
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData);
public enum DeviceCap {
VERTRES = 10,
DESKTOPVERTRES = 117
}
public static float scaling(String name) {
var hdc = CreateDC(name, "", "", IntPtr.Zero);
Graphics g = Graphics.FromHdc(hdc);
IntPtr desktop = g.GetHdc();
int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
return (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
}
}
public class Wallpaper
{
public static void Main()
{
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
Application.Run();
}
static void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
string path = "C:\\Windows\\Web\\4K\\Wallpaper\\Windows\\img0_{0}.jpg";
string[] resolutions = {
"768x1024",
"768x1366",
"1024x768",
"1200x1920",
"1366x768",
"1600x2560",
"2160x3840",
"2560x1600",
"3840x2160"
};
uint counter = 0;
string wallpaper = "";
foreach (Screen screen in Screen.AllScreens) {
float scaling = DPI.scaling(screen.DeviceName);
int width = (int)(screen.Bounds.Width * scaling);
int height = (int)(screen.Bounds.Height * scaling);
string resolution = width + "x" + height;
if (! resolutions.Contains(resolution)) {
if (width > height) {
resolution = "3840x2160";
} else {
resolution = "2160x3840";
}
}
wallpaper = path.Replace("{0}", resolution);
if (File.Exists(wallpaper)) {
SetWallpaper(counter++, wallpaper);
}
}
}
public static void SetWallpaper(uint id, string path)
{
DesktopWallpaper.IDesktopWallpaper wallpaper = DesktopWallpaper.WallpaperWrapper.GetWallpaper();
if (id <= wallpaper.GetMonitorDevicePathCount()) {
string monitor = wallpaper.GetMonitorDevicePathAt(id);
wallpaper.SetWallpaper(monitor, path);
wallpaper.SetPosition(DesktopWallpaper.DesktopWallpaperPosition.Fill);
}
Marshal.ReleaseComObject(wallpaper);
}
}
}
"@ -ReferencedAssemblies 'System.Drawing.dll', System.Windows.Forms
[WinAPI.Wallpaper]::Main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment