1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-10-16 14:10:45 +00:00
msfs-popout-panel-manager/MainApp/App.xaml.cs

190 lines
9.5 KiB
C#
Raw Normal View History

2023-07-12 22:41:31 +00:00
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
2024-02-28 02:44:21 +00:00
using MSFSPopoutPanelManager.MainApp.AppWindow;
2023-07-12 22:41:31 +00:00
using MSFSPopoutPanelManager.MainApp.ViewModel;
using MSFSPopoutPanelManager.Orchestration;
using MSFSPopoutPanelManager.Shared;
2022-07-23 19:23:32 +00:00
using MSFSPopoutPanelManager.WindowsAgent;
2022-01-27 13:40:04 +00:00
using System;
2023-08-02 03:39:03 +00:00
using System.Diagnostics;
using System.Linq;
using System.Reflection;
2022-01-27 13:40:04 +00:00
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
2023-07-12 22:41:31 +00:00
using System.Windows.Threading;
2024-02-28 02:44:21 +00:00
using Application = System.Windows.Application;
2022-01-27 13:40:04 +00:00
2023-07-12 22:41:31 +00:00
namespace MSFSPopoutPanelManager.MainApp
2022-01-27 13:40:04 +00:00
{
2024-02-28 02:44:21 +00:00
public partial class App
2022-01-27 13:40:04 +00:00
{
2024-02-28 02:44:21 +00:00
public SharedStorage SharedStorage;
2023-07-12 22:41:31 +00:00
2024-02-28 02:44:21 +00:00
public static IHost AppHost { get; private set; }
2023-07-12 22:41:31 +00:00
protected override async void OnStartup(StartupEventArgs e)
2022-01-27 13:40:04 +00:00
{
2022-07-23 19:23:32 +00:00
DpiAwareness.Enable();
2022-01-27 13:40:04 +00:00
2023-07-12 22:41:31 +00:00
// Must run this first
2023-08-02 03:39:03 +00:00
if(IsRunning())
{
//app is already running! Exiting the application
Application.Current.Shutdown();
}
else
{
2024-02-28 02:44:21 +00:00
// Setup all unhandled exception handlers
2023-08-02 03:39:03 +00:00
Dispatcher.UnhandledException += HandleDispatcherException;
TaskScheduler.UnobservedTaskException += HandleTaskSchedulerUnobservedTaskException;
AppDomain.CurrentDomain.UnhandledException += HandledDomainException;
2023-07-12 22:41:31 +00:00
2024-02-28 02:44:21 +00:00
// Setup all data storage objects
SharedStorage = new SharedStorage();
SharedStorage.AppSettingData.ReadSettings();
SharedStorage.ProfileData.ReadProfiles();
2023-08-02 03:39:03 +00:00
// Setup dependency injections
AppHost = Host.CreateDefaultBuilder()
2024-02-28 02:44:21 +00:00
.ConfigureServices((_, services) =>
2023-08-02 03:39:03 +00:00
{
2024-02-28 02:44:21 +00:00
services.AddSingleton<AppMainWindow>();
services.AddSingleton(s => new AppOrchestrator(SharedStorage, s.GetRequiredService<PanelConfigurationOrchestrator>(), s.GetRequiredService<FlightSimOrchestrator>(), s.GetRequiredService<HelpOrchestrator>(), s.GetRequiredService<KeyboardOrchestrator>()));
services.AddSingleton(s => new ProfileOrchestrator(SharedStorage));
services.AddSingleton(s => new PanelSourceOrchestrator(SharedStorage, s.GetRequiredService<FlightSimOrchestrator>()));
2024-03-03 05:02:21 +00:00
services.AddSingleton(s => new PanelPopOutOrchestrator(SharedStorage, s.GetRequiredService<FlightSimOrchestrator>(), s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelConfigurationOrchestrator>(), s.GetRequiredService<KeyboardOrchestrator>()));
2024-03-01 11:28:09 +00:00
services.AddSingleton(s => new PanelConfigurationOrchestrator(SharedStorage, s.GetRequiredService<FlightSimOrchestrator>(), s.GetRequiredService<KeyboardOrchestrator>()));
2024-02-28 02:44:21 +00:00
services.AddSingleton(s => new FlightSimOrchestrator(SharedStorage));
2024-03-01 11:28:09 +00:00
services.AddSingleton(s => new KeyboardOrchestrator(SharedStorage));
2024-02-28 02:44:21 +00:00
services.AddSingleton(s => new HelpOrchestrator());
services.AddSingleton(s => new OrchestratorUiHelper(SharedStorage, s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelPopOutOrchestrator>()));
services.AddSingleton(s => new ApplicationViewModel(SharedStorage, s.GetRequiredService<AppOrchestrator>()));
services.AddSingleton(s => new HelpViewModel(SharedStorage, s.GetRequiredService<HelpOrchestrator>()));
services.AddSingleton(s => new ProfileCardListViewModel(SharedStorage, s.GetRequiredService<ProfileOrchestrator>(), s.GetRequiredService<PanelSourceOrchestrator>()));
services.AddSingleton(s => new ProfileCardViewModel(SharedStorage, s.GetRequiredService<ProfileOrchestrator>(), s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelConfigurationOrchestrator>(), s.GetRequiredService<PanelPopOutOrchestrator>()));
services.AddSingleton(s => new TrayIconViewModel(SharedStorage, s.GetRequiredService<AppOrchestrator>(), s.GetRequiredService<PanelPopOutOrchestrator>()));
2024-03-03 05:02:21 +00:00
services.AddSingleton(s => new PreferenceDrawerViewModel(SharedStorage, s.GetRequiredService<KeyboardOrchestrator>()));
2024-02-28 02:44:21 +00:00
services.AddTransient(s => new AddProfileViewModel(SharedStorage, s.GetRequiredService<ProfileOrchestrator>(), s.GetRequiredService<PanelSourceOrchestrator>()));
services.AddTransient(s => new PopOutPanelListViewModel(SharedStorage));
2024-03-03 05:02:21 +00:00
services.AddTransient(s => new PopOutPanelConfigCardViewModel(SharedStorage, s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelConfigurationOrchestrator>(), s.GetRequiredService<KeyboardOrchestrator>()));
2024-02-28 02:44:21 +00:00
services.AddTransient(s => new PopOutPanelSourceCardViewModel(SharedStorage, s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelConfigurationOrchestrator>()));
services.AddTransient(s => new PopOutPanelSourceLegacyCardViewModel(SharedStorage, s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelConfigurationOrchestrator>()));
services.AddTransient(s => new PanelConfigFieldViewModel(SharedStorage, s.GetRequiredService<PanelConfigurationOrchestrator>()));
services.AddTransient(s => new PanelCoorOverlayViewModel(SharedStorage));
services.AddTransient(s => new MessageWindowViewModel(SharedStorage, s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelPopOutOrchestrator>()));
services.AddTransient(s => new HudBarViewModel(SharedStorage, s.GetRequiredService<FlightSimOrchestrator>()));
services.AddTransient(s => new NumPadViewModel(SharedStorage));
2023-07-12 22:41:31 +00:00
2023-08-02 03:39:03 +00:00
}).Build();
2023-07-12 22:41:31 +00:00
2023-08-02 03:39:03 +00:00
await AppHost!.StartAsync();
2023-07-12 22:41:31 +00:00
2023-08-02 03:39:03 +00:00
// Startup window (must come after DPI setup above)
2024-02-28 02:44:21 +00:00
MainWindow = AppHost.Services.GetRequiredService<AppMainWindow>();
MainWindow?.Show();
2023-07-12 22:41:31 +00:00
2023-08-02 03:39:03 +00:00
// Setup orchestration UI handler
2024-02-28 02:44:21 +00:00
App.AppHost.Services.GetRequiredService<OrchestratorUiHelper>();
2023-07-12 22:41:31 +00:00
2023-08-02 03:39:03 +00:00
// Setup message window dialog
var messageWindow = new MessageWindow();
messageWindow.Show();
2023-07-12 22:41:31 +00:00
2023-08-02 03:39:03 +00:00
base.OnStartup(e);
}
2023-07-12 22:41:31 +00:00
}
2023-08-02 03:39:03 +00:00
private bool IsRunning()
2023-07-12 22:41:31 +00:00
{
2024-02-28 02:44:21 +00:00
var assembly = Assembly.GetEntryAssembly();
if (assembly == null)
return false;
var assemblyName = assembly.GetName().Name;
if (string.IsNullOrEmpty(assemblyName))
return false;
return Process.GetProcesses().Count(p => p.ProcessName.Contains(assemblyName)) > 1;
2022-01-27 13:40:04 +00:00
}
2024-02-28 02:44:21 +00:00
private void HandleTaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
2022-01-27 13:40:04 +00:00
{
2022-07-23 19:23:32 +00:00
FileLogger.WriteException(e.Exception.Message, e.Exception);
2022-01-27 13:40:04 +00:00
}
2023-07-12 22:41:31 +00:00
private void HandleDispatcherException(object sender, DispatcherUnhandledExceptionEventArgs e)
2022-01-27 13:40:04 +00:00
{
e.Handled = true;
2022-06-30 23:53:08 +00:00
if (e.Exception.Message != "E_INVALIDARG") // Ignore this error
{
2022-07-23 19:23:32 +00:00
FileLogger.WriteException(e.Exception.Message, e.Exception);
2022-06-30 23:53:08 +00:00
}
2022-01-27 13:40:04 +00:00
}
private void HandledDomainException(object sender, UnhandledExceptionEventArgs e)
{
var exception = (Exception)e.ExceptionObject;
2022-07-23 19:23:32 +00:00
FileLogger.WriteException(exception.Message, exception);
2022-01-27 13:40:04 +00:00
}
}
2024-02-28 02:44:21 +00:00
public enum ProcessDpiAwareness
2022-01-27 13:40:04 +00:00
{
2024-02-28 02:44:21 +00:00
//PROCESS_DPI_UNAWARE = 0,
//PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
2022-01-27 13:40:04 +00:00
}
2024-02-28 02:44:21 +00:00
public enum DpiAwarenessContext
2022-01-27 13:40:04 +00:00
{
2024-02-28 02:44:21 +00:00
//DPI_AWARENESS_CONTEXT_UNAWARE = 16,
//DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 17,
//DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 18,
2022-01-27 13:40:04 +00:00
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 34
}
public static class DpiAwareness
{
2022-07-23 19:23:32 +00:00
public static void Enable()
2022-01-27 13:40:04 +00:00
{
// Windows 8.1 added support for per monitor DPI
if (Environment.OSVersion.Version >= new Version(6, 3, 0))
{
// Windows 10 creators update added support for per monitor v2
if (Environment.OSVersion.Version >= new Version(10, 0, 15063))
{
2024-02-28 02:44:21 +00:00
SetProcessDpiAwarenessContext(DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
2022-01-27 13:40:04 +00:00
}
else
{
2024-02-28 02:44:21 +00:00
SetProcessDpiAwareness(ProcessDpiAwareness.PROCESS_PER_MONITOR_DPI_AWARE);
2022-01-27 13:40:04 +00:00
}
}
else
{
SetProcessDPIAware();
}
2022-07-23 19:23:32 +00:00
var process = WindowProcessManager.GetApplicationProcess();
2024-02-28 02:44:21 +00:00
GetProcessDpiAwareness(process.Handle, out _);
2022-01-27 13:40:04 +00:00
}
[DllImport("User32.dll")]
2024-02-28 02:44:21 +00:00
internal static extern bool SetProcessDpiAwarenessContext(DpiAwarenessContext dpiFlag);
2022-01-27 13:40:04 +00:00
[DllImport("SHCore.dll")]
2024-02-28 02:44:21 +00:00
internal static extern bool SetProcessDpiAwareness(ProcessDpiAwareness awareness);
2022-01-27 13:40:04 +00:00
[DllImport("User32.dll")]
internal static extern bool SetProcessDPIAware();
[DllImport("SHCore.dll", SetLastError = true)]
2024-02-28 02:44:21 +00:00
internal static extern void GetProcessDpiAwareness(IntPtr hProcess, out ProcessDpiAwareness awareness);
2022-01-27 13:40:04 +00:00
}
2022-06-30 23:53:08 +00:00
}