use worker to start services and remove startup code from main form

This commit is contained in:
Vincent Maas committed 2024-03-16 13:22:27 +01:00
1 parent ab2ca92827
commit dd3a996172
32 files changed
+1564 -2287

No files matched your search

+12 -4
View File
@@ -27,7 +27,7 @@
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>false</UseWPF>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<ApplicationIcon>pngbarn.ico</ApplicationIcon>
<ApplicationIcon>Resources\pngbarn.ico</ApplicationIcon>
<SupportedOSPlatformVersion>10.0.20348.0</SupportedOSPlatformVersion>
<Copyright>2020-2024 Maassoft</Copyright>
<Authors>Maassoft</Authors>
@@ -65,6 +65,12 @@
<Compile Update="Forms\InfoPanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<Generator></Generator>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Services\Common\QuickAccessForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -81,13 +87,11 @@
<EmbeddedResource Include="Resources\LG_register.json" />
<EmbeddedResource Include="Resources\RC_coords.txt" />
<EmbeddedResource Include="Resources\LG_remote.jpg" />
<EmbeddedResource Include="Resources\pngbarn.ico" />
<Content Include="LgPresets.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="pngbarn.ico" />
</ItemGroup>
<ItemGroup>
<Folder Include="bin\x64\Debug\" />
</ItemGroup>
@@ -134,6 +138,10 @@
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Services\Samsung\SamsungPanel.resx">
<SubType>Designer</SubType>
</EmbeddedResource>
-1
View File
@@ -96,7 +96,6 @@
ClientSize = new System.Drawing.Size(1150, 594);
Controls.Add(btnUpdate);
Controls.Add(tcMain);
Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon");
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
MinimumSize = new System.Drawing.Size(1140, 611);
Name = "MainForm";
+49 -205
View File
@@ -1,4 +1,5 @@
using ColorControl.Forms;
using ColorControl.Properties;
using ColorControl.Services.AMD;
using ColorControl.Services.Common;
using ColorControl.Services.GameLauncher;
@@ -14,7 +15,6 @@ using ColorControl.Shared.Services;
using Linearstar.Windows.RawInput;
using Microsoft.Extensions.DependencyInjection;
using NLog;
using novideo_srgb;
using NWin32;
using System;
using System.Collections.Generic;
@@ -46,7 +46,7 @@ namespace ColorControl
private NvPanel _nvPanel;
public NotifyIcon _trayIcon;
public NotifyIconManager _notifyIconManager;
private bool _initialized = false;
private Config _config;
private bool _setVisibleCalled = false;
@@ -54,13 +54,6 @@ namespace ColorControl
private LgPanel _lgPanel;
private SamsungPanel _samsungPanel;
private ToolStripMenuItem _nvTrayMenu;
private ToolStripMenuItem _novideoTrayMenu;
private ToolStripMenuItem _amdTrayMenu;
private ToolStripMenuItem _lgTrayMenu;
private ToolStripMenuItem _samsungTrayMenu;
private ToolStripMenuItem _gameTrayMenu;
private StartUpParams StartUpParams { get; }
public string _lgTabMessage { get; private set; }
@@ -78,14 +71,22 @@ namespace ColorControl
private Dictionary<string, Func<UserControl>> _modules = new();
public MainForm(AppContextProvider appContextProvider, PowerEventDispatcher powerEventDispatcher, ServiceManager serviceManager,
IServiceProvider serviceProvider, WinApiAdminService winApiAdminService, WinApiService winApiService, ElevationService elevationService)
IServiceProvider serviceProvider, WinApiAdminService winApiAdminService, WinApiService winApiService, ElevationService elevationService, NotifyIconManager notifyIconManager)
{
InitializeComponent();
Icon = Resources.AppIcon;
var appContext = appContextProvider.GetAppContext();
if (appContext.MainHandle == 0)
{
appContext.MainHandle = Handle;
}
KeyboardShortcutManager.MainHandle = Handle;
StartUpParams = appContextProvider.GetAppContext().StartUpParams;
appContextProvider.GetAppContext().SynchronizationContext = AsyncOperationManager.SynchronizationContext;
StartUpParams = appContext.StartUpParams;
appContext.SynchronizationContext = AsyncOperationManager.SynchronizationContext;
_powerEventDispatcher = powerEventDispatcher;
_serviceManager = serviceManager;
@@ -93,17 +94,11 @@ namespace ColorControl
_winApiAdminService = winApiAdminService;
_winApiService = winApiService;
_elevationService = elevationService;
_notifyIconManager = notifyIconManager;
_dataDir = Program.DataDir;
_config = Program.Config;
var currentVersionInfo = FileVersionInfo.GetVersionInfo(Application.ExecutablePath);
Text = Application.ProductName + " " + Application.ProductVersion;
if (_winApiService.IsAdministrator())
{
Text += " (administrator)";
}
Text = appContext.ApplicationTitleAdmin;
LoadConfig();
@@ -113,37 +108,7 @@ namespace ColorControl
MessageForms.MainForm = this;
_nvTrayMenu = new ToolStripMenuItem("NVIDIA presets");
_novideoTrayMenu = new ToolStripMenuItem("Novideo sRGB");
_amdTrayMenu = new ToolStripMenuItem("AMD presets");
_lgTrayMenu = new ToolStripMenuItem("LG presets");
_samsungTrayMenu = new ToolStripMenuItem("Samsung presets");
_gameTrayMenu = new ToolStripMenuItem("Game Launcher");
_trayIcon = new NotifyIcon()
{
Icon = Icon,
ContextMenuStrip = new ContextMenuStrip(),
Visible = _config.MinimizeToTray,
Text = Text
};
_trayIcon.ContextMenuStrip.Items.AddRange(new ToolStripItem[] {
_nvTrayMenu,
_novideoTrayMenu,
_amdTrayMenu,
_lgTrayMenu,
_samsungTrayMenu,
_gameTrayMenu,
new ToolStripSeparator(),
new ToolStripMenuItem("Open", null, OpenForm),
new ToolStripSeparator(),
new ToolStripMenuItem("Restart", null, Restart),
new ToolStripMenuItem("Exit", null, Exit)
});
_trayIcon.MouseDoubleClick += trayIcon_MouseDoubleClick;
_trayIcon.ContextMenuStrip.Opened += trayIconContextMenu_Popup;
_trayIcon.BalloonTipClicked += trayIconBalloonTip_Clicked;
_notifyIconManager.Build();
InitShortcut(SHORTCUTID_SCREENSAVER, _config.ScreenSaverShortcut, StartScreenSaver);
@@ -155,7 +120,7 @@ namespace ColorControl
_winApiAdminService.InstallChromeFix(true, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
}
_screenStateNotify = WinApi.RegisterPowerSettingNotification(Handle, ref Utils.GUID_CONSOLE_DISPLAY_STATE, 0);
_screenStateNotify = WinApi.RegisterPowerSettingNotification(appContext.MainHandle, ref Utils.GUID_CONSOLE_DISPLAY_STATE, 0);
//Scale(new SizeF(1.25F, 1.25F));
@@ -225,8 +190,6 @@ namespace ColorControl
}
tcMain.SelectedIndex = 0;
_serviceManager.NvService?.InstallEventHandlers();
}
private UserControl InitNvService()
@@ -242,7 +205,7 @@ namespace ColorControl
var rpcService = _serviceProvider.GetRequiredService<RpcClientService>();
var winAdminService = _serviceProvider.GetRequiredService<WinApiAdminService>();
_nvPanel = new NvPanel(_serviceManager.NvService, _trayIcon, Handle, appContextProvider, rpcService, winAdminService);
_nvPanel = new NvPanel(_serviceManager.NvService, _notifyIconManager.NotifyIcon, appContextProvider, rpcService, winAdminService);
_nvPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
InitShortcut(NvPanel.SHORTCUTID_NVQA, _config.NvQuickAccessShortcut, _serviceManager.NvService.ToggleQuickAccessForm);
@@ -262,10 +225,10 @@ namespace ColorControl
{
try
{
var appContextProvider = _serviceProvider.GetRequiredService<AppContextProvider>();
_serviceManager.AmdService = new AmdService(appContextProvider);
_serviceManager.AmdService = _serviceProvider.GetRequiredService<AmdService>();
_amdPanel = new AmdPanel(_serviceManager.AmdService, _trayIcon, Handle);
var appContextProvider = _serviceProvider.GetRequiredService<AppContextProvider>();
_amdPanel = new AmdPanel(_serviceManager.AmdService, _notifyIconManager.NotifyIcon, appContextProvider);
_amdPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
InitShortcut(AmdPanel.SHORTCUTID_AMDQA, _config.AmdQuickAccessShortcut, _serviceManager.AmdService.ToggleQuickAccessForm);
@@ -287,7 +250,8 @@ namespace ColorControl
{
_serviceManager.GameService = _serviceProvider.GetRequiredService<GameService>();
_gamePanel = new GamePanel(_serviceManager.GameService, _serviceManager.NvService, _serviceManager.AmdService, _serviceManager.LgService, _serviceManager.SamsungService, _trayIcon, Handle);
var appContextProvider = _serviceProvider.GetRequiredService<AppContextProvider>();
_gamePanel = new GamePanel(_serviceManager.GameService, _serviceManager.NvService, _serviceManager.AmdService, _serviceManager.LgService, _serviceManager.SamsungService, _notifyIconManager.NotifyIcon, appContextProvider);
_gamePanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
InitShortcut(GamePanel.SHORTCUTID_GAMEQA, _config.GameQuickAccessShortcut, _serviceManager.GameService.ToggleQuickAccessForm);
@@ -318,7 +282,8 @@ namespace ColorControl
{
_serviceManager.LgService = _serviceProvider.GetRequiredService<LgService>();
_lgPanel = new LgPanel(_serviceManager.LgService, _serviceManager.NvService, _serviceManager.AmdService, _trayIcon, Handle, _powerEventDispatcher);
var appContextProvider = _serviceProvider.GetRequiredService<AppContextProvider>();
_lgPanel = new LgPanel(_serviceManager.LgService, _serviceManager.NvService, _serviceManager.AmdService, _notifyIconManager.NotifyIcon, _powerEventDispatcher, appContextProvider);
_lgPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
_lgPanel.Init();
@@ -342,9 +307,8 @@ namespace ColorControl
{
_serviceManager.SamsungService = _serviceProvider.GetRequiredService<SamsungService>();
//_serviceManager.SamsungService.Init();
_samsungPanel = new SamsungPanel(_serviceManager.SamsungService, _serviceManager.NvService, _serviceManager.AmdService, Handle, _powerEventDispatcher);
var appContextProvider = _serviceProvider.GetRequiredService<AppContextProvider>();
_samsungPanel = new SamsungPanel(_serviceManager.SamsungService, _serviceManager.NvService, _serviceManager.AmdService, _powerEventDispatcher, appContextProvider);
_samsungPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
_samsungPanel.Init();
@@ -379,6 +343,13 @@ namespace ColorControl
Program.Restart();
}
public void OpenForm()
{
Show();
WindowState = FormWindowState.Normal;
Activate();
}
private void trayIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
Show();
@@ -466,25 +437,25 @@ namespace ColorControl
var preset = _serviceManager.NvService?.GetPresets().FirstOrDefault(x => x.id == id);
if (preset != null)
{
_nvPanel?.ApplyNvPreset(preset);
_serviceManager.NvService?.ApplyPresetUi(preset);
}
var amdPreset = _serviceManager.AmdService?.GetPresets().FirstOrDefault(x => x.id == id);
if (amdPreset != null)
{
_amdPanel?.ApplyAmdPreset(amdPreset);
_serviceManager.AmdService?.ApplyPresetUi(amdPreset);
}
var lgPreset = _serviceManager.LgService?.GetPresets().FirstOrDefault(x => x.id == id);
if (lgPreset != null)
{
_lgPanel?.ApplyLgPreset(lgPreset);
_serviceManager.LgService?.ApplyPresetUi(lgPreset);
}
var samsungPreset = _serviceManager.SamsungService?.GetPresets().FirstOrDefault(x => x.id == id);
if (samsungPreset != null)
{
_samsungPanel?.ApplyPreset(samsungPreset);
_serviceManager.SamsungService?.ApplyPresetUi(samsungPreset);
}
}
}
@@ -511,15 +482,6 @@ namespace ColorControl
Logger.Debug("WM_BRINGTOFRONT message received, opening form");
OpenForm(this, EventArgs.Empty);
}
else if (m.Msg == NativeConstants.WM_SYSCOMMAND)
{
//Logger.Debug($"WM_SYSCOMMAND: {m.WParam.ToInt32()}");
//if (m.WParam.ToInt32() == NativeConstants.SC_MONITORPOWER)
//{
//}
}
else if (m.Msg == NativeConstants.WM_POWERBROADCAST)
{
//Logger.Debug($"WM_POWERBROADCAST: {m.WParam.ToInt32()}");
@@ -548,7 +510,7 @@ namespace ColorControl
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
// Hide tray icon, otherwise it will remain shown until user mouses over it
_trayIcon.Visible = false;
_notifyIconManager.HideIcon();
if (_screenStateNotify != IntPtr.Zero)
{
@@ -723,124 +685,6 @@ NOTE: installing the service may cause a User Account Control popup.");
//control.BackColor = SystemColors.Window;
}
private void UpdateTrayMenu(ToolStripMenuItem menu, IEnumerable<PresetBase> presets, EventHandler eventHandler)
{
menu.DropDownItems.Clear();
foreach (var preset in presets.OrderBy(p => p.name))
{
var name = preset.GetTextForMenuItem();
var keys = Keys.None;
if (!string.IsNullOrEmpty(preset.shortcut))
{
name += " " + preset.shortcut;
//keys = Utils.ShortcutToKeys(preset.shortcut);
}
var item = new ToolStripMenuItem(name, null, null, keys);
item.Tag = preset;
item.Click += eventHandler;
item.ForeColor = FormUtils.MenuItemForeColor;
menu.DropDownItems.Add(item);
}
}
private async void TrayMenuItemNv_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (NvPreset)item.Tag;
await _nvPanel?.ApplyNvPreset(preset);
}
private async void TrayMenuItemAmd_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (AmdPreset)item.Tag;
await _amdPanel?.ApplyAmdPreset(preset);
}
private async void TrayMenuItemGame_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (GamePreset)item.Tag;
await _gamePanel?.ApplyGamePreset(preset);
}
private void trayIconContextMenu_Popup(object sender, EventArgs e)
{
_nvTrayMenu.Visible = _serviceManager.NvService != null;
if (_nvTrayMenu.Visible)
{
var presets = _serviceManager.NvService.GetPresets().Where(x => x.applyColorData || x.applyDithering || x.applyHDR || x.applyRefreshRate || x.applyResolution || x.applyDriverSettings || x.applyOther || x.applyOverclocking || x.ApplyColorEnhancements || x.applyHdmiSettings);
UpdateTrayMenu(_nvTrayMenu, presets, TrayMenuItemNv_Click);
}
_novideoTrayMenu.Visible = _serviceManager.NvService != null && MainWindow.IsInitialized();
if (_novideoTrayMenu.Visible)
{
MainWindow.UpdateContextMenu(_novideoTrayMenu);
}
_amdTrayMenu.Visible = _serviceManager.AmdService != null;
if (_amdTrayMenu.Visible)
{
var presets = _serviceManager.AmdService.GetPresets().Where(x => x.applyColorData || x.applyDithering || x.applyHDR || x.applyRefreshRate);
UpdateTrayMenu(_amdTrayMenu, presets, TrayMenuItemAmd_Click);
}
_lgTrayMenu.Visible = _serviceManager.LgService != null;
if (_lgTrayMenu.Visible)
{
var presets = _serviceManager.LgService.GetPresets().Where(x => !string.IsNullOrEmpty(x.appId) || x.steps.Any());
_lgTrayMenu.DropDownItems.Clear();
UpdateTrayMenu(_lgTrayMenu, presets, TrayMenuItemLg_Click);
}
_samsungTrayMenu.Visible = _serviceManager.SamsungService != null;
if (_samsungTrayMenu.Visible)
{
var presets = _serviceManager.SamsungService.GetPresets().Where(x => x.Steps.Any());
_samsungTrayMenu.DropDownItems.Clear();
UpdateTrayMenu(_samsungTrayMenu, presets, TrayMenuItemSamsung_Click);
}
_gameTrayMenu.Visible = _serviceManager.GameService != null;
if (_gameTrayMenu.Visible)
{
var presets = _serviceManager.GameService.GetPresets();
_gameTrayMenu.DropDownItems.Clear();
UpdateTrayMenu(_gameTrayMenu, presets, TrayMenuItemGame_Click);
}
}
private async void TrayMenuItemLg_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (LgPreset)item.Tag;
await _lgPanel?.ApplyLgPreset(preset);
}
private async void TrayMenuItemSamsung_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (SamsungPreset)item.Tag;
await _samsungPanel?.ApplyPreset(preset);
}
private void MainForm_Activated(object sender, EventArgs e)
{
if (tcMain.SelectedTab?.Controls.Count > 0 && tcMain.SelectedTab.Controls[0] is IModulePanel panel)
@@ -861,10 +705,10 @@ NOTE: installing the service may cause a User Account Control popup.");
{
await _amdPanel.AfterInitialized();
}
if (_trayIcon.Visible)
{
await CheckForUpdates();
}
//if (_trayIcon.Visible)
//{
// await CheckForUpdates();
//}
}
private async Task CheckForUpdates()
@@ -943,9 +787,9 @@ NOTE: installing the service may cause a User Account Control popup.");
btnUpdate.Visible = true;
if (_trayIcon.Visible)
if (_notifyIconManager.NotifyIcon.Visible)
{
_trayIcon.ShowBalloonTip(5000, "Update available", $"Version {newVersion} is available. Click on the Update-button to update", ToolTipIcon.Info);
_notifyIconManager.NotifyIcon.ShowBalloonTip(5000, "Update available", $"Version {newVersion} is available. Click on the Update-button to update", ToolTipIcon.Info);
}
else
{
@@ -955,9 +799,9 @@ NOTE: installing the service may cause a User Account Control popup.");
return;
}
if (_trayIcon.Visible)
if (_notifyIconManager.NotifyIcon.Visible)
{
_trayIcon.ShowBalloonTip(5000, "Update available", $"Version {newVersion} is available. Click to open the GitHub page", ToolTipIcon.Info);
_notifyIconManager.NotifyIcon.ShowBalloonTip(5000, "Update available", $"Version {newVersion} is available. Click to open the GitHub page", ToolTipIcon.Info);
}
else
{
@@ -1039,7 +883,7 @@ NOTE: installing the service may cause a User Account Control popup.");
DarkModeUtils.InitWpfTheme();
DarkModeUtils.SetContextMenuForeColor(_trayIcon.ContextMenuStrip, FormUtils.CurrentForeColor);
DarkModeUtils.SetContextMenuForeColor(_notifyIconManager.NotifyIcon.ContextMenuStrip, FormUtils.CurrentForeColor);
InitSelectedTab();
}
@@ -1059,7 +903,7 @@ NOTE: installing the service may cause a User Account Control popup.");
internal void CloseForRestart()
{
Hide();
_trayIcon.Visible = false;
_notifyIconManager.NotifyIcon.Visible = false;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
+27 -1806
View File
File diff suppressed because it is too large. Load diff
+187
View File
@@ -0,0 +1,187 @@
using ColorControl.Services.Common;
using ColorControl.Shared.Common;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.EventDispatcher;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Native;
using ColorControl.Shared.Services;
using NLog;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace ColorControl;
internal class MainWorker
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly BackgroundWorker _backgroundWorker;
private readonly AppContextProvider _appContextProvider;
private readonly ServiceManager _serviceManager;
private readonly Config _config;
private readonly NotifyIconManager _notifyIconManager;
private readonly WindowMessageDispatcher _windowMessageDispatcher;
private readonly KeyboardShortcutDispatcher _keyboardShortcutDispatcher;
private readonly PowerEventDispatcher _powerEventDispatcher;
private readonly WinApiService _winApiService;
private readonly WinApiAdminService _winApiAdminService;
private readonly UpdateManager _updateManager;
private bool _isInitialized;
private bool _queryEndSession;
private nint _screenStateNotify;
public static int SHORTCUTID_SCREENSAVER = -100;
public MainWorker(
AppContextProvider appContextProvider,
ServiceManager serviceManager,
NotifyIconManager notifyIconManager,
WindowMessageDispatcher windowMessageDispatcher,
KeyboardShortcutDispatcher keyboardShortcutDispatcher,
PowerEventDispatcher powerEventDispatcher,
WinApiService winApiService,
WinApiAdminService winApiAdminService,
UpdateManager updateManager)
{
_backgroundWorker = new BackgroundWorker();
_appContextProvider = appContextProvider;
_serviceManager = serviceManager;
_notifyIconManager = notifyIconManager;
_windowMessageDispatcher = windowMessageDispatcher;
_keyboardShortcutDispatcher = keyboardShortcutDispatcher;
_powerEventDispatcher = powerEventDispatcher;
_winApiService = winApiService;
_winApiAdminService = winApiAdminService;
_updateManager = updateManager;
_config = _appContextProvider.GetAppContext().Config;
}
public async Task DoWork()
{
while (!_backgroundWorker.CancellationPending)
{
if (!_isInitialized)
{
await Init();
}
//await Task.Delay(1000);
System.Windows.Forms.Application.Run(_windowMessageDispatcher.MessageForm);
_notifyIconManager.HideIcon();
if (_screenStateNotify != 0)
{
WinApi.UnregisterPowerSettingNotification(_screenStateNotify);
_screenStateNotify = 0;
}
break;
}
}
private async Task Init()
{
_appContextProvider.GetAppContext().SynchronizationContext = AsyncOperationManager.SynchronizationContext;
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageQueryEndSession, HandleQueryEndSessionEvent);
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageClose, HandleCloseEvent);
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessagePowerBroadcast, HandlePowerBroadcastEvent);
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageShowWindow, HandleShowWindowEvent);
_screenStateNotify = WinApi.RegisterPowerSettingNotification(_windowMessageDispatcher.MessageForm.Handle, ref Utils.GUID_CONSOLE_DISPLAY_STATE, 0);
_keyboardShortcutDispatcher.SetUseRawInput(_config.UseRawInput);
_serviceManager.LoadModules();
_notifyIconManager.Build();
// Auto-apply fix if desired but not currently installed
if (_config.FixChromeFonts && _winApiService.IsChromeInstalled() && !_winApiService.IsChromeFixInstalled())
{
_winApiAdminService.InstallChromeFix(true, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
}
InitTheme();
_keyboardShortcutDispatcher.RegisterShortcut(SHORTCUTID_SCREENSAVER, _config.ScreenSaverShortcut);
_keyboardShortcutDispatcher.RegisterEventHandler(KeyboardShortcutDispatcher.Event_HotKey, HandleHotKeyEvent);
_isInitialized = true;
}
private bool _startupSent = false;
private void HandleShowWindowEvent(object sender, WindowMessageEventArgs e)
{
if (_startupSent)
{
return;
}
_startupSent = true;
var _ = _powerEventDispatcher.SendEventAsync(PowerEventDispatcher.Event_Startup);
var x = _updateManager.CheckForUpdates();
}
private void HandlePowerBroadcastEvent(object sender, WindowMessageEventArgs e)
{
if (e.Message.WParam.ToInt32() == WinApi.PBT_POWERSETTINGCHANGE)
{
var ps = Marshal.PtrToStructure<WinApi.POWERBROADCAST_SETTING>(e.Message.LParam);
var power = (WindowsMonitorPowerSetting)ps.Data;
Logger.Debug($"PBT_POWERSETTINGCHANGE: {power}");
_powerEventDispatcher.SendEvent(power == WindowsMonitorPowerSetting.Off ? PowerEventDispatcher.Event_MonitorOff : PowerEventDispatcher.Event_MonitorOn);
}
}
private void HandleCloseEvent(object sender, WindowMessageEventArgs e)
{
if (_queryEndSession)
{
_powerEventDispatcher.SendEvent(PowerEventDispatcher.Event_Shutdown);
}
}
private void HandleQueryEndSessionEvent(object sender, WindowMessageEventArgs e)
{
_queryEndSession = true;
}
private void HandleHotKeyEvent(object sender, KeyboardShortcutEventArgs args)
{
if (args.HotKeyId == SHORTCUTID_SCREENSAVER)
{
StartScreenSaver();
}
}
private void StartScreenSaver()
{
var screenSaver = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "scrnsave.scr");
Process.Start("explorer.exe", screenSaver);
}
private void InitTheme()
{
DarkModeUtils.SetDarkMode(_config.UseDarkMode);
WinApi.RefreshImmersiveColorPolicyState();
DarkModeUtils.InitWpfTheme();
DarkModeUtils.SetContextMenuForeColor(_notifyIconManager.NotifyIcon.ContextMenuStrip, FormUtils.CurrentForeColor);
}
}
+53 -19
View File
@@ -1,4 +1,5 @@
using ColorControl.Forms;
using ColorControl.Services.AMD;
using ColorControl.Services.Common;
using ColorControl.Services.GameLauncher;
using ColorControl.Services.LG;
@@ -7,6 +8,7 @@ using ColorControl.Services.Samsung;
using ColorControl.Shared.Common;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.EventDispatcher;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Native;
using ColorControl.Shared.Services;
using ColorControl.Svc;
@@ -38,12 +40,16 @@ namespace ColorControl
public static bool IsRestarting { get; private set; }
public static bool UserExit = false;
public static bool UseWorker = true;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static Mutex _mutex;
private static MainForm _mainForm;
public static MainForm _mainForm;
private static LoggingRule _loggingRule;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread] // autogenerated
public static void Main(string[] args)
{
@@ -51,10 +57,6 @@ namespace ColorControl
MainAsync(args).GetAwaiter().GetResult();
}
/// <summary>
/// The main entry point for the application.
/// </summary>
//[STAThread]
static async Task MainAsync(string[] args)
{
DataDir = Utils.GetDataPath();
@@ -73,6 +75,11 @@ namespace ColorControl
return;
}
await RunApp(args);
}
static async Task RunApp(string[] args)
{
var currentDomain = AppDomain.CurrentDomain;
// Handler for unhandled exceptions.
currentDomain.UnhandledException += GlobalUnhandledExceptionHandler;
@@ -96,9 +103,9 @@ namespace ColorControl
var appContextProvider = ServiceProvider.GetRequiredService<AppContextProvider>();
var startUpParams = StartUpParams.Parse(args);
AppContext = new GlobalContext(Config, startUpParams, DataDir, _loggingRule, mutexId);
AppContext = new GlobalContext(Config, startUpParams, DataDir, _loggingRule, ServiceProvider, mutexId);
appContextProvider.SetAppContext(AppContext);
MessageForms.Title = AppContext.ApplicationTitle;
var existingProcess = Utils.GetProcessByName("ColorControl");
@@ -134,19 +141,12 @@ namespace ColorControl
_mutex.WaitOne();
try
{
//if (Debugger.IsAttached)
//{
// Utils.StartService();
//}
//var result = WinApi.SetPreferredAppMode(1);
//result = WinApi.RefreshImmersiveColorPolicyState();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (Debugger.IsAttached)
{
//Utils.StartService();
var winApiService = ServiceProvider.GetRequiredService<WinApiService>();
if (winApiService.IsAdministrator())
@@ -158,8 +158,19 @@ namespace ColorControl
}
}
_mainForm = ServiceProvider.GetRequiredService<MainForm>();
Application.Run(_mainForm);
if (UseWorker)
{
var worker = ServiceProvider.GetRequiredService<MainWorker>();
await worker.DoWork();
//Application.Run();
}
else
{
_mainForm = ServiceProvider.GetRequiredService<MainForm>();
Application.Run(_mainForm);
}
if (Debugger.IsAttached && !IsRestarting)
{
@@ -182,6 +193,23 @@ namespace ColorControl
}
}
public static void OpenMainForm()
{
_mainForm ??= ServiceProvider.GetRequiredService<MainForm>();
_mainForm.OpenForm();
}
public static void Exit()
{
UserExit = true;
_mainForm?.Close();
if (AppContext.MainHandle != 0)
{
NativeMethods.SendMessageW(AppContext.MainHandle, NativeConstants.WM_CLOSE, 0, 0);
}
}
public static void Restart()
{
IsRestarting = true;
@@ -251,11 +279,16 @@ namespace ColorControl
{
//services.AddSingleton<NvService>();
services.RegisterSharedServices();
services.AddSingleton<MainWorker>();
services.AddSingleton<NotifyIconManager>();
services.AddSingleton<LgService>();
services.AddSingleton<GameService>();
services.AddSingleton<SamsungService>();
services.AddSingleton<AmdService>();
services.AddSingleton<PowerEventDispatcher>();
services.AddSingleton<ProcessEventDispatcher>();
services.AddSingleton<WindowMessageDispatcher>();
services.AddSingleton<KeyboardShortcutDispatcher>();
services.AddSingleton<MainForm>();
services.AddSingleton<ElevatedForm>();
services.AddSingleton<LogWindow>();
@@ -264,6 +297,7 @@ namespace ColorControl
services.AddSingleton<InfoPanel>();
services.AddSingleton<OptionsPanel>();
services.AddSingleton<ElevationService>();
services.AddSingleton<UpdateManager>();
});
}
private static async Task RunService(string[] args)
@@ -286,7 +320,7 @@ namespace ColorControl
ServiceProvider = host.Services;
var appContextProvider = ServiceProvider.GetRequiredService<AppContextProvider>();
AppContext = new GlobalContext(null, new StartUpParams(), DataDir, _loggingRule);
AppContext = new GlobalContext(null, new StartUpParams(), DataDir, _loggingRule, ServiceProvider);
appContextProvider.SetAppContext(AppContext);
await host.RunAsync();
@@ -348,7 +382,7 @@ namespace ColorControl
internal static NotifyIcon GetNotifyIcon()
{
return _mainForm?._trayIcon;
return _mainForm?._notifyIconManager?.NotifyIcon;
}
}
}
+15 -5
View File
@@ -22,7 +22,7 @@ namespace ColorControl.Properties {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
@@ -36,7 +36,7 @@ namespace ColorControl.Properties {
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ColorControl.Properties.Resources", typeof(Resources).Assembly);
@@ -51,7 +51,7 @@ namespace ColorControl.Properties {
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
@@ -60,10 +60,20 @@ namespace ColorControl.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
public static System.Drawing.Icon AppIcon {
get {
object obj = ResourceManager.GetObject("AppIcon", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap LG_remote {
public static System.Drawing.Bitmap LG_remote {
get {
object obj = ResourceManager.GetObject("LG_remote", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
@@ -108,7 +118,7 @@ namespace ColorControl.Properties {
///Rakuten TV;116;1218
///Play;202 [rest of string was truncated]&quot;;.
/// </summary>
internal static string RC_coords {
public static string RC_coords {
get {
return ResourceManager.GetString("RC_coords", resourceCulture);
}
+3
View File
@@ -118,6 +118,9 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="AppIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\pngbarn.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="LG_remote" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\LG_remote.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
File renamed without changes.
+9 -32
View File
@@ -3,6 +3,7 @@ using ColorControl.Shared.Common;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Native;
using ColorControl.Shared.Services;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -18,18 +19,17 @@ namespace ColorControl.Services.AMD
{
public static readonly int SHORTCUTID_AMDQA = -201;
private AmdService _amdService;
private NotifyIcon _trayIcon;
private IntPtr _mainHandle;
private readonly AmdService _amdService;
private readonly NotifyIcon _trayIcon;
private readonly AppContextProvider _appContextProvider;
private Config _config;
private string _lastDisplayRefreshRates = string.Empty;
internal AmdPanel(AmdService amdService, NotifyIcon trayIcon, IntPtr handle)
internal AmdPanel(AmdService amdService, NotifyIcon trayIcon, AppContextProvider appContextProvider)
{
_amdService = amdService;
_trayIcon = trayIcon;
_mainHandle = handle;
_appContextProvider = appContextProvider;
_config = Shared.Common.GlobalContext.CurrentContext.Config;
InitializeComponent();
@@ -144,7 +144,7 @@ namespace ColorControl.Services.AMD
{
if (_amdService.HasDisplaysAttached())
{
await ApplyAmdPreset(preset);
await _amdService.ApplyPresetUi(preset);
}
else
{
@@ -227,30 +227,7 @@ namespace ColorControl.Services.AMD
private async Task ApplySelectedAmdPreset()
{
var preset = GetSelectedAmdPreset();
await ApplyAmdPreset(preset);
}
internal async Task<bool> ApplyAmdPreset(AmdPreset preset)
{
if (preset == null || _amdService == null)
{
return false;
}
try
{
var result = await _amdService.ApplyPreset(preset);
if (!result)
{
throw new Exception("Error while applying AMD preset. At least one setting could not be applied. Check the log for details.");
}
return true;
}
catch (Exception e)
{
MessageForms.ErrorOk($"Error applying AMD-preset ({e.TargetSite.Name}): {e.Message}");
return false;
}
await _amdService.ApplyPresetUi(preset);
}
private async void btnApplyAmd_Click(object sender, EventArgs e)
@@ -325,7 +302,7 @@ namespace ColorControl.Services.AMD
if (!string.IsNullOrEmpty(preset.shortcut))
{
WinApi.UnregisterHotKey(_mainHandle, preset.id);
WinApi.UnregisterHotKey(_appContextProvider.GetAppContext().MainHandle, preset.id);
}
_amdService.GetPresets().Remove(preset);
+2
View File
@@ -25,6 +25,8 @@ namespace ColorControl.Services.AMD
public AmdService(AppContextProvider appContextProvider) : base(appContextProvider)
{
LoadPresets();
SetShortcuts(-201, _appContextProvider.GetAppContext().Config.AmdQuickAccessShortcut);
}
public static async Task<bool> ExecutePresetAsync(string idOrName)
@@ -0,0 +1,6 @@
namespace ColorControl.Services.Common;
internal interface IServiceBase
{
void InstallEventHandlers();
}
@@ -0,0 +1,233 @@
using ColorControl.Properties;
using ColorControl.Services.AMD;
using ColorControl.Services.GameLauncher;
using ColorControl.Services.LG;
using ColorControl.Services.NVIDIA;
using ColorControl.Services.Samsung;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Services;
using novideo_srgb;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace ColorControl.Services.Common;
public class NotifyIconManager
{
private readonly AppContextProvider _appContextProvider;
private readonly ServiceManager _serviceManager;
private readonly Config _config;
public NotifyIcon NotifyIcon { get; private set; }
private ToolStripMenuItem _nvTrayMenu;
private ToolStripMenuItem _novideoTrayMenu;
private ToolStripMenuItem _amdTrayMenu;
private ToolStripMenuItem _lgTrayMenu;
private ToolStripMenuItem _samsungTrayMenu;
private ToolStripMenuItem _gameTrayMenu;
public NotifyIconManager(AppContextProvider appContextProvider, ServiceManager serviceManager)
{
_appContextProvider = appContextProvider;
_serviceManager = serviceManager;
_config = appContextProvider.GetAppContext().Config;
}
public void Build()
{
if (_nvTrayMenu != null)
{
return;
}
_nvTrayMenu = new ToolStripMenuItem("NVIDIA presets");
_novideoTrayMenu = new ToolStripMenuItem("Novideo sRGB");
_amdTrayMenu = new ToolStripMenuItem("AMD presets");
_lgTrayMenu = new ToolStripMenuItem("LG presets");
_samsungTrayMenu = new ToolStripMenuItem("Samsung presets");
_gameTrayMenu = new ToolStripMenuItem("Game Launcher");
NotifyIcon = new NotifyIcon()
{
Icon = Resources.AppIcon,
ContextMenuStrip = new ContextMenuStrip(),
Visible = _config.MinimizeToTray,
Text = _appContextProvider.GetAppContext().ApplicationTitleAdmin
};
NotifyIcon.ContextMenuStrip.Items.AddRange(new ToolStripItem[] {
_nvTrayMenu,
_novideoTrayMenu,
_amdTrayMenu,
_lgTrayMenu,
_samsungTrayMenu,
_gameTrayMenu,
new ToolStripSeparator(),
new ToolStripMenuItem("Open", null, OpenForm),
new ToolStripSeparator(),
new ToolStripMenuItem("Restart", null, Restart),
new ToolStripMenuItem("Exit", null, Exit)
});
NotifyIcon.MouseDoubleClick += trayIcon_MouseDoubleClick;
NotifyIcon.ContextMenuStrip.Opened += trayIconContextMenu_Popup;
NotifyIcon.BalloonTipClicked += trayIconBalloonTip_Clicked;
}
public void HideIcon()
{
if (NotifyIcon != null)
{
NotifyIcon.Visible = false;
}
}
private void Exit(object sender, EventArgs e)
{
Program.Exit();
}
private void Restart(object sender, EventArgs e)
{
Program.Restart();
}
private void OpenForm(object sender, EventArgs e)
{
Program.OpenMainForm();
}
private void trayIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
Program.OpenMainForm();
}
private void trayIconBalloonTip_Clicked(object sender, EventArgs e)
{
//if (_updateHtmlUrl != null)
//{
// _winApiAdminService.StartProcess(_updateHtmlUrl);
//}
}
private void trayIconContextMenu_Popup(object sender, EventArgs e)
{
_nvTrayMenu.Visible = _serviceManager.NvService != null;
if (_nvTrayMenu.Visible)
{
var presets = _serviceManager.NvService.GetPresets().Where(x => x.applyColorData || x.applyDithering || x.applyHDR || x.applyRefreshRate || x.applyResolution || x.applyDriverSettings || x.applyOther || x.applyOverclocking || x.ApplyColorEnhancements || x.applyHdmiSettings);
UpdateTrayMenu(_nvTrayMenu, presets, TrayMenuItemNv_Click);
}
_novideoTrayMenu.Visible = _serviceManager.NvService != null && MainWindow.IsInitialized();
if (_novideoTrayMenu.Visible)
{
MainWindow.UpdateContextMenu(_novideoTrayMenu);
}
_amdTrayMenu.Visible = _serviceManager.AmdService != null;
if (_amdTrayMenu.Visible)
{
var presets = _serviceManager.AmdService.GetPresets().Where(x => x.applyColorData || x.applyDithering || x.applyHDR || x.applyRefreshRate);
UpdateTrayMenu(_amdTrayMenu, presets, TrayMenuItemAmd_Click);
}
_lgTrayMenu.Visible = _serviceManager.LgService != null;
if (_lgTrayMenu.Visible)
{
var presets = _serviceManager.LgService.GetPresets().Where(x => !string.IsNullOrEmpty(x.appId) || x.steps.Any());
_lgTrayMenu.DropDownItems.Clear();
UpdateTrayMenu(_lgTrayMenu, presets, TrayMenuItemLg_Click);
}
_samsungTrayMenu.Visible = _serviceManager.SamsungService != null;
if (_samsungTrayMenu.Visible)
{
var presets = _serviceManager.SamsungService.GetPresets().Where(x => x.Steps.Any());
_samsungTrayMenu.DropDownItems.Clear();
UpdateTrayMenu(_samsungTrayMenu, presets, TrayMenuItemSamsung_Click);
}
_gameTrayMenu.Visible = _serviceManager.GameService != null;
if (_gameTrayMenu.Visible)
{
var presets = _serviceManager.GameService.GetPresets();
_gameTrayMenu.DropDownItems.Clear();
UpdateTrayMenu(_gameTrayMenu, presets, TrayMenuItemGame_Click);
}
}
private void UpdateTrayMenu(ToolStripMenuItem menu, IEnumerable<PresetBase> presets, EventHandler eventHandler)
{
menu.DropDownItems.Clear();
foreach (var preset in presets.OrderBy(p => p.name))
{
var name = preset.GetTextForMenuItem();
var keys = Keys.None;
if (!string.IsNullOrEmpty(preset.shortcut))
{
name += " " + preset.shortcut;
//keys = Utils.ShortcutToKeys(preset.shortcut);
}
var item = new ToolStripMenuItem(name, null, null, keys);
item.Tag = preset;
item.Click += eventHandler;
item.ForeColor = FormUtils.MenuItemForeColor;
menu.DropDownItems.Add(item);
}
}
private async void TrayMenuItemNv_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (NvPreset)item.Tag;
await _serviceManager.NvService?.ApplyPresetUi(preset);
}
private async void TrayMenuItemAmd_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (AmdPreset)item.Tag;
await _serviceManager.AmdService?.ApplyPresetUi(preset);
}
private async void TrayMenuItemGame_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (GamePreset)item.Tag;
await _serviceManager.GameService?.ApplyPresetUi(preset);
}
private async void TrayMenuItemLg_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (LgPreset)item.Tag;
await _serviceManager.LgService?.ApplyPresetUi(preset);
}
private async void TrayMenuItemSamsung_Click(object sender, EventArgs e)
{
var item = sender as ToolStripMenuItem;
var preset = (SamsungPreset)item.Tag;
await _serviceManager.SamsungService?.ApplyPresetUi(preset);
}
}
+82 -1
View File
@@ -1,17 +1,21 @@
using ColorControl.Shared.EventDispatcher;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Native;
using ColorControl.Shared.Services;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using NStandard;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ColorControl.Services.Common
{
abstract class ServiceBase<T> where T : PresetBase, new()
abstract class ServiceBase<T> : IServiceBase where T : PresetBase, new()
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
@@ -31,6 +35,7 @@ namespace ColorControl.Services.Common
protected T _lastAppliedPreset;
protected string _loadPresetsError;
protected T _lastTriggeredPreset;
protected int _quickAccessShortcutId;
protected AppContextProvider _appContextProvider;
@@ -68,6 +73,72 @@ namespace ColorControl.Services.Common
public abstract Task<bool> ApplyPreset(T preset);
public async Task<bool> ApplyPresetUi(T preset)
{
if (preset == null)
{
return false;
}
try
{
var result = await ApplyPreset(preset);
if (!result)
{
throw new Exception($"Error while applying {ServiceName}-preset. At least one setting could not be applied. Check the log for details.");
}
return true;
}
catch (Exception e)
{
Logger.Error(e);
MessageForms.ErrorOk($"Error applying {ServiceName}-preset ({e.TargetSite.Name}): {e.Message}");
return false;
}
}
public async Task<bool> ApplyPresetById(int id)
{
var preset = _presets.FirstOrDefault(p => p.id == id);
if (preset == null)
{
return false;
}
return await ApplyPresetUi(preset);
}
protected void SetShortcuts(int quickAccessShortcutId = 0, string shortcut = null)
{
if (!Program.UseWorker)
{
return;
}
_quickAccessShortcutId = quickAccessShortcutId;
var keyboardShortcutDispatcher = _appContextProvider.GetAppContext().ServiceProvider.GetRequiredService<KeyboardShortcutDispatcher>();
if (quickAccessShortcutId != 0 && !shortcut.IsNullOrWhiteSpace())
{
keyboardShortcutDispatcher.RegisterShortcut(quickAccessShortcutId, shortcut);
}
foreach (var preset in _presets)
{
keyboardShortcutDispatcher.RegisterShortcut(preset.id, preset.shortcut);
}
keyboardShortcutDispatcher.RegisterAsyncEventHandler(KeyboardShortcutDispatcher.Event_HotKey, HotKeyPressed);
}
public virtual void InstallEventHandlers()
{
}
public T GetLastAppliedPreset()
{
return _lastAppliedPreset;
@@ -233,5 +304,15 @@ namespace ColorControl.Services.Common
}
}
protected virtual async Task HotKeyPressed(object sender, KeyboardShortcutEventArgs e, CancellationToken _)
{
if (e.HotKeyId == _quickAccessShortcutId)
{
ToggleQuickAccessForm();
return;
}
await ApplyPresetById(e.HotKeyId);
}
}
}
+54 -1
View File
@@ -3,8 +3,11 @@ using ColorControl.Services.GameLauncher;
using ColorControl.Services.LG;
using ColorControl.Services.NVIDIA;
using ColorControl.Services.Samsung;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Services;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -12,7 +15,11 @@ namespace ColorControl.Services.Common;
public class ServiceManager
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly WinApiAdminService _winApiAdminService;
private readonly IServiceProvider _serviceProvider;
private readonly Config _config;
public Dictionary<string, object> Modules { get; } = new();
internal NvService NvService { get; set; }
internal LgService LgService { get; set; }
@@ -20,9 +27,55 @@ public class ServiceManager
internal GameService GameService { get; set; }
internal SamsungService SamsungService { get; set; }
public ServiceManager(WinApiAdminService winApiAdminService)
public ServiceManager(WinApiAdminService winApiAdminService, IServiceProvider serviceProvider, AppContextProvider appContextProvider)
{
_winApiAdminService = winApiAdminService;
_serviceProvider = serviceProvider;
_config = appContextProvider.GetAppContext().Config;
}
public void LoadModules()
{
AddModule<NvService>("NVIDIA controller");
AddModule<AmdService>("AMD controller");
AddModule<LgService>("LG controller");
AddModule<SamsungService>("Samsung controller");
AddModule<GameService>("Game launcher");
var names = Modules.Select(m => m.Key).ToList();
_config.Modules = _config.Modules.OrderBy(m => names.IndexOf(m.DisplayName)).ToList();
}
private void AddModule<T>(string displayName) where T : class, IServiceBase
{
var moduleEx = new ModuleEx<T> { DisplayName = displayName };
Modules.Add(displayName, moduleEx);
var existingModule = _config.Modules.FirstOrDefault(m => m.DisplayName == displayName);
if (existingModule == null)
{
existingModule = new Module { DisplayName = displayName, IsActive = true };
_config.Modules.Add(existingModule);
}
if (existingModule.IsActive)
{
var service = moduleEx.CreateService(_serviceProvider);
service?.InstallEventHandlers();
object _ = service switch
{
NvService nvService => NvService = nvService,
AmdService amdService => AmdService = amdService,
LgService lgService => LgService = lgService,
SamsungService samsungService => SamsungService = samsungService,
GameService gameService => GameService = gameService,
_ => throw new InvalidOperationException("Unknown module")
};
}
}
public async Task<bool> HandleExternalServiceAsync(string serviceName, string[] parameters)
@@ -0,0 +1,163 @@
using ColorControl.Shared.Common;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Services;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ColorControl.Services.Common;
public class UpdateManager
{
private readonly AppContextProvider _appContextProvider;
private readonly ServiceManager _serviceManager;
private readonly NotifyIconManager _notifyIconManager;
private readonly WinApiService _winApiService;
private readonly Config _config;
private bool _checkedForUpdates;
private string _updateHtmlUrl;
private string _downloadUrl;
public UpdateManager(AppContextProvider appContextProvider, ServiceManager serviceManager, NotifyIconManager notifyIconManager, WinApiService winApiService)
{
_appContextProvider = appContextProvider;
_serviceManager = serviceManager;
_notifyIconManager = notifyIconManager;
_winApiService = winApiService;
_config = appContextProvider.GetAppContext().Config;
}
public async Task CheckForUpdates()
{
if (!_config.CheckForUpdates || _checkedForUpdates || Debugger.IsAttached)
{
return;
}
_checkedForUpdates = true;
await Utils.GetRestJsonAsync("https://api.github.com/repos/maassoft/colorcontrol/releases/latest", InitHandleCheckForUpdates);
}
private void InitHandleCheckForUpdates(dynamic latest)
{
HandleCheckForUpdates(latest);
//FormUtils.BeginInvokeCheck(() => HandleCheckForUpdates(latest));
}
private void HandleCheckForUpdates(dynamic latest)
{
if (latest?.tag_name == null)
{
return;
}
var currentVersion = Application.ProductVersion;
var cvParts = currentVersion.Split(".");
var newVersion = (string)latest.tag_name.Value.Substring(1);
var nvParts = newVersion.Split(".");
bool CompareVersions()
{
var result = true;
var aNumberIsLarger = false;
for (var i = 0; i < nvParts.Length; i++)
{
var part = Utils.ParseInt(nvParts[i]);
var cvPart = Utils.ParseInt(cvParts[i]);
if (part > cvPart)
{
aNumberIsLarger = true;
break;
}
if (part == cvPart)
{
continue;
}
result = false;
break;
}
return result && aNumberIsLarger;
}
if (nvParts.Length != cvParts.Length || CompareVersions())
{
_updateHtmlUrl = latest.html_url.Value;
if (latest.assets != null && _winApiService.IsServiceRunning())
{
var asset = latest.assets[0];
_downloadUrl = asset.browser_download_url.Value;
if (_config.AutoInstallUpdates)
{
InstallUpdate(_downloadUrl);
return;
}
_appContextProvider.GetAppContext().UpdateAvailable = true;
if (_notifyIconManager.NotifyIcon.Visible)
{
_notifyIconManager.NotifyIcon.ShowBalloonTip(5000, "Update available", $"Version {newVersion} is available. Click on the Update-button to update", ToolTipIcon.Info);
}
else
{
MessageForms.InfoOk($"New version {newVersion} is available. Click on the Update-button to update", "Update available", $"https://github.com/Maassoft/ColorControl/releases/tag/v{newVersion}");
}
return;
}
if (_notifyIconManager.NotifyIcon.Visible)
{
_notifyIconManager.NotifyIcon.ShowBalloonTip(5000, "Update available", $"Version {newVersion} is available. Click to open the GitHub page", ToolTipIcon.Info);
}
else
{
MessageForms.InfoOk($"New version {newVersion} is available. Click on the Help-button to open the GitHub page.", "Update available", $"https://github.com/Maassoft/ColorControl/releases/tag/v{newVersion}");
}
}
}
private void InstallUpdate(string downloadUrl)
{
var message = new SvcInstallUpdateMessage
{
DownloadUrl = downloadUrl,
ClientPath = new FileInfo(Application.ExecutablePath).Directory.FullName
};
var result = PipeUtils.SendMessage(message, 30000);
if (result != null && !result.Result)
{
MessageForms.ErrorOk($"Error while updating: {result.ErrorMessage}");
return;
}
PipeUtils.SendMessage(SvcMessageType.RestartAfterUpdate);
if (MessageForms.QuestionYesNo("Update installed successfully. Do you want to restart the application?") == DialogResult.Yes)
{
Program.Restart();
}
else
{
_downloadUrl = null;
_appContextProvider.GetAppContext().UpdateAvailable = true;
}
}
}
@@ -7,6 +7,7 @@ using ColorControl.Shared.Common;
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Native;
using ColorControl.Shared.Services;
using nspector;
using System;
using System.Collections.Generic;
@@ -27,18 +28,18 @@ namespace ColorControl.Services.GameLauncher
private Config _config;
private GameService _gameService;
private IntPtr _mainHandle;
private NotifyIcon _trayIcon;
private readonly AppContextProvider _appContextProvider;
private NvService _nvService;
private AmdService _amdService;
private LgService _lgService;
private SamsungService _samsungService;
internal GamePanel(GameService gameService, NvService nvService, AmdService amdService, LgService lgService, SamsungService samsungService, NotifyIcon trayIcon, IntPtr handle)
internal GamePanel(GameService gameService, NvService nvService, AmdService amdService, LgService lgService, SamsungService samsungService, NotifyIcon trayIcon, AppContextProvider appContextProvider)
{
_gameService = gameService;
_trayIcon = trayIcon;
_mainHandle = handle;
_appContextProvider = appContextProvider;
_nvService = nvService;
_amdService = amdService;
_lgService = lgService;
@@ -108,30 +109,7 @@ namespace ColorControl.Services.GameLauncher
private async Task ApplySelectedGamePreset()
{
var preset = GetSelectedGamePreset();
await ApplyGamePreset(preset);
}
internal async Task<bool> ApplyGamePreset(GamePreset preset)
{
if (preset == null || _gameService == null)
{
return false;
}
try
{
var result = await _gameService.ApplyPreset(preset, Program.AppContext);
if (!result)
{
throw new Exception("Error while applying Game-preset. At least one setting could not be applied. Check the log for details.");
}
return true;
}
catch (Exception e)
{
MessageForms.ErrorOk($"Error applying Game-preset ({e.TargetSite.Name}): {e.Message}");
return false;
}
await _gameService.ApplyPresetUi(preset);
}
private void lvGamePresets_SelectedIndexChanged(object sender, EventArgs _)
@@ -291,7 +269,7 @@ namespace ColorControl.Services.GameLauncher
if (!string.IsNullOrEmpty(preset.shortcut))
{
WinApi.UnregisterHotKey(_mainHandle, preset.id);
WinApi.UnregisterHotKey(_appContextProvider.GetAppContext().MainHandle, preset.id);
}
_gameService.GetPresets().Remove(preset);
@@ -41,6 +41,8 @@ namespace ColorControl.Services.GameLauncher
_winApiAdminService = winApiAdminService;
_winApiService = winApiService;
_processEventDispatcher.RegisterAsyncEventHandler(ProcessEventDispatcher.Event_ProcessChanged, ProcessChanged);
SetShortcuts(-203, _appContextProvider.GetAppContext().Config.GameQuickAccessShortcut);
}
private async Task ProcessChanged(object sender, ProcessChangedEventArgs e, CancellationToken token)
@@ -145,7 +147,7 @@ namespace ColorControl.Services.GameLauncher
var preset = GetPresetByIdOrName(idOrName);
if (preset != null)
{
return await ApplyPreset(preset, Program.AppContext);
return await ApplyPreset(preset);
}
else
{
@@ -154,11 +156,6 @@ namespace ColorControl.Services.GameLauncher
}
public override async Task<bool> ApplyPreset(GamePreset preset)
{
return await ApplyPreset(preset, Program.AppContext);
}
public async Task<bool> ApplyPreset(GamePreset preset, GlobalContext _)
{
var result = await ExecutePreset(preset);
+8 -22
View File
@@ -6,6 +6,7 @@ using ColorControl.Shared.Contracts;
using ColorControl.Shared.EventDispatcher;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Native;
using ColorControl.Shared.Services;
using LgTv;
using NLog;
using NStandard;
@@ -31,22 +32,21 @@ namespace ColorControl.Services.LG
private NvService _nvService;
private AmdService _amdService;
private readonly PowerEventDispatcher _powerEventDispatcher;
private IntPtr _mainHandle;
private readonly AppContextProvider _appContextProvider;
private NotifyIcon _trayIcon;
private string _lgTabMessage;
private bool _disableEvents = false;
private LgGameBar _gameBarForm;
internal LgPanel(LgService lgService, NvService nvService, AmdService amdService, NotifyIcon trayIcon, IntPtr handle, PowerEventDispatcher powerEventDispatcher)
internal LgPanel(LgService lgService, NvService nvService, AmdService amdService, NotifyIcon trayIcon, PowerEventDispatcher powerEventDispatcher, AppContextProvider appContextProvider)
{
_lgService = lgService;
_nvService = nvService;
_amdService = amdService;
_trayIcon = trayIcon;
_mainHandle = handle;
_powerEventDispatcher = powerEventDispatcher;
_appContextProvider = appContextProvider;
_config = Shared.Common.GlobalContext.CurrentContext.Config;
InitializeComponent();
@@ -253,7 +253,7 @@ namespace ColorControl.Services.LG
{
var preset = GetSelectedLgPreset();
await ApplyLgPreset(preset);
await _lgService.ApplyPresetUi(preset);
}
private void btnSetShortcutLg_Click(object sender, EventArgs e)
@@ -465,7 +465,7 @@ namespace ColorControl.Services.LG
if (!string.IsNullOrEmpty(preset.shortcut))
{
WinApi.UnregisterHotKey(_mainHandle, preset.id);
WinApi.UnregisterHotKey(_appContextProvider.GetAppContext().MainHandle, preset.id);
}
_lgService.GetPresets().Remove(preset);
@@ -479,20 +479,6 @@ namespace ColorControl.Services.LG
AddOrUpdateItemLg(_lgService.CreateNewPreset());
}
internal async Task ApplyLgPreset(LgPreset preset, bool reconnect = false)
{
if (preset == null)
{
return;
}
var result = await _lgService.ApplyPreset(preset, reconnect);
if (!result)
{
MessageForms.WarningOk("Could not apply the preset (entirely). Check the log for details.");
}
}
private void btnLgRefreshApps_Click(object sender, EventArgs e)
{
_lgService.RefreshApps(true).ContinueWith((task) => BeginInvoke(() => FillLgApps(true)));
@@ -526,7 +512,7 @@ namespace ColorControl.Services.LG
private async void ApplySelectedLgPreset()
{
var preset = GetSelectedLgPreset();
await ApplyLgPreset(preset);
await _lgService.ApplyPresetUi(preset);
}
private void btnLgAddButton_Click(object sender, EventArgs e)
@@ -1267,7 +1253,7 @@ Do you want to continue?";
if (string.IsNullOrEmpty(shortcutGB))
{
WinApi.UnregisterHotKey(_mainHandle, SHORTCUTID_GAMEBAR);
WinApi.UnregisterHotKey(_appContextProvider.GetAppContext().MainHandle, SHORTCUTID_GAMEBAR);
}
else
{
+3 -1
View File
@@ -425,8 +425,10 @@ namespace ColorControl.Services.LG
return PowerOnDevicesTask(wakeDevices, state, checkUserSession);
}
public void InstallEventHandlers()
public override void InstallEventHandlers()
{
base.InstallEventHandlers();
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_Suspend, PowerModeChanged);
_powerEventDispatcher.RegisterAsyncEventHandler(PowerEventDispatcher.Event_Resume, PowerModeResume);
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_Shutdown, PowerModeChanged);
+4 -31
View File
@@ -34,18 +34,16 @@ namespace ColorControl.Services.NVIDIA
private Config _config;
private NvService _nvService;
private IntPtr _mainHandle;
private readonly AppContextProvider _appContextProvider;
private string _lastDisplayRefreshRates = string.Empty;
private NotifyIcon _trayIcon;
private RpcClientService _rpcService;
private readonly WinApiAdminService _winApiAdminService;
public NvPanel(NvService nvService, NotifyIcon trayIcon, IntPtr handle, AppContextProvider appContextProvider, RpcClientService rpcService, WinApiAdminService winApiAdminService)
public NvPanel(NvService nvService, NotifyIcon trayIcon, AppContextProvider appContextProvider, RpcClientService rpcService, WinApiAdminService winApiAdminService)
{
_nvService = nvService;
_trayIcon = trayIcon;
_mainHandle = handle;
_appContextProvider = appContextProvider;
_config = appContextProvider.GetAppContext().Config;
_rpcService = rpcService;
@@ -245,7 +243,7 @@ namespace ColorControl.Services.NVIDIA
if (!string.IsNullOrEmpty(preset.shortcut))
{
WinApi.UnregisterHotKey(_mainHandle, preset.id);
WinApi.UnregisterHotKey(_appContextProvider.GetAppContext().MainHandle, preset.id);
}
_nvService.GetPresets().Remove(preset);
@@ -1248,32 +1246,7 @@ namespace ColorControl.Services.NVIDIA
private async Task ApplySelectedNvPreset()
{
var preset = GetSelectedNvPreset();
await ApplyNvPreset(preset);
}
public async Task<bool> ApplyNvPreset(NvPreset preset)
{
if (preset == null || _nvService == null)
{
return false;
}
try
{
var result = await _nvService.ApplyPreset(preset);
if (!result)
{
throw new Exception("Error while applying NVIDIA preset. At least one setting could not be applied. Check the log for details.");
}
return true;
}
catch (Exception e)
{
Logger.Error(e);
MessageForms.ErrorOk($"Error applying NVIDIA-preset ({e.TargetSite.Name}): {e.Message}");
return false;
}
await _nvService.ApplyPresetUi(preset);
}
private NvPreset GetSelectedNvPreset(bool currentDisplay = false, bool driverSettings = false)
@@ -1905,7 +1878,7 @@ namespace ColorControl.Services.NVIDIA
}
preset.IsStartupPreset = true;
await ApplyNvPreset(preset);
await _nvService.ApplyPresetUi(preset);
}
private void miNvDithering6bit_Click(object sender, EventArgs e)
+12 -5
View File
@@ -169,7 +169,8 @@ namespace ColorControl.Services.NVIDIA
private int _lastSetSDRBrightness = -1;
private int _lastReadSDRBrightness = -1;
private Semaphore _semaphore = new Semaphore(1, 1);
private SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
private SemaphoreSlim _refreshSemaphore = new SemaphoreSlim(1, 1);
public const uint DRS_GSYNC_APPLICATION_MODE = 294973784;
public const uint DRS_VSYNC_CONTROL = 11041231;
@@ -217,20 +218,26 @@ namespace ColorControl.Services.NVIDIA
private readonly RpcClientService _rpcClientService;
private readonly PowerEventDispatcher _powerEventDispatcher;
private readonly ServiceManager _serviceManager;
private readonly KeyboardShortcutDispatcher _keyboardShortcutDispatcher;
private static NvService ServiceInstance;
public NvService(AppContextProvider appContextProvider, WinApiService winApiService, RpcClientService rpcClientService, PowerEventDispatcher powerEventDispatcher, ServiceManager serviceManager) : base(appContextProvider)
public static readonly int SHORTCUTID_NVQA = -200;
public NvService(AppContextProvider appContextProvider, WinApiService winApiService, RpcClientService rpcClientService, PowerEventDispatcher powerEventDispatcher, ServiceManager serviceManager, KeyboardShortcutDispatcher keyboardShortcutDispatcher) : base(appContextProvider)
{
_winApiService = winApiService;
_rpcClientService = rpcClientService;
_powerEventDispatcher = powerEventDispatcher;
_serviceManager = serviceManager;
_keyboardShortcutDispatcher = keyboardShortcutDispatcher;
_rpcClientService.Name = nameof(NvService);
NvPreset.NvService = this;
AddJsonConverter(new ColorDataConverter());
LoadConfig();
LoadPresets();
SetShortcuts(SHORTCUTID_NVQA, _appContextProvider.GetAppContext().Config.NvQuickAccessShortcut);
}
public void InstallEventHandlers()
@@ -1575,7 +1582,7 @@ namespace ColorControl.Services.NVIDIA
protected List<SettingItem> GetSettings()
{
_semaphore.WaitOne();
_semaphore.Wait();
try
{
if (!_settings.Any())
@@ -1620,7 +1627,7 @@ namespace ColorControl.Services.NVIDIA
public void RefreshProfileSettings()
{
_semaphore.WaitOne();
_refreshSemaphore.Wait();
try
{
var firstTime = _settings?.Any() != true;
@@ -1644,7 +1651,7 @@ namespace ColorControl.Services.NVIDIA
}
finally
{
_semaphore.Release();
_refreshSemaphore.Release();
}
}
@@ -14,7 +14,6 @@ namespace ColorControl.Services.Samsung
Task<bool> ApplyPreset(string idOrName);
SamsungDevice GetPresetDevice(SamsungPreset preset);
void GlobalSave();
void InstallEventHandlers();
Task RefreshDevices(bool connect = true, bool afterStartUp = false);
}
}
+11 -22
View File
@@ -6,6 +6,7 @@ using ColorControl.Shared.Contracts;
using ColorControl.Shared.EventDispatcher;
using ColorControl.Shared.Forms;
using ColorControl.Shared.Native;
using ColorControl.Shared.Services;
using NLog;
using NStandard;
using System;
@@ -28,18 +29,18 @@ namespace ColorControl.Services.Samsung
private SamsungService _samsungService;
private NvService _nvService;
private AmdService _amdService;
private IntPtr _mainHandle;
private readonly PowerEventDispatcher _powerEventDispatcher;
private readonly AppContextProvider _appContextProvider;
private string _tabMessage;
private bool _disableEvents = false;
internal SamsungPanel(SamsungService samsungService, NvService nvService, AmdService amdService, IntPtr handle, PowerEventDispatcher powerEventDispatcher)
internal SamsungPanel(SamsungService samsungService, NvService nvService, AmdService amdService, PowerEventDispatcher powerEventDispatcher, AppContextProvider appContextProvider)
{
_samsungService = samsungService;
_nvService = nvService;
_amdService = amdService;
_mainHandle = handle;
_powerEventDispatcher = powerEventDispatcher;
_appContextProvider = appContextProvider;
_config = Shared.Common.GlobalContext.CurrentContext.Config;
InitializeComponent();
@@ -72,9 +73,11 @@ namespace ColorControl.Services.Samsung
public void Init()
{
var _ = Handle;
_powerEventDispatcher.RegisterAsyncEventHandler(PowerEventDispatcher.Event_Startup, PowerStateChanged);
//_powerEventDispatcher.RegisterAsyncEventHandler(PowerEventDispatcher.Event_Startup, PowerStateChanged);
_samsungService.InstallEventHandlers();
//_samsungService.InstallEventHandlers();
var x = AfterSamsungServiceRefreshDevices();
}
private async Task PowerStateChanged(object sender, PowerStateChangedEventArgs e, CancellationToken token)
@@ -247,7 +250,7 @@ namespace ColorControl.Services.Samsung
{
var preset = GetSelectedPreset();
await ApplyPreset(preset);
await _samsungService.ApplyPresetUi(preset);
}
private void btnSetShortcutLg_Click(object sender, EventArgs e)
@@ -457,7 +460,7 @@ namespace ColorControl.Services.Samsung
if (!string.IsNullOrEmpty(preset.shortcut))
{
WinApi.UnregisterHotKey(_mainHandle, preset.id);
WinApi.UnregisterHotKey(_appContextProvider.GetAppContext().MainHandle, preset.id);
}
_samsungService.GetPresets().Remove(preset);
@@ -471,20 +474,6 @@ namespace ColorControl.Services.Samsung
AddOrUpdateItem(_samsungService.CreateNewPreset());
}
internal async Task ApplyPreset(SamsungPreset preset)
{
if (preset == null)
{
return;
}
var result = await _samsungService.ApplyPreset(preset);
if (!result)
{
MessageForms.WarningOk("Could not apply the preset (entirely). Check the log for details.");
}
}
private void btnSamsungRefreshApps_Click(object sender, EventArgs e)
{
//_samsungService.RefreshApps(true).ContinueWith((task) => FormUtils.BeginInvokeCheck(this, () => FillLgApps(true)));
@@ -518,7 +507,7 @@ namespace ColorControl.Services.Samsung
private async void ApplySelectedPreset()
{
var preset = GetSelectedPreset();
await ApplyPreset(preset);
await _samsungService.ApplyPresetUi(preset);
}
private void btnSamsungAddButton_Click(object sender, EventArgs e)
@@ -56,6 +56,8 @@ namespace ColorControl.Services.Samsung
LoadConfig();
LoadPresets();
SetShortcuts(-204, Config.QuickAccessShortcut);
}
public static async Task<bool> ExecutePresetAsync(string presetName)
@@ -82,8 +84,11 @@ namespace ColorControl.Services.Samsung
}
}
public void InstallEventHandlers()
public override void InstallEventHandlers()
{
base.InstallEventHandlers();
_powerEventDispatcher.RegisterAsyncEventHandler(PowerEventDispatcher.Event_Startup, PowerStateChanged);
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_MonitorOn, PowerModeChanged);
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_MonitorOff, PowerModeChanged);
_powerEventDispatcher.RegisterEventHandler(PowerEventDispatcher.Event_Suspend, PowerModeChanged);
@@ -92,6 +97,11 @@ namespace ColorControl.Services.Samsung
_processEventDispatcher.RegisterAsyncEventHandler(ProcessEventDispatcher.Event_ProcessChanged, ProcessChanged);
}
private async Task PowerStateChanged(object sender, PowerStateChangedEventArgs e, CancellationToken token)
{
await RefreshDevices(afterStartUp: true);
}
private void LoadConfig()
{
_configFilename = Path.Combine(_dataPath, "SamsungConfig.json");
@@ -117,7 +127,7 @@ namespace ColorControl.Services.Samsung
await WakeAfterStartupOrResume(PowerOnOffState.Resume);
ExecutePresetsForEvent(PresetTriggerType.Resume);
await ExecutePresetsForEvent(PresetTriggerType.Resume);
}
private void PowerModeChanged(object sender, PowerStateChangedEventArgs e)
@@ -134,7 +144,7 @@ namespace ColorControl.Services.Samsung
{
case PowerOnOffState.StandBy:
{
ExecutePresetsForEvent(PresetTriggerType.Standby);
_ = ExecutePresetsForEvent(PresetTriggerType.Standby).ConfigureAwait(true);
var devices = Devices.Where(d => d.Options.PowerOffOnStandby);
PowerOffDevices(devices, PowerOnOffState.StandBy);
@@ -142,7 +152,7 @@ namespace ColorControl.Services.Samsung
}
case PowerOnOffState.ShutDown:
{
ExecutePresetsForEvent(PresetTriggerType.Shutdown);
_ = ExecutePresetsForEvent(PresetTriggerType.Shutdown).ConfigureAwait(true);
var devices = Devices.Where(d => d.Options.PowerOffOnShutdown);
@@ -165,7 +175,7 @@ namespace ColorControl.Services.Samsung
}
}
private void ExecutePresetsForEvent(PresetTriggerType triggerType)
private async Task ExecutePresetsForEvent(PresetTriggerType triggerType)
{
Logger.Debug($"Executing presets for event {triggerType}");
@@ -184,7 +194,7 @@ namespace ColorControl.Services.Samsung
return;
}
ExecuteEventPresets(_serviceManager, new[] { triggerType }).Wait();
await ExecuteEventPresets(_serviceManager, new[] { triggerType });
}
public async Task RefreshDevices(bool connect = true, bool afterStartUp = false)
@@ -310,7 +320,12 @@ namespace ColorControl.Services.Samsung
var device = GetPresetDevice(preset);
await device?.ExecutePresetAsync(preset, appContext, Config);
if (device == null)
{
return false;
}
await device.ExecutePresetAsync(preset, appContext, Config);
_lastAppliedPreset = preset;
+20 -1
View File
@@ -1,4 +1,5 @@
using ColorControl.Shared.Contracts;
using ColorControl.Shared.Services;
using NLog;
using NLog.Config;
using System.ComponentModel;
@@ -18,16 +19,34 @@ namespace ColorControl.Shared.Common
public LoggingRule LoggingRule { get; private set; }
public DateTime StartTime { get; private set; } = DateTime.Now;
public string MutexId { get; private set; }
public nint MainHandle { get; set; }
public IServiceProvider ServiceProvider { get; private set; }
public GlobalContext(Config config, StartUpParams startUpParams, string dataPath, LoggingRule loggingRule, string mutexId = null)
public string ApplicationTitle { get; private set; }
public string ApplicationTitleAdmin { get; private set; }
public bool UpdateAvailable { get; set; }
public GlobalContext(Config config, StartUpParams startUpParams, string dataPath, LoggingRule loggingRule, IServiceProvider serviceProvider, string mutexId = null)
{
Config = config;
StartUpParams = startUpParams;
DataPath = dataPath;
LoggingRule = loggingRule;
ServiceProvider = serviceProvider;
MutexId = mutexId;
CurrentContext = this;
ApplicationTitle = Application.ProductName + " " + Application.ProductVersion;
if (WinApiService.IsAdministratorStatic())
{
ApplicationTitleAdmin = ApplicationTitle + " (administrator)";
}
else
{
ApplicationTitleAdmin = ApplicationTitle;
}
}
public void SetLogLevel(LogLevel logLevel)
+50 -51
View File
@@ -2,67 +2,66 @@
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace ColorControl.Shared.Common
namespace ColorControl.Shared.Common;
public class ShortcutStruct
{
internal class ShortcutStruct
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public int VirtualKeyCode { get; private set; }
public int Modifiers { get; private set; }
public int Id { get; }
public string Shortcut { get; private set; }
public bool HotKeyRegistered { get; set; }
public ShortcutStruct(int modifiers, int virtualKeyCode, int id, string shortcut)
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
VirtualKeyCode = virtualKeyCode;
Modifiers = modifiers;
Id = id;
Shortcut = shortcut;
}
public int VirtualKeyCode { get; private set; }
public int Modifiers { get; private set; }
public int Id { get; }
public string Shortcut { get; private set; }
public bool HotKeyRegistered { get; set; }
internal void SetModifiers(int mods)
{
Modifiers = mods;
}
public ShortcutStruct(int modifiers, int virtualKeyCode, int id, string shortcut)
internal void SetKey(int key)
{
VirtualKeyCode = key;
}
internal void SetShortcut(string shortcut)
{
Shortcut = shortcut;
}
internal bool RegisterHotKey(nint handle)
{
var result = WinApi.RegisterHotKey(handle, Id, Modifiers, VirtualKeyCode);
if (!result)
{
VirtualKeyCode = virtualKeyCode;
Modifiers = modifiers;
Id = id;
Shortcut = shortcut;
var errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
Logger.Error($"Could not register shortcut {Shortcut}: {errorMessage}");
}
else
{
HotKeyRegistered = true;
}
internal void SetModifiers(int mods)
return result;
}
internal void UnregisterHotKey(nint handle)
{
if (!HotKeyRegistered)
{
Modifiers = mods;
return;
}
internal void SetKey(int key)
{
VirtualKeyCode = key;
}
WinApi.UnregisterHotKey(handle, Id);
internal void SetShortcut(string shortcut)
{
Shortcut = shortcut;
}
internal bool RegisterHotKey(nint handle)
{
var result = WinApi.RegisterHotKey(handle, Id, Modifiers, VirtualKeyCode);
if (!result)
{
var errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
Logger.Error($"Could not register shortcut {Shortcut}: {errorMessage}");
}
else
{
HotKeyRegistered = true;
}
return result;
}
internal void UnregisterHotKey(nint handle)
{
if (!HotKeyRegistered)
{
return;
}
WinApi.UnregisterHotKey(handle, Id);
HotKeyRegistered = false;
}
HotKeyRegistered = false;
}
}
+37 -7
View File
@@ -1,12 +1,42 @@
using Newtonsoft.Json;
using ColorControl.Shared.Common;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using NLog;
namespace ColorControl.Shared.Contracts
namespace ColorControl.Shared.Contracts;
public class Module
{
public class Module
public bool IsActive { get; set; }
public string DisplayName { get; set; }
[JsonIgnore]
public Func<UserControl> InitAction { get; set; }
}
public class ModuleEx<T> where T : class
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public bool IsActive { get; set; }
public string DisplayName { get; set; }
public T CreateService(IServiceProvider serviceProvider)
{
public bool IsActive { get; set; }
public string DisplayName { get; set; }
[JsonIgnore]
public Func<UserControl> InitAction { get; set; }
try
{
Logger.Debug($"Initializing {typeof(T).Name}...");
var service = serviceProvider.GetRequiredService<T>();
Logger.Debug($"Initializing {typeof(T).Name}...Done");
return service;
}
catch (Exception ex)
{
Logger.Debug($"Error initializing {typeof(T).Name}. No device(s) or drivers are available: {ex.ToLogString()}");
return null;
}
}
}
@@ -0,0 +1,370 @@
using ColorControl.Shared.Common;
using ColorControl.Shared.Forms;
using Linearstar.Windows.RawInput;
using Linearstar.Windows.RawInput.Native;
namespace ColorControl.Shared.EventDispatcher;
public class KeyboardShortcutEventArgs : EventArgs
{
public int HotKeyId { get; set; }
}
public class KeyboardShortcutDispatcher : EventDispatcher<KeyboardShortcutEventArgs>
{
[Flags]
public enum ModKeys : int
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Win = 8
}
public const string Event_HotKey = "HotKey";
public nint MainHandle { get; set; }
public bool UseRawInput { get; private set; }
private bool WinKeyDown = false;
private static readonly List<Keys> KeysWithoutModifiers = new List<Keys> { Keys.F13, Keys.F14, Keys.F15, Keys.F16, Keys.F17, Keys.F18, Keys.F19, Keys.F20, Keys.F21, Keys.F22, Keys.F23, Keys.F24 };
private static readonly List<Keys> Modifiers = new List<Keys> { Keys.ControlKey, Keys.Menu, Keys.ShiftKey, Keys.LWin };
private readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
private readonly HashSet<ModKeys> _downModifierKeys = new HashSet<ModKeys>();
private readonly HashSet<Keys> _downKeys = new HashSet<Keys>();
private readonly object _modifiersLock = new object();
private readonly WindowMessageDispatcher _windowMessageDispatcher;
private readonly Dictionary<int, ShortcutStruct> _registeredShortcuts = new Dictionary<int, ShortcutStruct>();
public KeyboardShortcutDispatcher(WindowMessageDispatcher windowMessageDispatcher)
{
_windowMessageDispatcher = windowMessageDispatcher;
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageHotKey, HotKeyPressed);
_windowMessageDispatcher.RegisterEventHandler(WindowMessageDispatcher.Event_WindowMessageInput, HandleInputMessage);
MainHandle = _windowMessageDispatcher.MessageForm.Handle;
}
private async void HotKeyPressed(object sender, WindowMessageEventArgs e)
{
await DispatchEventAsync(Event_HotKey, new KeyboardShortcutEventArgs { HotKeyId = (int)e.Message.WParam });
}
private async void HandleInputMessage(object sender, WindowMessageEventArgs e)
{
// Create an RawInputData from the handle stored in lParam.
var data = RawInputData.FromHandle(e.Message.LParam);
if (data is RawInputKeyboardData keyboard)
{
var shortcut = GetRawKeyboardInputShortcut(keyboard);
if (shortcut != null)
{
await DispatchEventAsync(Event_HotKey, new KeyboardShortcutEventArgs { HotKeyId = shortcut.Id });
}
}
}
public void SetUseRawInput(bool useRawInput)
{
if (UseRawInput == useRawInput)
{
return;
}
UseRawInput = useRawInput;
if (useRawInput)
{
UnregisterHotKeys();
RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, MainHandle);
}
else
{
RawInputDevice.UnregisterDevice(HidUsageAndPage.Keyboard);
RegisterHotKeys();
}
}
private void UnregisterHotKeys()
{
foreach (var shortcut in _registeredShortcuts.Values.Where(s => s.HotKeyRegistered).ToList())
{
shortcut.UnregisterHotKey(MainHandle);
}
}
private void RegisterHotKeys()
{
foreach (var shortcut in _registeredShortcuts.Values.Where(s => !s.HotKeyRegistered).ToList())
{
shortcut.RegisterHotKey(MainHandle);
}
}
public ShortcutStruct GetRawKeyboardInputShortcut(RawInputKeyboardData data)
{
var keyboard = data.Keyboard;
//Debug.WriteLine($"Key: {keyboard}");
var add = !keyboard.Flags.HasFlag(RawKeyboardFlags.Up);
var keys = (Keys)keyboard.VirutalKey;
var isModifier = Modifiers.Contains(keys);
var modKey = KeysToModKeys(keys);
var changed = false;
lock (_modifiersLock)
{
if (add)
{
if (isModifier)
{
changed = _downModifierKeys.Add(modKey);
}
else
{
changed = _downKeys.Add((Keys)keyboard.VirutalKey);
}
}
else
{
if (isModifier)
{
changed = _downModifierKeys.Remove(modKey);
}
else
{
changed = _downKeys.Remove((Keys)keyboard.VirutalKey);
}
}
}
if (!changed || _downKeys.Count != 1 || !(_downModifierKeys.Any() || KeysWithoutModifiers.Contains(_downKeys.First())))
{
return null;
}
var sum = _downModifierKeys.Sum(k => (int)k) * 1000;
sum += _downKeys.Sum(k => (int)k);
var shortcut = _registeredShortcuts.Values.FirstOrDefault(s => (s.Modifiers * 1000 + s.VirtualKeyCode) == sum);
if (shortcut == null)
{
return null;
}
return shortcut;
}
public bool RegisterShortcut(int id, string shortcut)
{
var clear = string.IsNullOrWhiteSpace(shortcut);
var shortcutStruct = GetShortcutById(id);
if (shortcutStruct == null)
{
if (clear)
{
return true;
}
var (mods, key) = ParseShortcut(shortcut);
shortcutStruct = new ShortcutStruct(mods, key, id, shortcut);
_registeredShortcuts[id] = shortcutStruct;
}
else if (clear)
{
shortcutStruct.UnregisterHotKey(id);
_registeredShortcuts.Remove(id);
return true;
}
else
{
var (mods, key) = ParseShortcut(shortcut);
if (shortcutStruct.Modifiers == mods && shortcutStruct.VirtualKeyCode == key)
{
return true;
}
shortcutStruct.SetModifiers(mods);
shortcutStruct.SetKey(key);
shortcutStruct.SetShortcut(shortcut);
shortcutStruct.UnregisterHotKey(MainHandle);
}
//if (UseRawInput)
//{
// return true;
//}
return shortcutStruct.RegisterHotKey(MainHandle);
}
private ShortcutStruct GetShortcutById(int id)
{
if (_registeredShortcuts.TryGetValue(id, out var shortcut))
{
return shortcut;
}
return null;
}
public static (int mods, int key) ParseShortcut(string shortcut)
{
int mods = 0;
var key = 0;
shortcut = shortcut.Replace(",", "");
shortcut = shortcut.Replace("+", "");
shortcut = shortcut.Replace(" ", " ");
var parts = shortcut.Split(' ');
if (parts.Length > 0)
{
for (int i = 0; i + 1 < parts.Length; i++)
{
switch (parts[i])
{
case "Alt":
mods += (int)ModKeys.Alt;
break;
case "Control":
mods += (int)ModKeys.Control;
break;
case "Shift":
mods += (int)ModKeys.Shift;
break;
case "Win":
mods += (int)ModKeys.Win;
break;
}
}
var keyName = parts[parts.Length - 1];
key = (int)Enum.Parse(typeof(Keys), keyName);
}
return (mods, key);
}
public static Keys ShortcutToKeys(string shortcut)
{
var (mods, key) = ParseShortcut(shortcut);
var keys = Keys.None;
if (((uint)mods & (uint)ModKeys.Alt) > 0)
{
keys |= Keys.Alt;
}
if (((uint)mods & (uint)ModKeys.Control) > 0)
{
keys |= Keys.Control;
}
if (((uint)mods & (uint)ModKeys.Shift) > 0)
{
keys |= Keys.Shift;
}
if (((uint)mods & (uint)ModKeys.Win) > 0)
{
keys |= Keys.Control;
}
keys |= (Keys)key;
return keys;
}
public static ModKeys KeysToModKeys(Keys key)
{
return key switch
{
Keys.ControlKey => ModKeys.Control,
Keys.Menu => ModKeys.Alt,
Keys.ShiftKey => ModKeys.Shift,
Keys.LWin => ModKeys.Win,
_ => ModKeys.None,
};
}
public string FormatKeyboardShortcut(KeyEventArgs keyEvent)
{
var pressedModifiers = keyEvent.Modifiers;
//Debug.WriteLine("KD: " + e.Modifiers + ", " + e.KeyCode);
var shortcutString = pressedModifiers > 0 ? pressedModifiers.ToString() : "";
if (keyEvent.KeyCode == Keys.LWin || WinKeyDown)
{
WinKeyDown = true;
if (!string.IsNullOrEmpty(shortcutString))
{
shortcutString += ", ";
}
shortcutString += "Win";
}
var empty = string.IsNullOrEmpty(shortcutString);
if ((!empty || KeysWithoutModifiers.Contains(keyEvent.KeyCode)) && keyEvent.KeyCode != Keys.ControlKey && keyEvent.KeyCode != Keys.ShiftKey && keyEvent.KeyCode != Keys.Menu && keyEvent.KeyCode != Keys.LWin)
{
if (!empty)
{
shortcutString += " + ";
}
shortcutString += keyEvent.KeyCode.ToString();
}
if (string.IsNullOrEmpty(shortcutString))
{
keyEvent.SuppressKeyPress = true;
}
return shortcutString;
}
public static bool ValidateShortcut(string shortcut)
{
var valid = string.IsNullOrWhiteSpace(shortcut) || shortcut.Contains("+") || ShortcutIsAllowedWithoutModifier(shortcut);
if (!valid)
{
MessageForms.WarningOk("Invalid shortcut. The shortcut should have modifiers and a normal key or be F13-F24.");
}
return valid;
}
public static bool ShortcutIsAllowedWithoutModifier(string shortcut)
{
return Enum.TryParse<Keys>(shortcut, out var key) && KeysWithoutModifiers.Contains(key);
}
public void HandleKeyboardShortcutUp(KeyEventArgs keyEvent)
{
if (keyEvent.KeyCode == Keys.LWin)
{
WinKeyDown = false;
}
}
}
@@ -0,0 +1,86 @@
using ColorControl.Shared.Services;
using NWin32;
namespace ColorControl.Shared.EventDispatcher;
public class WindowMessageEventArgs : EventArgs
{
public Message Message { get; private set; }
public WindowMessageEventArgs(Message message)
{
Message = message;
}
}
public class WindowMessageDispatcher : EventDispatcher<WindowMessageEventArgs>
{
public const string Event_WindowMessage = "WindowMessage";
public const string Event_WindowMessageHotKey = "WindowMessageHotKey";
public const string Event_WindowMessageInput = "WindowMessageInput";
public const string Event_WindowMessageQueryEndSession = "WindowMessageQueryEndSession";
public const string Event_WindowMessageClose = "WindowMessageClose";
public const string Event_WindowMessagePowerBroadcast = "WindowMessagePowerBroadcast";
public const string Event_WindowMessageShowWindow = "WindowMessageShowWindow";
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
private readonly AppContextProvider _appContextProvider;
public DummyForm MessageForm { get; set; }
private static Dictionary<int, string> Messages = new() {
{ NativeConstants.WM_HOTKEY, Event_WindowMessageHotKey },
{ NativeConstants.WM_INPUT, Event_WindowMessageInput },
{ NativeConstants.WM_QUERYENDSESSION, Event_WindowMessageQueryEndSession },
{ NativeConstants.WM_CLOSE, Event_WindowMessageClose },
{ NativeConstants.WM_POWERBROADCAST, Event_WindowMessagePowerBroadcast },
{ NativeConstants.WM_SHOWWINDOW, Event_WindowMessageShowWindow }
};
public WindowMessageDispatcher(AppContextProvider appContextProvider)
{
MessageForm = new DummyForm();
MessageForm.OnMessage += MessageForm_OnMessage;
_appContextProvider = appContextProvider;
_appContextProvider.GetAppContext().MainHandle = MessageForm.Handle;
}
private void MessageForm_OnMessage(object sender, Message e)
{
if (Messages.TryGetValue(e.Msg, out var eventName))
{
DispatchEvent(eventName, new WindowMessageEventArgs(e));
}
}
public class DummyForm : Form
{
public event EventHandler<Message> OnMessage;
public DummyForm()
{
FormBorderStyle = FormBorderStyle.None;
ShowInTaskbar = false;
Load += DummyForm_Load;
Shown += DummyForm_Shown;
}
private void DummyForm_Shown(object sender, EventArgs e)
{
Hide();
}
protected void DummyForm_Load(object sender, EventArgs e)
{
Size = new Size(0, 0);
}
protected override void WndProc(ref Message m)
{
OnMessage?.Invoke(this, m);
base.WndProc(ref m);
}
}
}
+31 -26
View File
@@ -81,6 +81,35 @@ namespace ColorControl.Shared.Forms
}
}
public static void SetDarkMode(bool darkMode)
{
UseDarkMode = darkMode;
// Takes care of system context menu
WinApi.SetPreferredAppMode(darkMode ? 1 : 0);
var backColor = darkMode ? FormUtils.DarkModeBackColor : SystemColors.Control;
var foreColor = darkMode ? FormUtils.DarkModeForeColor : SystemColors.ControlText;
FormUtils.CurrentBackColor = backColor;
FormUtils.CurrentForeColor = foreColor;
if (darkMode)
{
_defaultRenderer ??= ToolStripManager.Renderer;
ToolStripManager.Renderer = new DarkModeToolStripRenderer();
}
else if (_defaultRenderer != null)
{
ToolStripManager.Renderer = _defaultRenderer;
}
FormUtils.MenuItemForeColor = FormUtils.CurrentForeColor;
WinApi.FlushMenuThemes();
}
public static void UpdateTheme(this Form form, bool? useDarkMode = null, bool onlyIfDark = false)
{
var toDark = useDarkMode ?? UseDarkMode;
@@ -90,7 +119,7 @@ namespace ColorControl.Shared.Forms
return;
}
UseDarkMode = toDark;
SetDarkMode(toDark);
form.SuspendLayout();
@@ -102,36 +131,12 @@ namespace ColorControl.Shared.Forms
//var backroundColorValue = settings.GetColorValue(UIColorType.Background);
//var isDarkMode = FormUtils.IsColorLight(foregroundColorValue);
// Takes care of system context menu
WinApi.SetPreferredAppMode(toDark ? 1 : 0);
var backColor = toDark ? FormUtils.DarkModeBackColor : SystemColors.Control;
var foreColor = toDark ? FormUtils.DarkModeForeColor : SystemColors.ControlText;
FormUtils.CurrentBackColor = backColor;
FormUtils.CurrentForeColor = foreColor;
SetControlTheme(form, backColor, foreColor);
SetControlTheme(form, FormUtils.CurrentBackColor, FormUtils.CurrentForeColor);
var value = toDark ? 1 : 0;
// Takes care of title bar
WinApi.DwmSetWindowAttribute(form.Handle, DWMWA_USE_IMMERSIVE_DARK_MODE, ref value, 4);
if (toDark)
{
_defaultRenderer ??= ToolStripManager.Renderer;
ToolStripManager.Renderer = new DarkModeToolStripRenderer();
}
else if (_defaultRenderer != null)
{
ToolStripManager.Renderer = _defaultRenderer;
}
FormUtils.MenuItemForeColor = foreColor;
WinApi.FlushMenuThemes();
}
finally
{
+6 -5
View File
@@ -113,32 +113,33 @@ namespace ColorControl.Shared.Forms
public class MessageForms
{
public static Form MainForm;
public static string Title = null;
public static void WarningOk(string text)
{
MessageBox.Show(text, MainForm?.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
MessageBox.Show(text, Title ?? "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
public static void ErrorOk(string text)
{
MessageBox.Show(text, MainForm?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(text, Title ?? "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
public static void InfoOk(string text, string title = null, string url = null)
{
if (url != null)
{
MessageBox.Show(text, title ?? MainForm?.Text, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0, url);
MessageBox.Show(text, title ?? Title ?? "Info", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0, url);
}
else
{
MessageBox.Show(text, title ?? MainForm?.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
MessageBox.Show(text, title ?? Title ?? "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
public static DialogResult QuestionYesNo(string text)
{
return MessageBox.Show(text, MainForm?.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Information);
return MessageBox.Show(text, Title ?? "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
}
public static List<FieldDefinition> ShowDialog(string caption, IEnumerable<string> labels, Func<IEnumerable<FieldDefinition>, string> validateFunc = null)