Skip to content

Commit 48f3173

Browse files
committed
Init
1 parent 8260de7 commit 48f3173

File tree

9 files changed

+170
-88
lines changed

9 files changed

+170
-88
lines changed

src/Files.App/Actions/Content/Background/BaseSetAsAction.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Copyright (c) 2024 Files Community
22
// Licensed under the MIT License. See the LICENSE.
33

4+
using Microsoft.UI.Xaml.Controls;
5+
using Windows.Foundation.Metadata;
6+
47
namespace Files.App.Actions
58
{
69
internal abstract class BaseSetAsAction : ObservableObject, IAction
@@ -28,6 +31,21 @@ public BaseSetAsAction()
2831

2932
public abstract Task ExecuteAsync(object? parameter = null);
3033

34+
protected async void ShowErrorDialog(string message)
35+
{
36+
var errorDialog = new ContentDialog()
37+
{
38+
Title = "FailedToSetBackground".GetLocalizedResource(),
39+
Content = message,
40+
PrimaryButtonText = "OK".GetLocalizedResource(),
41+
};
42+
43+
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
44+
errorDialog.XamlRoot = MainWindow.Instance.Content.XamlRoot;
45+
46+
await errorDialog.TryShowAsync();
47+
}
48+
3149
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
3250
{
3351
switch (e.PropertyName)

src/Files.App/Actions/Content/Background/SetAsLockscreenBackgroundAction.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace Files.App.Actions
55
{
66
internal sealed class SetAsLockscreenBackgroundAction : BaseSetAsAction
77
{
8+
private readonly IWindowsWallpaperService WindowsWallpaperService = Ioc.Default.GetRequiredService<IWindowsWallpaperService>();
9+
810
public override string Label
911
=> "SetAsLockscreen".GetLocalizedResource();
1012

@@ -20,10 +22,19 @@ public override RichGlyph Glyph
2022

2123
public override Task ExecuteAsync(object? parameter = null)
2224
{
23-
if (context.SelectedItem is not null)
24-
return WallpaperHelpers.SetAsBackgroundAsync(WallpaperType.LockScreen, context.SelectedItem.ItemPath);
25+
if (context.SelectedItem is null)
26+
return Task.CompletedTask;
27+
28+
try
29+
{
30+
return WindowsWallpaperService.SetLockScreenWallpaper(context.SelectedItem.ItemPath);
31+
}
32+
catch (Exception ex)
33+
{
34+
ShowErrorDialog(ex.Message);
2535

26-
return Task.CompletedTask;
36+
return Task.CompletedTask;
37+
}
2738
}
2839
}
2940
}

src/Files.App/Actions/Content/Background/SetAsSlideshowBackgroundAction.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace Files.App.Actions
55
{
66
internal sealed class SetAsSlideshowBackgroundAction : BaseSetAsAction
77
{
8+
private readonly IWindowsWallpaperService WindowsWallpaperService = Ioc.Default.GetRequiredService<IWindowsWallpaperService>();
9+
810
public override string Label
911
=> "SetAsSlideshow".GetLocalizedResource();
1012

@@ -21,7 +23,15 @@ public override RichGlyph Glyph
2123
public override Task ExecuteAsync(object? parameter = null)
2224
{
2325
var paths = context.SelectedItems.Select(item => item.ItemPath).ToArray();
24-
WallpaperHelpers.SetSlideshow(paths);
26+
27+
try
28+
{
29+
WindowsWallpaperService.SetDesktopSlideshow(paths);
30+
}
31+
catch (Exception ex)
32+
{
33+
ShowErrorDialog(ex.Message);
34+
}
2535

2636
return Task.CompletedTask;
2737
}

src/Files.App/Actions/Content/Background/SetAsWallpaperBackgroundAction.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace Files.App.Actions
55
{
66
internal sealed class SetAsWallpaperBackgroundAction : BaseSetAsAction
77
{
8+
private readonly IWindowsWallpaperService WindowsWallpaperService = Ioc.Default.GetRequiredService<IWindowsWallpaperService>();
9+
810
public override string Label
911
=> "SetAsBackground".GetLocalizedResource();
1012

@@ -20,10 +22,21 @@ public override RichGlyph Glyph
2022

2123
public override Task ExecuteAsync(object? parameter = null)
2224
{
23-
if (context.SelectedItem is not null)
24-
return WallpaperHelpers.SetAsBackgroundAsync(WallpaperType.Desktop, context.SelectedItem.ItemPath);
25+
if (context.SelectedItem is null)
26+
return Task.CompletedTask;
27+
28+
try
29+
{
30+
WindowsWallpaperService.SetDesktopWallpaper(context.SelectedItem.ItemPath);
31+
32+
return Task.CompletedTask;
33+
}
34+
catch (Exception ex)
35+
{
36+
ShowErrorDialog(ex.Message);
2537

26-
return Task.CompletedTask;
38+
return Task.CompletedTask;
39+
}
2740
}
2841
}
2942
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
namespace Files.App.Data.Contracts
5+
{
6+
/// <summary>
7+
/// Provides service for manipulating shell wallpapers on Windows.
8+
/// </summary>
9+
public interface IWindowsWallpaperService
10+
{
11+
/// <summary>
12+
/// Sets desktop wallpaper using the specified image path.
13+
/// </summary>
14+
/// <param name="szPath">The image path to use to set as wallpaper.</param>
15+
void SetDesktopWallpaper(string szPath);
16+
17+
/// <summary>
18+
/// Sets desktop slideshow using the specified image paths.
19+
/// </summary>
20+
/// <param name="aszPaths">The image paths to use to set as slideshow.</param>
21+
void SetDesktopSlideshow(string[] aszPaths);
22+
23+
/// <summary>
24+
/// Gets lock screen wallpaper using the specified image path.
25+
/// </summary>
26+
/// <param name="szPath">The image path to use to set as lock screen wallpaper.</param>
27+
Task SetLockScreenWallpaper(string szPath);
28+
}
29+
}

src/Files.App/Helpers/Application/AppLifecycleHelper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ public static IHost ConfigureHost()
165165
.AddSingleton<ISidebarContext, SidebarContext>()
166166
// Services
167167
.AddSingleton<IWindowsIniService, WindowsIniService>()
168+
.AddSingleton<IWindowsWallpaperService, WindowsWallpaperService>()
168169
.AddSingleton<IAppThemeModeService, AppThemeModeService>()
169170
.AddSingleton<IDialogService, DialogService>()
170171
.AddSingleton<ICommonDialogService, CommonDialogService>()

src/Files.App/NativeMethods.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,7 @@ LocalAlloc
8989
InitializeAcl
9090
AddAce
9191
LocalFree
92+
IDesktopWallpaper
93+
DesktopWallpaper
94+
SHCreateShellItemArrayFromIDLists
95+
ILCreateFromPath
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
using Windows.Storage;
5+
using Windows.System.UserProfile;
6+
using Windows.Win32;
7+
using Windows.Win32.Foundation;
8+
using Windows.Win32.System.Com;
9+
using Windows.Win32.UI.Shell;
10+
using Windows.Win32.UI.Shell.Common;
11+
12+
namespace Files.App.Services
13+
{
14+
/// <inheritdoc cref="IWindowsWallpaperService"/>
15+
public sealed class WindowsWallpaperService : IWindowsWallpaperService
16+
{
17+
/// <inheritdoc/>
18+
public unsafe void SetDesktopWallpaper(string szPath)
19+
{
20+
PInvoke.CoCreateInstance(
21+
typeof(DesktopWallpaper).GUID,
22+
null,
23+
CLSCTX.CLSCTX_INPROC_SERVER,
24+
out IDesktopWallpaper desktopWallpaper);
25+
26+
desktopWallpaper.GetMonitorDevicePathCount(out var dwMonitorCount);
27+
28+
fixed (char* pszPath = szPath)
29+
{
30+
var pwszPath = new PWSTR(pszPath);
31+
32+
for (uint dwIndex = 0; dwIndex < dwMonitorCount; dwIndex++)
33+
{
34+
desktopWallpaper.GetMonitorDevicePathAt(dwIndex, out var pMonitorID);
35+
desktopWallpaper.SetWallpaper(pMonitorID, pwszPath);
36+
}
37+
}
38+
}
39+
40+
/// <inheritdoc/>
41+
public unsafe void SetDesktopSlideshow(string[] aszPaths)
42+
{
43+
PInvoke.CoCreateInstance(
44+
typeof(DesktopWallpaper).GUID,
45+
null,
46+
CLSCTX.CLSCTX_INPROC_SERVER,
47+
out IDesktopWallpaper desktopWallpaper);
48+
49+
var dwCount = (uint)aszPaths.Length;
50+
51+
fixed (ITEMIDLIST** idList = new ITEMIDLIST*[dwCount])
52+
{
53+
for (uint dwIndex = 0u; dwIndex < dwCount; dwIndex++)
54+
{
55+
var id = PInvoke.ILCreateFromPath(aszPaths[dwIndex]);
56+
idList[dwIndex] = id;
57+
}
58+
59+
// Get shell item array from images to use for slideshow
60+
PInvoke.SHCreateShellItemArrayFromIDLists(dwCount, idList, out var shellItemArray);
61+
62+
// Set slideshow
63+
desktopWallpaper.SetSlideshow(shellItemArray);
64+
}
65+
66+
// Set wallpaper to fill desktop.
67+
desktopWallpaper.SetPosition(DESKTOP_WALLPAPER_POSITION.DWPOS_FILL);
68+
}
69+
70+
/// <inheritdoc/>
71+
public async Task SetLockScreenWallpaper(string szPath)
72+
{
73+
IStorageFile sourceFile = await StorageFile.GetFileFromPathAsync(szPath);
74+
await LockScreen.SetImageFileAsync(sourceFile);
75+
}
76+
}
77+
}

src/Files.App/Utils/Global/WallpaperHelpers.cs

Lines changed: 0 additions & 81 deletions
This file was deleted.

0 commit comments

Comments
 (0)