Fix taskbar icon (#1271)

This commit is contained in:
2026-01-12 01:18:30 +01:00
parent 1da19b2e1d
commit fbc0c39a37
5 changed files with 64 additions and 3 deletions
+4
View File
@@ -6,6 +6,10 @@ namespace Daybreak.Shared.Utils;
public static class NativeMethods
{
public const uint WM_SETICON = 0x0080;
public const nint ICON_BIG = 1; // 32x32 (taskbar icon)
public const nint ICON_SMALL = 0; // 16x16 (title bar icon)
public const int STD_OUTPUT_HANDLE = -11;
public const int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
public const int ENABLE_PROCESSED_OUTPUT = 0x0001;
+10
View File
@@ -129,6 +129,16 @@
<DaybreakInjectorSources Include="..\Daybreak.Shared\**\*.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="Daybreak.ico" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Daybreak.ico">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<!--
This is a workaround to determine where to place the dependency projects
It will first check if PublishDir is set.
+2
View File
@@ -1,4 +1,5 @@
using Daybreak.Shared.Services.Screens;
using Daybreak.Shared.Utils;
using Daybreak.Views;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -39,6 +40,7 @@ public partial class Launcher
.SetSmoothScrollingEnabled(true)
.SetChromeless(true);
app.MainWindow.SetLogVerbosity(0);
app.MainWindow.RegisterWindowCreatedHandler((_, __) => SetupWindowIcon(app));
app.MainWindow.RegisterWindowCreatedHandler((_, __) => SetupRoundedWindows(app));
app.MainWindow.RegisterWindowCreatedHandler((_, __) => SetupBorderless(app));
app.MainWindow.RegisterWindowCreatedHandler((_, __) => StartHostedServices(app, cts));
+48
View File
@@ -8,17 +8,22 @@ using Photino.Blazor;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;
using System.Drawing;
using System.Extensions.Core;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Daybreak.Launch;
public partial class Launcher
{
private const string IconResourceName = "Daybreak.Daybreak.ico";
public const string OutputTemplate = "[{Timestamp:yyyy-MM-dd HH:mm:ss}] {Level:u4}: [{EnvironmentName}] [{ThreadId}:{ThreadName}] [{SourceContext}]{NewLine}{Message:lj}{NewLine}{Exception}";
private static nint OriginalWndProc;
private static NativeMethods.WndProcDelegate? WndProcDelegate;
private static Icon? WindowIcon;
public static void SetupLogging(IServiceCollection services)
{
@@ -130,6 +135,49 @@ public partial class Launcher
0x0001 | 0x0002 | 0x0004 | 0x0020); // SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED
}
private static void SetupWindowIcon(PhotinoBlazorApp app)
{
var hwnd = app.MainWindow.WindowHandle;
if (hwnd == IntPtr.Zero)
{
return;
}
var scopedLogger = app.Services.GetRequiredService<ILogger<Launcher>>().CreateScopedLogger();
try
{
var assembly = Assembly.GetExecutingAssembly();
if (assembly.GetManifestResourceInfo(IconResourceName) is not ManifestResourceInfo info)
{
scopedLogger.LogWarning("Icon resource '{IconResourceName}' not found in assembly.", IconResourceName);
return;
}
var embeddedIconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(IconResourceName);
if (embeddedIconStream is null)
{
scopedLogger.LogWarning("Icon resource '{IconResourceName}' stream is null.", IconResourceName);
return;
}
WindowIcon = new Icon(embeddedIconStream);
var hIcon = WindowIcon.Handle;
if (hIcon is 0)
{
scopedLogger.LogWarning("Failed to get handle for window icon.");
return;
}
NativeMethods.SendMessage(hwnd, NativeMethods.WM_SETICON, NativeMethods.ICON_BIG, hIcon);
NativeMethods.SendMessage(hwnd, NativeMethods.WM_SETICON, NativeMethods.ICON_SMALL, hIcon);
scopedLogger.LogDebug("Window icon set successfully.");
}
catch(Exception ex)
{
scopedLogger.LogError(ex, "Failed to set window icon.");
}
}
private static nint WndProc(nint hwnd, uint msg, nint wParam, nint lParam)
{
if (msg == NativeMethods.WM_NCCALCSIZE && wParam != 0)
-3
View File
@@ -22,9 +22,6 @@ public partial class Launcher
[STAThread]
public static void Main(string[] args)
{
#if DEBUG
AllocateAnsiConsole();
#endif
var bootstrap = SetupBootstrap();
LaunchSequence(args, bootstrap);
}