我自己用這些代碼做的小app如下: 第一種,user32.dll /// <summary> /// 調用外部切換壁紙的方法 /// </summary> /// <param name="uAction"></param> /// <param name="uParam"></param> /// ...
我自己用這些代碼做的小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
以上。