我自己用这些代码做的小app如下:
第一种,user32.dll
/// <summary> /// 调用外部切换壁纸的方法 /// </summary> /// <param name="uAction"></param> /// <param name="uParam"></param> /// <param name="lpvParam"></param> /// <param name="fuWinIni"></param> /// <returns></returns> [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")] public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
就是一种很常用,好像兼容性最好的办法吧,但是,使用的局限性很大,多显示器情况下会导致所有显示器使用相同的壁纸!而且无法区分多个显示器
第二种,IActiveDesktop
public class ActiveDesktopCom { /// <summary> /// 壁纸的显示方式 /// </summary> public enum WPSTYLE { /// <summary> /// 居中 /// </summary> CENTER = 0, /// <summary> /// 平铺 /// </summary> TILE = 1, /// <summary> /// 拉伸 /// </summary> STRETCH = 2, /// <summary> /// 适应 /// </summary> adapt = 3, /// <summary> /// 填充 /// </summary> FILL = 4, /// <summary> /// 跨区 /// </summary> Transregional = 5, } struct WALLPAPEROPT { public int dwSize; public WPSTYLE dwStyle; } struct COMPONENTSOPT { public int dwSize; [MarshalAs(UnmanagedType.Bool)] public bool fEnableComponents; [MarshalAs(UnmanagedType.Bool)] public bool fActiveDesktop; } struct COMPPOS { public const int COMPONENT_TOP = 0x3FFFFFFF; public const int COMPONENT_DEFAULT_LEFT = 0xFFFF; public const int COMPONENT_DEFAULT_TOP = 0xFFFF; public int dwSize; public int iLeft; public int iTop; public int dwWidth; public int dwHeight; public int izIndex; [MarshalAs(UnmanagedType.Bool)] public bool fCanResize; [MarshalAs(UnmanagedType.Bool)] public bool fCanResizeX; [MarshalAs(UnmanagedType.Bool)] public bool fCanResizeY; public int iPreferredLeftPercent; public int iPreferredTopPercent; } [Flags] enum ITEMSTATE { NORMAL = 0x00000001, FULLSCREEN = 00000002, SPLIT = 0x00000004, VALIDSIZESTATEBITS = NORMAL | SPLIT | FULLSCREEN, VALIDSTATEBITS = NORMAL | SPLIT | FULLSCREEN | unchecked((int)0x80000000) | 0x40000000 } struct COMPSTATEINFO { public int dwSize; public int iLeft; public int iTop; public int dwWidth; public int dwHeight; public int dwItemState; } enum COMP_TYPE { HTMLDOC = 0, PICTURE = 1, WEBSITE = 2, CONTROL = 3, CFHTML = 4, MAX = 4 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] struct COMPONENT { private const int INTERNET_MAX_URL_LENGTH = 2084; // = // INTERNET_MAX_SCHEME_LENGTH (32) + "://\0".Length + // INTERNET_MAX_PATH_LENGTH (2048) public int dwSize; public int dwID; public COMP_TYPE iComponentType; [MarshalAs(UnmanagedType.Bool)] public bool fChecked; [MarshalAs(UnmanagedType.Bool)] public bool fDirty; [MarshalAs(UnmanagedType.Bool)] public bool fNoScroll; public COMPPOS cpPos; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string wszFriendlyName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = INTERNET_MAX_URL_LENGTH)] public string wszSource; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = INTERNET_MAX_URL_LENGTH)] public string wszSubscribedURL; #if AD_IE5 public int dwCurItemState; public COMPSTATEINFO csiOriginal; public COMPSTATEINFO csiRestored; #endif } enum DTI_ADTIWUI { DTI_ADDUI_DEFAULT = 0x00000000, DTI_ADDUI_DISPSUBWIZARD = 0x00000001, DTI_ADDUI_POSITIONITEM = 0x00000002, } [Flags] enum AD_APPLY { SAVE = 0x00000001, HTMLGEN = 0x00000002, REFRESH = 0x00000004, ALL = SAVE | HTMLGEN | REFRESH, FORCE = 0x00000008, BUFFERED_REFRESH = 0x00000010, DYNAMICREFRESH = 0x00000020 } [Flags] enum COMP_ELEM { TYPE = 0x00000001, CHECKED = 0x00000002, DIRTY = 0x00000004, NOSCROLL = 0x00000008, POS_LEFT = 0x00000010, POS_TOP = 0x00000020, SIZE_WIDTH = 0x00000040, SIZE_HEIGHT = 0x00000080, POS_ZINDEX = 0x00000100, SOURCE = 0x00000200, FRIENDLYNAME = 0x00000400, SUBSCRIBEDURL = 0x00000800, ORIGINAL_CSI = 0x00001000, RESTORED_CSI = 0x00002000, CURITEMSTATE = 0x00004000, ALL = TYPE | CHECKED | DIRTY | NOSCROLL | POS_LEFT | SIZE_WIDTH | SIZE_HEIGHT | POS_ZINDEX | SOURCE | FRIENDLYNAME | POS_TOP | SUBSCRIBEDURL | ORIGINAL_CSI | RESTORED_CSI | CURITEMSTATE } [Flags] enum ADDURL { SILENT = 0x0001 } [ ComImport(), Guid("F490EB00-1240-11D1-9888-006097DEACF9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown) ] interface IActiveDesktop { void ApplyChanges(AD_APPLY dwFlags); void GetWallpaper([MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pwszWallpaper, int cchWallpaper, int dwReserved); void SetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string pwszWallpaper, int dwReserved); void GetWallpaperOptions(ref WALLPAPEROPT pwpo, int dwReserved); void SetWallpaperOptions([In] ref WALLPAPEROPT pwpo, int dwReserved); void GetPattern([MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pwszPattern, int cchPattern, int dwReserved); void SetPattern([MarshalAs(UnmanagedType.LPWStr)] string pwszPattern, int dwReserved); void GetDesktopItemOptions(ref COMPONENTSOPT pco, int dwReserved); void SetDesktopItemOptions([In] ref COMPONENTSOPT pco, int dwReserved); void AddDesktopItem([In] ref COMPONENT pcomp, int dwReserved); void AddDesktopItemWithUI(IntPtr hwnd, [In] ref COMPONENT pcomp, DTI_ADTIWUI dwFlags); void ModifyDesktopItem([In] ref COMPONENT pcomp, COMP_ELEM dwFlags); void RemoveDesktopItem([In] ref COMPONENT pcomp, int dwReserved); void GetDesktopItemCount(out int lpiCount, int dwReserved); void GetDesktopItem(int nComponent, ref COMPONENT pcomp, int dwReserved); void GetDesktopItemByID(IntPtr dwID, ref COMPONENT pcomp, int dwReserved); void GenerateDesktopItemHtml([MarshalAs(UnmanagedType.LPWStr)] string pwszFileName, [In] ref COMPONENT pcomp, int dwReserved); void AddUrl(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszSource, [In] ref COMPONENT pcomp, ADDURL dwFlags); void GetDesktopItemBySource([MarshalAs(UnmanagedType.LPWStr)] string pwszSource, ref COMPONENT pcomp, int dwReserved); } [ ComImport(), Guid("75048700-EF1F-11D0-9888-006097DEACF9") ] class ActiveDesktop /* : IActiveDesktop */ { } public class OLE32DLL { [DllImport("ole32.dll", SetLastError = true)] public static extern int CoUninitialize(); [DllImport("ole32.dll", SetLastError = true)] public static extern int CoInitialize(int pvReserved); [DllImport("ole32.dll", CharSet = CharSet.Unicode)] public static extern int CLSIDFromString(string lpsz, out Guid pclsid); [DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)] [return: MarshalAs(UnmanagedType.Interface)] public static extern object CoCreateInstance( [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, int pUnkOuter, int dwClsContext, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid ); } /// <summary> /// 兼容win7版本以前版本系统的修改壁纸 /// </summary> /// <param name="filename"></param> /// <returns></returns> public static bool SetActiveDesktop(string filename, WPSTYLE dwstyle = WPSTYLE.FILL) { try { const int NULL = 0; const int S_OK = 0; const int CLSCTX_ALL = 23; Guid IID_IActiveDesktop = new Guid("F490EB00-1240-11D1-9888-006097DEACF9"); Guid CLSID_ActiveDesktop = new Guid("75048700-EF1F-11D0-9888-006097DEACF9"); if (System.Threading.Thread.CurrentThread.GetApartmentState() != System.Threading.ApartmentState.STA && OLE32DLL.CoInitialize(NULL) < S_OK) throw new Exception("Failed to initialize COM library."); //object ppvObject = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_ALL, IID_IActiveDesktop); //ActiveDesktop ad = new ActiveDesktop(); object ad = OLE32DLL.CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_ALL, IID_IActiveDesktop); IActiveDesktop iad = (IActiveDesktop)ad; if (iad != null) { //WPSTYLE_CENTER 居中 0 //WPSTYLE_TILE 平铺 1 //WPSTYLE_STRETCH 拉伸 2 //WPSTYLE dwstyle = WPSTYLE.FILL;//这里调整显示背景图片样式 WALLPAPEROPT wp = new WALLPAPEROPT(); wp.dwSize = System.Runtime.InteropServices.Marshal.SizeOf(wp); wp.dwStyle = dwstyle; iad.SetWallpaperOptions(ref wp, 0); iad.SetWallpaper(filename, 0); iad.ApplyChanges(AD_APPLY.ALL);//AD_APPLY.ALL); //System.Runtime.InteropServices.Marshal.ReleaseComObject(ad); //ad = null; } OLE32DLL.CoUninitialize(); return true; } catch { return false; } } }
以上代码也是我从网上流传的代码中复制到的,但是网上流传的代码中其中有一部分代码是有问题的:
ActiveDesktop ad = new ActiveDesktop();
就是这里,这个代码不可运行,因为这种接口中IActiveDesktop对象不能通过类型强转得到,因为ActiveDesktop实例本身就不是通过new方式得到的,而我的代码中已经将这个错误进行了修改,并且win10系统中已经确认运行无误。
第三种,IDesktopWallpaper也是一种Com接口(只支持win8以上系统,且支持多显示器独立设置壁纸)
/// <summary> /// 使用IDesktopWallpaper方式切换壁纸的方法 /// </summary> public class DesktopWallpaperCom { [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); void GetSlideshowOptions(out DesktopSlideshowDirection options, out uint slideshowTick); void AdvanceSlideshow([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.I4)] DesktopSlideshowDirection direction); DesktopSlideshowDirection GetStatus(); bool Enable(); } [ComImport] [Guid("C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD")] public class DesktopWallpaper { } [Flags] public enum DesktopSlideshowOptions { None = 0, ShuffleImages = 0x01 } [Flags] public enum DesktopSlideshowState { None = 0, 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, } [StructLayout(LayoutKind.Sequential)] public struct Rect { public int Left; public int Top; public int Right; public int Bottom; } /// <summary> /// 获取所有的显示器的ID,用于在设置壁纸中用到的显示器的id /// </summary> /// <returns></returns> public static string[] GetDeskMonitorIds() { try { DesktopWallpaper ad = new DesktopWallpaper(); IDesktopWallpaper iad = (IDesktopWallpaper)ad; List<string> mids = new List<string>(); if (iad != null) { for (uint i = 0; i < iad.GetMonitorDevicePathCount(); i++) { mids.Add(iad.GetMonitorDevicePathAt(i)); } } System.Runtime.InteropServices.Marshal.ReleaseComObject(ad); ad = null; return mids.ToArray(); } catch { return null; } } /// <summary> /// 新版的win8以上版本调用修改桌面的方法 /// </summary> /// <param name="filename"></param> /// <returns></returns> public static bool SetDesktopWallpaper(string filename, string mid = null) { try { DesktopWallpaper ad = new DesktopWallpaper(); IDesktopWallpaper iad = (IDesktopWallpaper)ad; if (iad != null) { iad.SetWallpaper(mid ?? string.Empty, filename); } System.Runtime.InteropServices.Marshal.ReleaseComObject(ad); ad = null; return true; } catch { return false; } } }
这是win8系统以上才支持的一种桌面壁纸切换方法,可以支持多显示器独立进行壁纸的设置
最后放上我自己做的壁纸切换工具,可以自适应切换壁纸的方式,且支持多显示器壁纸切换管理和收藏,还有可以添加自动切换壁纸的系统任务,其中的有个vbs脚本是用于壁纸切换的,杀软一般都会报毒,但是要是文件没了就无法切换壁纸了。
下载地址是:https://comm.zhaimaojun.cn/AllSources/ToolDetail/?tid=9379
以上。