Merge branch 'develop'

This commit is contained in:
Terry MacDonald 2021-12-18 21:58:12 +13:00
commit 11f231a9f1
30 changed files with 54128 additions and 792 deletions

View File

@ -4,13 +4,15 @@ using DesktopNotifications;
using Microsoft.QueryStringDotNET;
using System.Windows.Forms;
using DisplayMagician.UIForms;
using DisplayMagicianShared;
namespace DisplayMagician
{
// The GUID must be unique to your app. Create a new GUID if copying this code.
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(INotificationActivationCallback))]
[Guid("56F14154-6339-4B94-8B82-80F78D5BCEAF"), ComVisible(true)]
[Guid(Program.AppActivationId), ComVisible(true)]
public class DesktopNotificationActivator : NotificationActivator
{
public override void OnActivated(string arguments, NotificationUserInput userInput, string appUserModelId)
@ -28,25 +30,26 @@ namespace DisplayMagician
if (myArg.Name.Equals("action",StringComparison.OrdinalIgnoreCase))
{
// See what action is being requested
switch (args["action"].ToLowerInvariant())
switch (args["action"])
{
// Open the image
// Open the Main window
case "open":
// Open the Main DisplayMagician Window
Program.AppMainForm.openApplicationWindow();
break;
// Background: Quick reply to the conversation
// Exit the application
case "exit":
// Exit the application (overriding the close restriction)
Program.AppMainForm.exitApplication();
break;
case "stop":
// Stop waiting so that the monitoring stops, and the UI becomes free
case "stopWaiting":
MessageBox.Show("User just asked DisplayMagician to stop monitoring the game");
ShortcutRepository.CancelWait = true;
break;
default:

View File

@ -142,6 +142,7 @@
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="ShortcutItem.cs" />
<Compile Include="ShortcutManager.cs" />
<Compile Include="ShortcutRepository.cs" />
<Compile Include="Processes\SingleInstanceHelper.cs" />
<Compile Include="UIForms\GameAdaptor.cs" />
@ -328,7 +329,7 @@
<Version>4.0.0-beta.74</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
<Version>7.1.1</Version>
<Version>7.1.2</Version>
</PackageReference>
<PackageReference Include="MintPlayer.IconUtils">
<Version>1.0.4</Version>
@ -343,7 +344,7 @@
<Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="NLog">
<Version>4.7.12</Version>
<Version>4.7.13</Version>
</PackageReference>
<PackageReference Include="protobuf-net">
<Version>3.0.101</Version>
@ -395,12 +396,6 @@
<None Include="Resources\nvidiawhite.png" />
<Content Include="Resources\redarrows.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DisplayMagicianShared\DisplayMagicianShared.csproj">
<Project>{1cacda43-01c7-4cd4-bf6e-9421a29510fc}</Project>
<Name>DisplayMagicianShared</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary">
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
@ -421,6 +416,12 @@
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DisplayMagicianShared\DisplayMagicianShared.csproj">
<Project>{1cacda43-01c7-4cd4-bf6e-9421a29510fc}</Project>
<Name>DisplayMagicianShared</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>"$(DevEnvDir)TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt"</PreBuildEvent>

View File

@ -158,18 +158,25 @@ namespace DisplayMagician.GameLibraries
{
List<Process> epicLibraryProcesses = new List<Process>();
foreach (string epicLibraryProcessName in _epicProcessList)
try
{
// Look for the processes with the ProcessName we sorted out earlier
epicLibraryProcesses.AddRange(Process.GetProcessesByName(epicLibraryProcessName));
}
foreach (string epicLibraryProcessName in _epicProcessList)
{
// Look for the processes with the ProcessName we sorted out earlier
epicLibraryProcesses.AddRange(Process.GetProcessesByName(epicLibraryProcessName));
}
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (epicLibraryProcesses.Count > 0)
return true;
else
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (epicLibraryProcesses.Count > 0)
return true;
else
return false;
}
catch (Exception ex)
{
return false;
}
}
}

View File

@ -163,18 +163,24 @@ namespace DisplayMagician.GameLibraries
{
List<Process> gogLibraryProcesses = new List<Process>();
foreach (string gogLibraryProcessName in _gogProcessList)
try
{
// Look for the processes with the ProcessName we sorted out earlier
gogLibraryProcesses.AddRange(Process.GetProcessesByName(gogLibraryProcessName));
}
foreach (string gogLibraryProcessName in _gogProcessList)
{
// Look for the processes with the ProcessName we sorted out earlier
gogLibraryProcesses.AddRange(Process.GetProcessesByName(gogLibraryProcessName));
}
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (gogLibraryProcesses.Count > 0)
return true;
else
return false;
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (gogLibraryProcesses.Count > 0)
return true;
else
return false;
}
catch (Exception ex) {
return false;
}
}
}

View File

@ -159,18 +159,25 @@ namespace DisplayMagician.GameLibraries
{
List<Process> originLibraryProcesses = new List<Process>();
foreach (string originLibraryProcessName in _originProcessList)
try
{
// Look for the processes with the ProcessName we sorted out earlier
originLibraryProcesses.AddRange(Process.GetProcessesByName(originLibraryProcessName));
}
foreach (string originLibraryProcessName in _originProcessList)
{
// Look for the processes with the ProcessName we sorted out earlier
originLibraryProcesses.AddRange(Process.GetProcessesByName(originLibraryProcessName));
}
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (originLibraryProcesses.Count > 0)
return true;
else
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (originLibraryProcesses.Count > 0)
return true;
else
return false;
}
catch (Exception ex)
{
return false;
}
}
}

View File

@ -176,18 +176,25 @@ namespace DisplayMagician.GameLibraries
{
List<Process> steamLibraryProcesses = new List<Process>();
foreach (string steamLibraryProcessName in _steamProcessList)
try
{
// Look for the processes with the ProcessName we sorted out earlier
steamLibraryProcesses.AddRange(Process.GetProcessesByName(steamLibraryProcessName));
}
foreach (string steamLibraryProcessName in _steamProcessList)
{
// Look for the processes with the ProcessName we sorted out earlier
steamLibraryProcesses.AddRange(Process.GetProcessesByName(steamLibraryProcessName));
}
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (steamLibraryProcesses.Count > 0)
return true;
else
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (steamLibraryProcesses.Count > 0)
return true;
else
return false;
}
catch (Exception ex)
{
return false;
}
}
}

View File

@ -157,18 +157,26 @@ namespace DisplayMagician.GameLibraries
{
List<Process> uplayLibraryProcesses = new List<Process>();
foreach (string uplayLibraryProcessName in _uplayProcessList)
try
{
// Look for the processes with the ProcessName we sorted out earlier
uplayLibraryProcesses.AddRange(Process.GetProcessesByName(uplayLibraryProcessName));
}
foreach (string uplayLibraryProcessName in _uplayProcessList)
{
// Look for the processes with the ProcessName we sorted out earlier
uplayLibraryProcesses.AddRange(Process.GetProcessesByName(uplayLibraryProcessName));
}
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (uplayLibraryProcesses.Count > 0)
return true;
else
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (uplayLibraryProcesses.Count > 0)
return true;
else
return false;
}
catch (Exception ex)
{
return false;
}
}
}

View File

@ -66,7 +66,7 @@ namespace DisplayMagician.Processes
else
{
logger.Warn($"ProcessUtils/StartProcess: {executable} {arguments} was unable to be started by TryExecute, so attempting with TryExecute_Impersonate");
ImpersonationProcess impProcessCreated;
/*ImpersonationProcess impProcessCreated;
//if (IsImpersonated())
//{
//logger.Trace($"ProcessUtils/StartProcess: Useer CAN be impersonated, so trying to run {executable} {arguments} with TryExecute_Impersonated");
@ -78,7 +78,7 @@ namespace DisplayMagician.Processes
else
{
logger.Error($"ProcessUtils/StartProcess: {executable} {arguments} was unable to be started by TryExecute_Impersonated, so giving up");
}
}*/
//}
//else
//{

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using DesktopNotifications;
using System.Windows.Forms;
using DisplayMagician.InterProcess;
using DisplayMagician.Resources;
@ -13,13 +14,14 @@ using DisplayMagician.UIForms;
using DisplayMagician.GameLibraries;
using System.Text.RegularExpressions;
using System.Drawing;
using DesktopNotifications;
using Windows.UI.Notifications;
using System.Runtime.Serialization;
using NLog.Config;
using System.Collections.Generic;
using AutoUpdaterDotNET;
using Newtonsoft.Json;
using System.Threading;
using Microsoft.Win32;
namespace DisplayMagician {
@ -38,6 +40,10 @@ namespace DisplayMagician {
public static string AppUplayIconFilename = Path.Combine(AppIconPath, @"Uplay.ico");
public static string AppEpicIconFilename = Path.Combine(AppIconPath, @"Epic.ico");
public static string AppDownloadsPath = Utils.GetDownloadsPath();
public static string AppPermStartMenuPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonPrograms), "DisplayMagician","DisplayMagician.lnk");
public static string AppTempStartMenuPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Programs),"DisplayMagician.lnk");
public const string AppUserModelId = "LittleBitBig.DisplayMagician";
public const string AppActivationId = "4F319902-EB8C-43E6-8A51-8EA74E4308F8";
public static bool AppToastActivated = false;
public static bool WaitingForGameToExit = false;
public static ProgramSettings AppProgramSettings;
@ -47,6 +53,7 @@ namespace DisplayMagician {
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private static SharedLogger sharedLogger;
private static bool _gamesLoaded = false;
private static bool _tempShortcutRegistered = false;
/// <summary>
/// The main entry point for the application.
@ -55,12 +62,7 @@ namespace DisplayMagician {
private static int Main(string[] args)
{
// This sets the Application User Model ID to "LittleBitBig.DisplayMagician" so that
// Windows 10 recognises the application, and allows features such as Toasts,
// taskbar pinning and similar.
// Register AUMID, COM server, and activator
DesktopNotificationManagerCompat.RegisterAumidAndComServer<DesktopNotificationActivator>(ShellUtils.AUMID);
DesktopNotificationManagerCompat.RegisterActivator<DesktopNotificationActivator>();
RegisterDisplayMagicianWithWindows();
// Prepare NLog for internal logging - Comment out when not required
//NLog.Common.InternalLogger.LogLevel = NLog.LogLevel.Debug;
@ -291,7 +293,7 @@ namespace DisplayMagician {
myMessageWindow.HeadingText = "DisplayMagician v2.1.0 Upgrade Warning";
myMessageWindow.ButtonText = "&Close";
myMessageWindow.ShowDialog();
}
}
logger.Debug($"Setting up commandline processing configuration");
var app = new CommandLineApplication
@ -309,6 +311,7 @@ namespace DisplayMagician {
app.HelpOption("-?|-h|--help", inherited:true);
app.VersionOption("-v|--version", () => {
DeRegisterDisplayMagicianWithWindows();
return string.Format("Version {0}", Assembly.GetExecutingAssembly().GetName().Version);
});
@ -384,6 +387,7 @@ namespace DisplayMagician {
GameLibrary.LoadGamesInBackground();
RunShortcut(argumentShortcut.Value);
DeRegisterDisplayMagicianWithWindows();
return 0;
});
});
@ -453,11 +457,13 @@ namespace DisplayMagician {
try
{
RunProfile(argumentProfile.Value);
DeRegisterDisplayMagicianWithWindows();
return 0;
}
catch (Exception ex)
{
logger.Error(ex, $"Program/Main exception running ApplyProfile(profileToUse)");
DeRegisterDisplayMagicianWithWindows();
return 1;
}
});
@ -522,6 +528,7 @@ namespace DisplayMagician {
logger.Debug($"CreateProfile commandline command was invoked!");
Console.WriteLine("Starting up and creating a new Display Profile...");
CreateProfile();
DeRegisterDisplayMagicianWithWindows();
return 0;
});
});
@ -603,6 +610,7 @@ namespace DisplayMagician {
GameLibrary.LoadGamesInBackground();
StartUpApplication();
DeRegisterDisplayMagicianWithWindows();
return 0;
});
@ -1016,7 +1024,7 @@ namespace DisplayMagician {
private static void AutoUpdaterOnParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
{
dynamic json = JsonConvert.DeserializeObject(args.RemoteData);
logger.Trace($"MainForm/AutoUpdaterOnParseUpdateInfoEvent: Received the following Update JSON file from {AutoUpdater.AppCastURL}: {args.RemoteData}");
logger.Trace($"Program/AutoUpdaterOnParseUpdateInfoEvent: Received the following Update JSON file from {AutoUpdater.AppCastURL}: {args.RemoteData}");
try
{
logger.Trace($"MainForm/AutoUpdaterOnParseUpdateInfoEvent: Trying to create an UpdateInfoEventArgs object from the received Update JSON file.");
@ -1040,7 +1048,7 @@ namespace DisplayMagician {
}
catch (Exception ex)
{
logger.Error(ex, $"MainForm/AutoUpdaterOnParseUpdateInfoEvent: Exception trying to create an UpdateInfoEventArgs object from the received Update JSON file.");
logger.Error(ex, $"Program/AutoUpdaterOnParseUpdateInfoEvent: Exception trying to create an UpdateInfoEventArgs object from the received Update JSON file.");
}
}
@ -1055,12 +1063,12 @@ namespace DisplayMagician {
if (Program.AppProgramSettings.ShowSplashScreen && Program.AppSplashScreen != null && !Program.AppSplashScreen.Disposing && !Program.AppSplashScreen.IsDisposed)
Program.AppSplashScreen.Invoke(new Action(() => Program.AppSplashScreen.Close()));
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - There is an upgrade to version {args.CurrentVersion} available from {args.DownloadURL}. We're using version {args.InstalledVersion} at the moment.");
logger.Info($"Program/AutoUpdaterOnCheckForUpdateEvent - There is an upgrade to version {args.CurrentVersion} available from {args.DownloadURL}. We're using version {args.InstalledVersion} at the moment.");
DialogResult dialogResult;
if (args.Mandatory.Value)
{
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - New version {args.CurrentVersion} available. Current version is {args.InstalledVersion}. Mandatory upgrade.");
logger.Info($"Program/AutoUpdaterOnCheckForUpdateEvent - New version {args.CurrentVersion} available. Current version is {args.InstalledVersion}. Mandatory upgrade.");
dialogResult =
MessageBox.Show(
$@"There is new version {args.CurrentVersion} available. You are using version {args.InstalledVersion}. This is required update. Press Ok to begin updating the application.", @"Update Available",
@ -1069,7 +1077,7 @@ namespace DisplayMagician {
}
else
{
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - New version {args.CurrentVersion} available. Current version is {args.InstalledVersion}. Optional upgrade.");
logger.Info($"Program/AutoUpdaterOnCheckForUpdateEvent - New version {args.CurrentVersion} available. Current version is {args.InstalledVersion}. Optional upgrade.");
dialogResult =
MessageBox.Show(
$@"There is new version {args.CurrentVersion} available. You are using version {
@ -1086,16 +1094,16 @@ namespace DisplayMagician {
{
try
{
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - Downloading {args.InstalledVersion} update.");
logger.Info($"Program/AutoUpdaterOnCheckForUpdateEvent - Downloading {args.InstalledVersion} update.");
if (AutoUpdater.DownloadUpdate(args))
{
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - Restarting to apply {args.InstalledVersion} update.");
logger.Info($"Program/AutoUpdaterOnCheckForUpdateEvent - Restarting to apply {args.InstalledVersion} update.");
Application.Exit();
}
}
catch (Exception ex)
{
logger.Warn(ex, $"MainForm/AutoUpdaterOnCheckForUpdateEvent - Exception during update download.");
logger.Warn(ex, $"Program/AutoUpdaterOnCheckForUpdateEvent - Exception during update download.");
MessageBox.Show(ex.Message, ex.GetType().ToString(), MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
@ -1110,14 +1118,14 @@ namespace DisplayMagician {
if (args.Error is WebException)
{
logger.Warn(args.Error, $"MainForm/AutoUpdaterOnCheckForUpdateEvent - WebException - There was a problem reaching the update server.");
logger.Warn(args.Error, $"Program/AutoUpdaterOnCheckForUpdateEvent - WebException - There was a problem reaching the update server.");
MessageBox.Show(
@"There is a problem reaching update server. Please check your internet connection and try again later.",
@"Update Check Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
logger.Warn(args.Error, $"MainForm/AutoUpdaterOnCheckForUpdateEvent - There was a problem performing the update: {args.Error.Message}");
logger.Warn(args.Error, $"Program/AutoUpdaterOnCheckForUpdateEvent - There was a problem performing the update: {args.Error.Message}");
MessageBox.Show(args.Error.Message,
args.Error.GetType().ToString(), MessageBoxButtons.OK,
MessageBoxIcon.Error);
@ -1125,10 +1133,77 @@ namespace DisplayMagician {
}
}
}
private static void RegisterDisplayMagicianWithWindows()
{
// This sets the Application User Model ID to "LittleBitBig.DisplayMagician" so that
// Windows 10 recognises the application, and allows features such as Toasts,
// taskbar pinning and similar.
// Register AUMID, COM server, and activator
DesktopNotificationManagerCompat.RegisterAumidAndComServer<DesktopNotificationActivator>(AppUserModelId);
DesktopNotificationManagerCompat.RegisterActivator<DesktopNotificationActivator>();
public class LoadingInstalledGamesException : Exception
// Force toasts to work if we're not 'installed' per se by creating a temp DisplayMagician start menu icon
// Allows running from a ZIP file rather than forcing the app to be installed. If we don't do this then Toasts just wouldn't work.
try
{
if (!IsInstalledVersion())
{
_tempShortcutRegistered = true;
ShortcutManager.RegisterAppForNotifications(
AppTempStartMenuPath, Assembly.GetExecutingAssembly().Location, null, AppUserModelId, AppActivationId);
}
}
catch (Exception ex)
{
logger.Warn(ex, $"Program/RegisterDisplayMagicianWithWindows - Exception while trying to register the temporary application shortcut {AppTempStartMenuPath}. Windows Toasts will not work.");
}
}
private static void DeRegisterDisplayMagicianWithWindows()
{
// Remove the temporary shortcut if we have added it
if (_tempShortcutRegistered)
{
try
{
File.Delete(AppTempStartMenuPath);
}
catch(Exception ex)
{
logger.Warn(ex, $"Program/DeRegisterDisplayMagicianWithWindows - Exception while deleting the temporary application shortcut {AppTempStartMenuPath} ");
}
_tempShortcutRegistered = false;
}
}
public static bool IsInstalledVersion()
{
string installKey = @"SOFTWARE\DisplayMagician";
string thisInstallDir = Path.GetDirectoryName(Application.ExecutablePath) + "\\";
try
{
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(installKey))
{
if (rk.GetValue("InstallDir") != null && rk.GetValue("InstallDir").ToString() == thisInstallDir)
{
return true; //exists
}
}
return false;
}
catch (Exception ex)
{
return false;
}
}
}
public class LoadingInstalledGamesException : Exception
{
public LoadingInstalledGamesException()
{ }

View File

@ -26,8 +26,8 @@ using System.Resources;
[assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
// Version information
[assembly: AssemblyVersion("2.1.1.1")]
[assembly: AssemblyFileVersion("2.1.1.1")]
[assembly: AssemblyVersion("2.1.2.1")]
[assembly: AssemblyFileVersion("2.1.2.1")]
[assembly: NeutralResourcesLanguageAttribute( "en" )]
[assembly: CLSCompliant(true)]

View File

@ -0,0 +1,521 @@
/**
* Copyright 2020 Google LLC.
* SPDX-License-Identifier: MIT
*/
//using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
using Microsoft.WindowsAPICodePack.PropertySystem;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace DisplayMagician
{
internal static class UnsafeNativeMethods
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct WIN32_FIND_DATAW
{
internal uint dwFileAttributes;
// ftCreationTime was a by-value FILETIME structure
internal uint ftCreationTime_dwLowDateTime;
internal uint ftCreationTime_dwHighDateTime;
// ftLastAccessTime was a by-value FILETIME structure
internal uint ftLastAccessTime_dwLowDateTime;
internal uint ftLastAccessTime_dwHighDateTime;
// ftLastWriteTime was a by-value FILETIME structure
internal uint ftLastWriteTime_dwLowDateTime;
internal uint ftLastWriteTime_dwHighDateTime;
internal uint nFileSizeHigh;
internal uint nFileSizeLow;
internal uint dwReserved0;
internal uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
internal string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
internal string cAlternateFileName;
}
/// <summary>IShellLink.Resolve fFlags</summary>
[Flags()]
internal enum SLR_FLAGS
{
/// <summary>
/// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set,
/// the high-order word of fFlags can be set to a time-out value that specifies the
/// maximum amount of time to be spent resolving the link. The function returns if the
/// link cannot be resolved within the time-out duration. If the high-order word is set
/// to zero, the time-out duration will be set to the default value of 3,000 milliseconds
/// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out
/// duration, in milliseconds.
/// </summary>
SLR_NO_UI = 0x1,
/// <summary>Obsolete and no longer used</summary>
SLR_ANY_MATCH = 0x2,
/// <summary>If the link object has changed, update its path and list of identifiers.
/// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine
/// whether or not the link object has changed.</summary>
SLR_UPDATE = 0x4,
/// <summary>Do not update the link information</summary>
SLR_NOUPDATE = 0x8,
/// <summary>Do not execute the search heuristics</summary>
SLR_NOSEARCH = 0x10,
/// <summary>Do not use distributed link tracking</summary>
SLR_NOTRACK = 0x20,
/// <summary>Disable distributed link tracking. By default, distributed link tracking tracks
/// removable media across multiple devices based on the volume name. It also uses the
/// Universal Naming Convention (UNC) path to track remote file systems whose drive letter
/// has changed. Setting SLR_NOLINKINFO disables both types of tracking.</summary>
SLR_NOLINKINFO = 0x40,
/// <summary>Call the Microsoft Windows Installer</summary>
SLR_INVOKE_MSI = 0x80
}
[Flags()]
internal enum SLGP_FLAGS
{
/// <summary>Retrieves the standard short (8.3 format) file name</summary>
SLGP_SHORTPATH = 0x1,
/// <summary>Retrieves the Universal Naming Convention (UNC) path name of the file</summary>
SLGP_UNCPRIORITY = 0x2,
/// <summary>Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded</summary>
SLGP_RAWPATH = 0x4
}
[SuppressUnmanagedCodeSecurity]
[DllImport("ole32.dll")]
public extern static int PropVariantClear(ref PROPVARIANT pvar);
}
[StructLayout(LayoutKind.Sequential)]
internal struct CLIPDATA
{
public uint cbSize; //ULONG
public int ulClipFmt; //long
public IntPtr pClipData; //BYTE*
}
// Credit: http://blogs.msdn.com/b/adamroot/archive/2008/04/11/interop-with-propvariants-in-net.aspx
/// <summary>
/// Represents the OLE struct PROPVARIANT.
/// </summary>
/// <remarks>
/// Must call Clear when finished to avoid memory leaks. If you get the value of
/// a VT_UNKNOWN prop, an implicit AddRef is called, thus your reference will
/// be active even after the PropVariant struct is cleared.
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
internal struct PROPVARIANT
{
#region struct fields
// The layout of these elements needs to be maintained.
//
// NOTE: We could use LayoutKind.Explicit, but we want
// to maintain that the IntPtr may be 8 bytes on
// 64-bit architectures, so we'll let the CLR keep
// us aligned.
//
// NOTE: In order to allow x64 compat, we need to allow for
// expansion of the IntPtr. However, the BLOB struct
// uses a 4-byte int, followed by an IntPtr, so
// although the p field catches most pointer values,
// we need an additional 4-bytes to get the BLOB
// pointer. The p2 field provides this, as well as
// the last 4-bytes of an 8-byte value on 32-bit
// architectures.
// This is actually a VarEnum value, but the VarEnum type
// shifts the layout of the struct by 4 bytes instead of the
// expected 2.
ushort vt;
ushort wReserved1;
ushort wReserved2;
ushort wReserved3;
public IntPtr p;
int p2;
#endregion // struct fields
#region union members
sbyte cVal // CHAR cVal;
{
get { return (sbyte)GetDataBytes()[0]; }
}
byte bVal // UCHAR bVal;
{
get { return GetDataBytes()[0]; }
}
short iVal // SHORT iVal;
{
get { return BitConverter.ToInt16(GetDataBytes(), 0); }
}
ushort uiVal // USHORT uiVal;
{
get { return BitConverter.ToUInt16(GetDataBytes(), 0); }
}
int lVal // LONG lVal;
{
get { return BitConverter.ToInt32(GetDataBytes(), 0); }
}
uint ulVal // ULONG ulVal;
{
get { return BitConverter.ToUInt32(GetDataBytes(), 0); }
}
long hVal // LARGE_INTEGER hVal;
{
get { return BitConverter.ToInt64(GetDataBytes(), 0); }
}
ulong uhVal // ULARGE_INTEGER uhVal;
{
get { return BitConverter.ToUInt64(GetDataBytes(), 0); }
}
float fltVal // FLOAT fltVal;
{
get { return BitConverter.ToSingle(GetDataBytes(), 0); }
}
double dblVal // DOUBLE dblVal;
{
get { return BitConverter.ToDouble(GetDataBytes(), 0); }
}
bool boolVal // VARIANT_BOOL boolVal;
{
get { return (iVal == 0 ? false : true); }
}
int scode // SCODE scode;
{
get { return lVal; }
}
decimal cyVal // CY cyVal;
{
get { return decimal.FromOACurrency(hVal); }
}
DateTime date // DATE date;
{
get { return DateTime.FromOADate(dblVal); }
}
#endregion // union members
private byte[] GetBlobData()
{
var blobData = new byte[lVal];
IntPtr pBlobData;
try
{
switch (IntPtr.Size)
{
case 4:
pBlobData = new IntPtr(p2);
break;
case 8:
pBlobData = new IntPtr(BitConverter.ToInt64(GetDataBytes(), sizeof(int)));
break;
default:
throw new NotSupportedException();
}
Marshal.Copy(pBlobData, blobData, 0, lVal);
}
catch
{
return null;
}
return blobData;
}
internal CLIPDATA GetCLIPDATA()
{
return (CLIPDATA)Marshal.PtrToStructure(p, typeof(CLIPDATA));
}
/// <summary>
/// Gets a byte array containing the data bits of the struct.
/// </summary>
/// <returns>A byte array that is the combined size of the data bits.</returns>
private byte[] GetDataBytes()
{
var ret = new byte[IntPtr.Size + sizeof(int)];
if (IntPtr.Size == 4)
{
BitConverter.GetBytes(p.ToInt32()).CopyTo(ret, 0);
}
else if (IntPtr.Size == 8)
{
BitConverter.GetBytes(p2).CopyTo(ret, IntPtr.Size);
}
return ret;
}
/// <summary>
/// Called to clear the PropVariant's referenced and local memory.
/// </summary>
/// <remarks>
/// You must call Clear to avoid memory leaks.
/// </remarks>
public void Clear()
{
// Can't pass "this" by ref, so make a copy to call PropVariantClear with
PROPVARIANT var = this;
UnsafeNativeMethods.PropVariantClear(ref var);
// Since we couldn't pass "this" by ref, we need to clear the member fields manually
// NOTE: PropVariantClear already freed heap data for us, so we are just setting
// our references to null.
vt = (ushort)VarEnum.VT_EMPTY;
wReserved1 = wReserved2 = wReserved3 = 0;
p = IntPtr.Zero;
p2 = 0;
}
/// <summary>
/// Gets the variant type.
/// </summary>
public VarEnum Type
{
get { return (VarEnum)vt; }
}
/// <summary>
/// Gets the variant value.
/// </summary>
public object Value
{
get
{
switch ((VarEnum)vt)
{
case VarEnum.VT_I1:
return cVal;
case VarEnum.VT_UI1:
return bVal;
case VarEnum.VT_I2:
return iVal;
case VarEnum.VT_UI2:
return uiVal;
case VarEnum.VT_I4:
case VarEnum.VT_INT:
return lVal;
case VarEnum.VT_UI4:
case VarEnum.VT_UINT:
return ulVal;
case VarEnum.VT_I8:
return hVal;
case VarEnum.VT_UI8:
return uhVal;
case VarEnum.VT_R4:
return fltVal;
case VarEnum.VT_R8:
return dblVal;
case VarEnum.VT_BOOL:
return boolVal;
case VarEnum.VT_ERROR:
return scode;
case VarEnum.VT_CY:
return cyVal;
case VarEnum.VT_DATE:
return date;
case VarEnum.VT_FILETIME:
if (hVal > 0)
{
return DateTime.FromFileTime(hVal);
}
else
{
return null;
}
case VarEnum.VT_BSTR:
return Marshal.PtrToStringBSTR(p);
case VarEnum.VT_LPSTR:
return Marshal.PtrToStringAnsi(p);
case VarEnum.VT_LPWSTR:
return Marshal.PtrToStringUni(p);
case VarEnum.VT_UNKNOWN:
return Marshal.GetObjectForIUnknown(p);
case VarEnum.VT_DISPATCH:
return p;
case VarEnum.VT_CLSID:
return Marshal.PtrToStructure(p, typeof(Guid));
//default:
// throw new NotSupportedException("The type of this variable is not support ('" + vt.ToString() + "')");
}
return null;
}
}
public PROPVARIANT(string value)
{
this.vt = (ushort)VarEnum.VT_LPWSTR;
this.p = Marshal.StringToCoTaskMemUni(value);
this.p2 = 0;
this.wReserved1 = 0;
this.wReserved2 = 0;
this.wReserved3 = 0;
}
public PROPVARIANT(Guid value)
{
this.vt = (ushort)VarEnum.VT_CLSID;
byte[] guid = value.ToByteArray();
this.p = Marshal.AllocCoTaskMem(guid.Length);
Marshal.Copy(guid, 0, p, guid.Length);
this.p2 = 0;
this.wReserved1 = 0;
this.wReserved2 = 0;
this.wReserved3 = 0;
}
}
/// <summary>
/// This is the CoClass that impliments the shell link interfaces.
/// </summary>
[ComImport, Guid("00021401-0000-0000-C000-000000000046")]
internal class ShellLinkCoClass { }
/// <summary>The IShellLink interface allows Shell links to be created, modified, and resolved</summary>
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")]
interface IShellLinkW
{
/// <summary>Retrieves the path and file name of a Shell link object</summary>
void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out UnsafeNativeMethods.WIN32_FIND_DATAW pfd, UnsafeNativeMethods.SLGP_FLAGS fFlags);
/// <summary>Retrieves the list of item identifiers for a Shell link object</summary>
void GetIDList(out IntPtr ppidl);
/// <summary>Sets the pointer to an item identifier list (PIDL) for a Shell link object.</summary>
void SetIDList(IntPtr pidl);
/// <summary>Retrieves the description string for a Shell link object</summary>
void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
/// <summary>Sets the description for a Shell link object. The description can be any application-defined string</summary>
void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
/// <summary>Retrieves the name of the working directory for a Shell link object</summary>
void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
/// <summary>Sets the name of the working directory for a Shell link object</summary>
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
/// <summary>Retrieves the command-line arguments associated with a Shell link object</summary>
void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
/// <summary>Sets the command-line arguments for a Shell link object</summary>
void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
/// <summary>Retrieves the hot key for a Shell link object</summary>
void GetHotkey(out short pwHotkey);
/// <summary>Sets a hot key for a Shell link object</summary>
void SetHotkey(short wHotkey);
/// <summary>Retrieves the show command for a Shell link object</summary>
void GetShowCmd(out int piShowCmd);
/// <summary>Sets the show command for a Shell link object. The show command sets the initial show state of the window.</summary>
void SetShowCmd(int iShowCmd);
/// <summary>Retrieves the location (path and index) of the icon for a Shell link object</summary>
void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
int cchIconPath, out int piIcon);
/// <summary>Sets the location (path and index) of the icon for a Shell link object</summary>
void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
/// <summary>Sets the relative path to the Shell link object</summary>
void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
/// <summary>Attempts to find the target of a Shell link, even if it has been moved or renamed</summary>
void Resolve(IntPtr hwnd, UnsafeNativeMethods.SLR_FLAGS fFlags);
/// <summary>Sets the path and file name of a Shell link object</summary>
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000010B-0000-0000-C000-000000000046")]
internal interface IPersistFile
{
#region Methods inherited from IPersist
void GetClassID(out Guid pClassID);
#endregion
[PreserveSig]
int IsDirty();
void Load(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
int dwMode);
void Save(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
[MarshalAs(UnmanagedType.Bool)] bool fRemember);
void SaveCompleted(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
void GetCurFile(
out IntPtr ppszFileName);
}
[ComImport, Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPropertyStore
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCount([Out] out uint cProps);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAt([In] uint iProp, out PropertyKey pkey);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetValue([In] ref PropertyKey key, out PROPVARIANT pv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetValue([In] ref PropertyKey key, [In] ref PROPVARIANT pv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Commit();
}
class ShortcutManager
{
/// <summary>
/// Creates a shortcut to enable the app to receive toast notifications.
/// </summary>
/// <remarks>
/// Documentation: https://docs.microsoft.com/en-us/windows/win32/shell/enable-desktop-toast-with-appusermodelid
/// </remarks>
/// <param name="shortcutPath">Full path to the shortcut (including .lnk), must be in Program Files or Start Menu</param>
/// <param name="appExecutablePath">Path the to app that receives notifications</param>
/// <param name="arguments">Optional arguments</param>
/// <param name="appName">The name of the app - used to create the toast</param>
/// <param name="activatorId">The activation id</param>
public static void RegisterAppForNotifications(string shortcutPath, string appExecutablePath, string arguments, string appName, string activatorId)
{
var shellLinkClass = new ShellLinkCoClass();
IShellLinkW shellLink = (IShellLinkW)shellLinkClass;
shellLink.SetPath(appExecutablePath);
IPropertyStore propertyStore = (IPropertyStore)shellLinkClass;
IPersistFile persistFile = (IPersistFile)shellLinkClass;
if (arguments != null)
{
shellLink.SetArguments(arguments);
}
// https://docs.microsoft.com/en-us/windows/win32/properties/props-system-appusermodel-id
propertyStore.SetValue(new PropertyKey("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3", 5), new PROPVARIANT(appName));
// https://docs.microsoft.com/en-us/windows/win32/properties/props-system-appusermodel-toastactivatorclsid
propertyStore.SetValue(new PropertyKey("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3", 26), new PROPVARIANT(new Guid(activatorId)));
propertyStore.Commit();
persistFile.Save(shortcutPath, true);
}
}
}

View File

@ -1074,6 +1074,7 @@ namespace DisplayMagician
.AddToastActivationInfo("notify=runningApplication", ToastActivationType.Foreground)
.AddText($"Running {shortcutToUse.ExecutableNameAndPath}", hintMaxLines: 1)
.AddText($"Waiting for all {processToMonitorName } processes to exit...")
.AddButton("Cancel", ToastActivationType.Background, "notify=runningApplication&action=stopWaiting")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
ToastContent toastContent = tcBuilder.Content;
@ -1154,6 +1155,7 @@ namespace DisplayMagician
{
while (true)
{
Application.DoEvents();
// If we have no more processes left then we're done!
if (ProcessUtils.ProcessExited(processesToMonitor))
{
@ -1161,6 +1163,11 @@ namespace DisplayMagician
break;
}
if (_cancelWait)
{
logger.Debug($"ShortcutRepository/RunShortcut: User requested we stop waiting. Exiting loop while waiting for application {shortcutToUse.ExecutableNameAndPath} to close.");
break;
}
// Send a message to windows so that it doesn't think
// we're locked and try to kill us
System.Threading.Thread.CurrentThread.Join(0);
@ -1168,14 +1175,31 @@ namespace DisplayMagician
}
}
logger.Debug($"ShortcutRepository/RunShortcut: Creating a Windows Toast to notify the user that the executable {shortcutToUse.ExecutableNameAndPath} has closed.");
// Tell the user that the application has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.ExecutableNameAndPath} was closed", hintMaxLines: 1)
.AddText($"All {processToMonitorName} processes were shutdown and changes were reverted.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
if (_cancelWait)
{
// The monitoring was stopped by the user
logger.Debug($"ShortcutRepository/RunShortcut: Creating a Windows Toast to notify the user that the executable {shortcutToUse.ExecutableNameAndPath} monitoring was stopped by the user.");
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopApplicationByUser", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.ExecutableNameAndPath} monitoring cancelled", hintMaxLines: 1)
.AddText($"Monitoring of {processToMonitorName} processes were stopped by the user.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
}
else
{
// The program was closed normally
logger.Debug($"ShortcutRepository/RunShortcut: Creating a Windows Toast to notify the user that the executable {shortcutToUse.ExecutableNameAndPath} has closed.");
// Tell the user that the application has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopApplicationDetected", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.ExecutableNameAndPath} was closed", hintMaxLines: 1)
.AddText($"All {processToMonitorName} processes were shutdown and changes were reverted.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
}
toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
doc = new XmlDocument();
@ -1253,7 +1277,7 @@ namespace DisplayMagician
// Now we want to tell the user we're start a game
// Construct the Windows toast content
ToastContentBuilder tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo($"notify=starting{gameLibraryToUse.GameLibraryName}", ToastActivationType.Foreground)
.AddToastActivationInfo($"notify=startingGameLibrary", ToastActivationType.Foreground)
.AddText($"Starting {gameLibraryToUse.GameLibraryName}", hintMaxLines: 1)
.AddText($"Waiting for {gameLibraryToUse.GameLibraryName} Game Library to start (and update if needed)...")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
@ -1315,7 +1339,7 @@ namespace DisplayMagician
// Now we want to tell the user we're updating the game library
// Construct the Windows toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo($"notify=updating{gameLibraryToUse.GameLibraryName}", ToastActivationType.Foreground)
.AddToastActivationInfo($"notify=updatingGameLibrary", ToastActivationType.Foreground)
.AddText($"Updating {gameLibraryToUse.GameLibraryName}", hintMaxLines: 1)
.AddText($"Waiting for {gameLibraryToUse.GameLibraryName} Game Library to update itself...")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
@ -1365,7 +1389,7 @@ namespace DisplayMagician
// Now we want to tell the user we're updating the game
// Construct the Windows toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo($"notify=updating{gameToRun.Name}", ToastActivationType.Foreground)
.AddToastActivationInfo($"notify=updatingGame", ToastActivationType.Foreground)
.AddText($"Updating {gameToRun.Name}", hintMaxLines: 1)
.AddText($"Waiting for {gameToRun.Name} Game to update...")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
@ -1492,7 +1516,7 @@ namespace DisplayMagician
// Now we want to tell the user we couldn't start the game!
// Construct the Windows toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo($"notify=errorRunning{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
.AddToastActivationInfo($"notify=errorRunningGame", ToastActivationType.Foreground)
.AddText($"Could not detect {shortcutToUse.GameName} starting", hintMaxLines: 1)
.AddText($"Could not detect {shortcutToUse.GameName} Game starting, so reverting changes back if needed. You may need to monitor a different game executable.");
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
@ -1516,8 +1540,9 @@ namespace DisplayMagician
// Now we want to tell the user we're running a game!
// Construct the Windows toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo($"notify=running{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
.AddToastActivationInfo($"notify=runningGame", ToastActivationType.Foreground)
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
.AddButton("Cancel", ToastActivationType.Background, "notify=runningGame&action=stopWaiting")
.AddText($"Waiting for the {gameToRun.ProcessName} game process to exit as {altGameProcessToMonitor} alternative game executable wasn't found...");
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
toastContent = tcBuilder.Content;
@ -1536,6 +1561,7 @@ namespace DisplayMagician
logger.Debug($"ShortcutRepository/RunShortcut: waiting for {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} to exit.");
while (true)
{
Application.DoEvents();
if (!gameToRun.IsRunning)
{
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} is no longer running (IsRunning is false).");
@ -1553,15 +1579,33 @@ namespace DisplayMagician
Thread.CurrentThread.Join(0);
Thread.Sleep(1000);
}
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} has exited.");
// Tell the user that the Game has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.GameName} was closed", hintMaxLines: 1)
.AddText($"{shortcutToUse.GameName} game was exited.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
if (_cancelWait)
{
// The monitoring was stopped by the user
logger.Debug($"ShortcutRepository/RunShortcut: Creating a Windows Toast to notify the user that the {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} monitoring was stopped by the user.");
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopGameByUser", ToastActivationType.Foreground)
.AddText($"{gameToRun.Name} Game monitoring cancelled", hintMaxLines: 1)
.AddText($"Monitoring of {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} was stopped by the user.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
}
else
{
// The program was closed normally
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} has exited.");
// Tell the user that the Game has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopGameDetected", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.GameName} was closed", hintMaxLines: 1)
.AddText($"{shortcutToUse.GameName} game was exited.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
}
toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
doc = new XmlDocument();
@ -1584,9 +1628,10 @@ namespace DisplayMagician
// Now we want to tell the user we're monitoring the alternative executables!
// Construct the Windows toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo($"notify=running{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
.AddToastActivationInfo($"notify=runningGame", ToastActivationType.Foreground)
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
.AddText($"Waiting for the {altGameProcessToMonitor} alternative game process to exit...")
.AddButton("Cancel", ToastActivationType.Background, "notify=runningGame&action=stopWaiting")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
toastContent = tcBuilder.Content;
@ -1602,6 +1647,7 @@ namespace DisplayMagician
while (true)
{
Application.DoEvents();
processesToMonitor = Process.GetProcessesByName(altGameProcessToMonitor).ToList();
// If we have no more processes left then we're done!
@ -1624,14 +1670,32 @@ namespace DisplayMagician
// Pause for a second
Thread.Sleep(1000);
}
logger.Debug($"ShortcutRepository/RunShortcut: Alternative Game Executable {altGameProcessToMonitor} has exited.");
// Tell the user that the Alt Game Executable has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
.AddText($"{altGameProcessToMonitor} was closed", hintMaxLines: 1)
.AddText($"{altGameProcessToMonitor} alternative game executable was exited.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
if (_cancelWait)
{
// The monitoring was stopped by the user
logger.Debug($"ShortcutRepository/RunShortcut: Creating a Windows Toast to notify the user that the Alternative Game Executable {altGameProcessToMonitor} monitoring was stopped by the user.");
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopGameByUser", ToastActivationType.Foreground)
.AddText($"{altGameProcessToMonitor} monitoring cancelled", hintMaxLines: 1)
.AddText($"Monitoring of {altGameProcessToMonitor} alternative game executable was stopped by the user.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
}
else
{
// The program was closed normally
logger.Debug($"ShortcutRepository/RunShortcut: Alternative Game Executable {altGameProcessToMonitor} has exited.");
// Tell the user that the Alt Game Executable has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopGameDetected", ToastActivationType.Foreground)
.AddText($"{altGameProcessToMonitor} was closed", hintMaxLines: 1)
.AddText($"{altGameProcessToMonitor} alternative game executable was exited.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
}
toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
doc = new XmlDocument();
@ -1651,9 +1715,10 @@ namespace DisplayMagician
// Now we want to tell the user we're running a game!
// Construct the Windows toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo($"notify=running{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
.AddToastActivationInfo($"notify=runningGame", ToastActivationType.Foreground)
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
.AddText($"Waiting for the {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} to exit...")
.AddButton("Cancel", ToastActivationType.Background, "notify=runningGame&action=stopWaiting")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
toastContent = tcBuilder.Content;
@ -1677,6 +1742,7 @@ namespace DisplayMagician
if (gameToRun.IsRunning)
{
// The game is running! So now we continue processing
Application.DoEvents();
gameRunning = true;
logger.Debug($"ShortcutRepository/RunShortcut: Found the '{gameToRun.Name}' process has started");
@ -1733,6 +1799,7 @@ namespace DisplayMagician
logger.Debug($"ShortcutRepository/RunShortcut: waiting for {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} to exit.");
while (true)
{
Application.DoEvents();
if (!gameToRun.IsRunning)
{
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} is no longer running (IsRunning is false).");
@ -1750,15 +1817,33 @@ namespace DisplayMagician
Thread.CurrentThread.Join(0);
Thread.Sleep(1000);
}
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} has exited.");
// Tell the user that the Game has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.GameName} was closed", hintMaxLines: 1)
.AddText($"{shortcutToUse.GameName} game was exited.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
if (_cancelWait)
{
// The monitoring was stopped by the user
logger.Debug($"ShortcutRepository/RunShortcut: Creating a Windows Toast to notify the user that the {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} monitoring was stopped by the user.");
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopGameByUser", ToastActivationType.Foreground)
.AddText($"{gameToRun.Name} Game monitoring cancelled", hintMaxLines: 1)
.AddText($"Monitoring of {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} was stopped by the user.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
}
else
{
// The program was closed normally
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} has exited.");
// Tell the user that the Game has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopGameDetected", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.GameName} was closed", hintMaxLines: 1)
.AddText($"{shortcutToUse.GameName} game was exited.")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"), false, true);
}
toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
doc = new XmlDocument();
@ -1960,7 +2045,18 @@ namespace DisplayMagician
// Reset the popup over the system tray icon to what's normal for it.
notifyIcon.Text = $"DisplayMagician";
// Set the notifyIcon text with the current profile
if (notifyIcon != null)
{
string shortProfileName = ProfileRepository.CurrentProfile.Name;
if (shortProfileName.Length >= 64)
{
shortProfileName = ProfileRepository.CurrentProfile.Name.Substring(0, 45);
}
notifyIcon.Text = $"DisplayMagician ({shortProfileName })";
Application.DoEvents();
}
Application.DoEvents();
}

View File

@ -59,25 +59,29 @@ namespace DisplayMagician.UIForms
this.btn_hotkey = new System.Windows.Forms.Button();
this.lbl_hotkey_assigned = new System.Windows.Forms.Label();
this.dv_profile = new DisplayMagicianShared.UserControls.DisplayView();
this.panel1 = new System.Windows.Forms.Panel();
this.p_upper = new System.Windows.Forms.Panel();
this.btn_profile_settings = new System.Windows.Forms.Button();
this.pbLogo = new System.Windows.Forms.PictureBox();
this.p_lower = new System.Windows.Forms.Panel();
this.p_fill = new System.Windows.Forms.Panel();
this.menu_profiles.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pb_down_arrow)).BeginInit();
this.panel1.SuspendLayout();
this.p_upper.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pbLogo)).BeginInit();
this.p_lower.SuspendLayout();
this.p_fill.SuspendLayout();
this.SuspendLayout();
//
// btn_apply
//
this.btn_apply.Anchor = System.Windows.Forms.AnchorStyles.None;
this.btn_apply.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btn_apply.BackColor = System.Drawing.Color.Black;
this.btn_apply.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_apply.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_apply.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_apply.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_apply.ForeColor = System.Drawing.Color.White;
this.btn_apply.Location = new System.Drawing.Point(194, 769);
this.btn_apply.Location = new System.Drawing.Point(300, 23);
this.btn_apply.Name = "btn_apply";
this.btn_apply.Size = new System.Drawing.Size(118, 40);
this.btn_apply.TabIndex = 2;
@ -93,7 +97,7 @@ namespace DisplayMagician.UIForms
this.btn_back.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_back.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_back.ForeColor = System.Drawing.Color.White;
this.btn_back.Location = new System.Drawing.Point(889, 794);
this.btn_back.Location = new System.Drawing.Point(847, 48);
this.btn_back.Name = "btn_back";
this.btn_back.Size = new System.Drawing.Size(75, 23);
this.btn_back.TabIndex = 5;
@ -103,13 +107,13 @@ namespace DisplayMagician.UIForms
//
// btn_delete
//
this.btn_delete.Anchor = System.Windows.Forms.AnchorStyles.None;
this.btn_delete.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btn_delete.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_delete.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_delete.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_delete.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_delete.ForeColor = System.Drawing.Color.White;
this.btn_delete.Location = new System.Drawing.Point(446, 769);
this.btn_delete.Location = new System.Drawing.Point(424, 23);
this.btn_delete.Name = "btn_delete";
this.btn_delete.Size = new System.Drawing.Size(120, 40);
this.btn_delete.TabIndex = 4;
@ -170,33 +174,35 @@ namespace DisplayMagician.UIForms
// btn_view_current
//
this.btn_view_current.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btn_view_current.BackColor = System.Drawing.Color.Black;
this.btn_view_current.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_view_current.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_view_current.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_view_current.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_view_current.ForeColor = System.Drawing.Color.White;
this.btn_view_current.Location = new System.Drawing.Point(712, 12);
this.btn_view_current.Location = new System.Drawing.Point(670, 18);
this.btn_view_current.Name = "btn_view_current";
this.btn_view_current.Size = new System.Drawing.Size(252, 39);
this.btn_view_current.TabIndex = 6;
this.btn_view_current.Text = "View &Current Display";
this.btn_view_current.UseVisualStyleBackColor = true;
this.btn_view_current.UseVisualStyleBackColor = false;
this.btn_view_current.Click += new System.EventHandler(this.btn_view_current_Click);
//
// btn_save_or_rename
//
this.btn_save_or_rename.Anchor = System.Windows.Forms.AnchorStyles.None;
this.btn_save_or_rename.BackColor = System.Drawing.Color.Black;
this.btn_save_or_rename.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_save_or_rename.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_save_or_rename.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_save_or_rename.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_save_or_rename.ForeColor = System.Drawing.Color.White;
this.btn_save_or_rename.Location = new System.Drawing.Point(146, 520);
this.btn_save_or_rename.Location = new System.Drawing.Point(120, 438);
this.btn_save_or_rename.Name = "btn_save_or_rename";
this.btn_save_or_rename.Size = new System.Drawing.Size(151, 33);
this.btn_save_or_rename.TabIndex = 1;
this.btn_save_or_rename.Text = "&Save As";
this.btn_save_or_rename.UseVisualStyleBackColor = true;
this.btn_save_or_rename.UseVisualStyleBackColor = false;
this.btn_save_or_rename.Click += new System.EventHandler(this.btn_save_as_Click);
//
// pb_down_arrow
@ -204,7 +210,7 @@ namespace DisplayMagician.UIForms
this.pb_down_arrow.Anchor = System.Windows.Forms.AnchorStyles.None;
this.pb_down_arrow.BackColor = System.Drawing.Color.DimGray;
this.pb_down_arrow.Image = ((System.Drawing.Image)(resources.GetObject("pb_down_arrow.Image")));
this.pb_down_arrow.Location = new System.Drawing.Point(461, 551);
this.pb_down_arrow.Location = new System.Drawing.Point(440, 467);
this.pb_down_arrow.Name = "pb_down_arrow";
this.pb_down_arrow.Size = new System.Drawing.Size(54, 27);
this.pb_down_arrow.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
@ -214,10 +220,10 @@ namespace DisplayMagician.UIForms
// lbl_profile_shown
//
this.lbl_profile_shown.AutoSize = true;
this.lbl_profile_shown.BackColor = System.Drawing.Color.DimGray;
this.lbl_profile_shown.BackColor = System.Drawing.Color.Black;
this.lbl_profile_shown.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lbl_profile_shown.ForeColor = System.Drawing.Color.White;
this.lbl_profile_shown.Location = new System.Drawing.Point(18, 73);
this.lbl_profile_shown.Location = new System.Drawing.Point(19, 22);
this.lbl_profile_shown.Name = "lbl_profile_shown";
this.lbl_profile_shown.Size = new System.Drawing.Size(205, 29);
this.lbl_profile_shown.TabIndex = 19;
@ -226,8 +232,10 @@ namespace DisplayMagician.UIForms
// txt_profile_save_name
//
this.txt_profile_save_name.Anchor = System.Windows.Forms.AnchorStyles.None;
this.txt_profile_save_name.BackColor = System.Drawing.Color.White;
this.txt_profile_save_name.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txt_profile_save_name.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txt_profile_save_name.Location = new System.Drawing.Point(297, 519);
this.txt_profile_save_name.Location = new System.Drawing.Point(271, 437);
this.txt_profile_save_name.MaxLength = 200;
this.txt_profile_save_name.Name = "txt_profile_save_name";
this.txt_profile_save_name.Size = new System.Drawing.Size(384, 35);
@ -241,14 +249,13 @@ namespace DisplayMagician.UIForms
this.ilv_saved_profiles.AllowColumnResize = false;
this.ilv_saved_profiles.AllowItemReorder = false;
this.ilv_saved_profiles.AllowPaneResize = false;
this.ilv_saved_profiles.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.ilv_saved_profiles.Location = new System.Drawing.Point(0, 601);
this.ilv_saved_profiles.Dock = System.Windows.Forms.DockStyle.Fill;
this.ilv_saved_profiles.Location = new System.Drawing.Point(0, 0);
this.ilv_saved_profiles.MultiSelect = false;
this.ilv_saved_profiles.Name = "ilv_saved_profiles";
this.ilv_saved_profiles.PersistentCacheDirectory = "";
this.ilv_saved_profiles.PersistentCacheSize = ((long)(100));
this.ilv_saved_profiles.Size = new System.Drawing.Size(976, 144);
this.ilv_saved_profiles.Size = new System.Drawing.Size(934, 141);
this.ilv_saved_profiles.TabIndex = 21;
this.ilv_saved_profiles.UseWIC = true;
this.ilv_saved_profiles.View = Manina.Windows.Forms.View.HorizontalStrip;
@ -258,10 +265,10 @@ namespace DisplayMagician.UIForms
// lbl_profile_shown_subtitle
//
this.lbl_profile_shown_subtitle.AutoSize = true;
this.lbl_profile_shown_subtitle.BackColor = System.Drawing.Color.DimGray;
this.lbl_profile_shown_subtitle.BackColor = System.Drawing.Color.Black;
this.lbl_profile_shown_subtitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lbl_profile_shown_subtitle.ForeColor = System.Drawing.Color.White;
this.lbl_profile_shown_subtitle.Location = new System.Drawing.Point(20, 102);
this.lbl_profile_shown_subtitle.Location = new System.Drawing.Point(21, 51);
this.lbl_profile_shown_subtitle.Name = "lbl_profile_shown_subtitle";
this.lbl_profile_shown_subtitle.Size = new System.Drawing.Size(132, 20);
this.lbl_profile_shown_subtitle.TabIndex = 22;
@ -269,11 +276,12 @@ namespace DisplayMagician.UIForms
//
// label1
//
this.label1.Anchor = System.Windows.Forms.AnchorStyles.None;
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.label1.AutoSize = true;
this.label1.BackColor = System.Drawing.Color.Black;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(263, 581);
this.label1.Location = new System.Drawing.Point(242, 497);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(450, 20);
this.label1.TabIndex = 23;
@ -281,30 +289,31 @@ namespace DisplayMagician.UIForms
//
// lbl_save_profile
//
this.lbl_save_profile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.lbl_save_profile.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.lbl_save_profile.BackColor = System.Drawing.Color.Brown;
this.lbl_save_profile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbl_save_profile.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
this.lbl_save_profile.ForeColor = System.Drawing.Color.White;
this.lbl_save_profile.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.lbl_save_profile.Location = new System.Drawing.Point(668, 82);
this.lbl_save_profile.Location = new System.Drawing.Point(319, 95);
this.lbl_save_profile.Name = "lbl_save_profile";
this.lbl_save_profile.Size = new System.Drawing.Size(296, 102);
this.lbl_save_profile.TabIndex = 33;
this.lbl_save_profile.Text = "Setup your displays with NVIDIA Setup, AMD Setup or Windows Setup, then return to" +
" DisplayMagician and click \'Save As\' to save this Display Profile.";
this.lbl_save_profile.Text = "Setup your display layout in NVIDIA Control Panel, AMD Radeon Adrenalin or Window" +
"s Setup, then return to DisplayMagician and click \'Save As\' to store this Displa" +
"y Profile for later.";
this.lbl_save_profile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// btn_save
//
this.btn_save.Anchor = System.Windows.Forms.AnchorStyles.None;
this.btn_save.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btn_save.BackColor = System.Drawing.Color.Black;
this.btn_save.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_save.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_save.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_save.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_save.ForeColor = System.Drawing.Color.White;
this.btn_save.Location = new System.Drawing.Point(572, 769);
this.btn_save.Location = new System.Drawing.Point(550, 23);
this.btn_save.Name = "btn_save";
this.btn_save.Size = new System.Drawing.Size(211, 40);
this.btn_save.TabIndex = 34;
@ -321,13 +330,13 @@ namespace DisplayMagician.UIForms
//
// btn_hotkey
//
this.btn_hotkey.Anchor = System.Windows.Forms.AnchorStyles.None;
this.btn_hotkey.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btn_hotkey.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_hotkey.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_hotkey.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_hotkey.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_hotkey.ForeColor = System.Drawing.Color.White;
this.btn_hotkey.Location = new System.Drawing.Point(320, 769);
this.btn_hotkey.Location = new System.Drawing.Point(174, 23);
this.btn_hotkey.Name = "btn_hotkey";
this.btn_hotkey.Size = new System.Drawing.Size(120, 40);
this.btn_hotkey.TabIndex = 35;
@ -337,11 +346,12 @@ namespace DisplayMagician.UIForms
//
// lbl_hotkey_assigned
//
this.lbl_hotkey_assigned.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.lbl_hotkey_assigned.AutoSize = true;
this.lbl_hotkey_assigned.BackColor = System.Drawing.Color.Transparent;
this.lbl_hotkey_assigned.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lbl_hotkey_assigned.ForeColor = System.Drawing.Color.White;
this.lbl_hotkey_assigned.Location = new System.Drawing.Point(20, 782);
this.lbl_hotkey_assigned.Location = new System.Drawing.Point(21, 39);
this.lbl_hotkey_assigned.Name = "lbl_hotkey_assigned";
this.lbl_hotkey_assigned.Size = new System.Drawing.Size(57, 16);
this.lbl_hotkey_assigned.TabIndex = 36;
@ -356,24 +366,35 @@ namespace DisplayMagician.UIForms
this.dv_profile.BackColor = System.Drawing.Color.DimGray;
this.dv_profile.Font = new System.Drawing.Font("Consolas", 50F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.dv_profile.ForeColor = System.Drawing.Color.MidnightBlue;
this.dv_profile.Location = new System.Drawing.Point(0, 120);
this.dv_profile.Location = new System.Drawing.Point(0, 95);
this.dv_profile.Margin = new System.Windows.Forms.Padding(18);
this.dv_profile.Name = "dv_profile";
this.dv_profile.PaddingX = 100;
this.dv_profile.PaddingY = 100;
this.dv_profile.Profile = null;
this.dv_profile.Size = new System.Drawing.Size(976, 399);
this.dv_profile.Size = new System.Drawing.Size(934, 399);
this.dv_profile.TabIndex = 4;
//
// panel1
// p_upper
//
this.panel1.BackColor = System.Drawing.Color.DimGray;
this.panel1.Controls.Add(this.btn_profile_settings);
this.panel1.Controls.Add(this.pbLogo);
this.panel1.Location = new System.Drawing.Point(0, 61);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(976, 521);
this.panel1.TabIndex = 37;
this.p_upper.BackColor = System.Drawing.Color.DimGray;
this.p_upper.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("p_upper.BackgroundImage")));
this.p_upper.Controls.Add(this.txt_profile_save_name);
this.p_upper.Controls.Add(this.lbl_save_profile);
this.p_upper.Controls.Add(this.btn_profile_settings);
this.p_upper.Controls.Add(this.pb_down_arrow);
this.p_upper.Controls.Add(this.pbLogo);
this.p_upper.Controls.Add(this.btn_view_current);
this.p_upper.Controls.Add(this.btn_save_or_rename);
this.p_upper.Controls.Add(this.label1);
this.p_upper.Controls.Add(this.lbl_profile_shown);
this.p_upper.Controls.Add(this.lbl_profile_shown_subtitle);
this.p_upper.Controls.Add(this.dv_profile);
this.p_upper.Dock = System.Windows.Forms.DockStyle.Top;
this.p_upper.Location = new System.Drawing.Point(0, 0);
this.p_upper.Name = "p_upper";
this.p_upper.Size = new System.Drawing.Size(934, 517);
this.p_upper.TabIndex = 37;
//
// btn_profile_settings
//
@ -384,7 +405,7 @@ namespace DisplayMagician.UIForms
this.btn_profile_settings.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_profile_settings.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_profile_settings.ForeColor = System.Drawing.Color.White;
this.btn_profile_settings.Location = new System.Drawing.Point(682, 459);
this.btn_profile_settings.Location = new System.Drawing.Point(655, 438);
this.btn_profile_settings.Name = "btn_profile_settings";
this.btn_profile_settings.Size = new System.Drawing.Size(170, 33);
this.btn_profile_settings.TabIndex = 38;
@ -395,13 +416,38 @@ namespace DisplayMagician.UIForms
// pbLogo
//
this.pbLogo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.pbLogo.Location = new System.Drawing.Point(854, 14);
this.pbLogo.Location = new System.Drawing.Point(822, 111);
this.pbLogo.Name = "pbLogo";
this.pbLogo.Size = new System.Drawing.Size(100, 49);
this.pbLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pbLogo.TabIndex = 0;
this.pbLogo.TabStop = false;
//
// p_lower
//
this.p_lower.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("p_lower.BackgroundImage")));
this.p_lower.Controls.Add(this.lbl_hotkey_assigned);
this.p_lower.Controls.Add(this.btn_hotkey);
this.p_lower.Controls.Add(this.btn_delete);
this.p_lower.Controls.Add(this.btn_apply);
this.p_lower.Controls.Add(this.btn_save);
this.p_lower.Controls.Add(this.btn_back);
this.p_lower.Dock = System.Windows.Forms.DockStyle.Bottom;
this.p_lower.Location = new System.Drawing.Point(0, 658);
this.p_lower.Name = "p_lower";
this.p_lower.Size = new System.Drawing.Size(934, 83);
this.p_lower.TabIndex = 38;
//
// p_fill
//
this.p_fill.BackColor = System.Drawing.Color.White;
this.p_fill.Controls.Add(this.ilv_saved_profiles);
this.p_fill.Dock = System.Windows.Forms.DockStyle.Fill;
this.p_fill.Location = new System.Drawing.Point(0, 517);
this.p_fill.Name = "p_fill";
this.p_fill.Size = new System.Drawing.Size(934, 141);
this.p_fill.TabIndex = 39;
//
// DisplayProfileForm
//
this.AcceptButton = this.btn_apply;
@ -410,28 +456,13 @@ namespace DisplayMagician.UIForms
this.BackColor = System.Drawing.Color.Black;
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.CancelButton = this.btn_back;
this.ClientSize = new System.Drawing.Size(976, 829);
this.Controls.Add(this.lbl_hotkey_assigned);
this.Controls.Add(this.btn_hotkey);
this.Controls.Add(this.btn_save);
this.Controls.Add(this.lbl_save_profile);
this.Controls.Add(this.label1);
this.Controls.Add(this.lbl_profile_shown_subtitle);
this.Controls.Add(this.ilv_saved_profiles);
this.Controls.Add(this.txt_profile_save_name);
this.Controls.Add(this.lbl_profile_shown);
this.Controls.Add(this.btn_save_or_rename);
this.Controls.Add(this.btn_view_current);
this.Controls.Add(this.btn_delete);
this.Controls.Add(this.btn_back);
this.Controls.Add(this.btn_apply);
this.Controls.Add(this.pb_down_arrow);
this.Controls.Add(this.dv_profile);
this.Controls.Add(this.panel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.ClientSize = new System.Drawing.Size(934, 741);
this.Controls.Add(this.p_fill);
this.Controls.Add(this.p_lower);
this.Controls.Add(this.p_upper);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimumSize = new System.Drawing.Size(800, 400);
this.MinimumSize = new System.Drawing.Size(950, 780);
this.Name = "DisplayProfileForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
@ -440,10 +471,13 @@ namespace DisplayMagician.UIForms
this.Load += new System.EventHandler(this.DisplayProfileForm_Load);
this.menu_profiles.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pb_down_arrow)).EndInit();
this.panel1.ResumeLayout(false);
this.p_upper.ResumeLayout(false);
this.p_upper.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pbLogo)).EndInit();
this.p_lower.ResumeLayout(false);
this.p_lower.PerformLayout();
this.p_fill.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
@ -474,9 +508,11 @@ namespace DisplayMagician.UIForms
private System.Windows.Forms.SaveFileDialog dialog_save;
private System.Windows.Forms.Button btn_hotkey;
private System.Windows.Forms.Label lbl_hotkey_assigned;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Panel p_upper;
private System.Windows.Forms.PictureBox pbLogo;
private System.Windows.Forms.Button btn_profile_settings;
private System.Windows.Forms.Panel p_lower;
private System.Windows.Forms.Panel p_fill;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.btn_help = new System.Windows.Forms.Button();
this.btn_donate = new System.Windows.Forms.Button();
this.btn_settings = new System.Windows.Forms.Button();
this.lbl_create_profile = new System.Windows.Forms.Label();
@ -55,7 +56,6 @@
this.shortcutToolStripSeparator = new System.Windows.Forms.ToolStripSeparator();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.btn_help = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
@ -90,6 +90,16 @@
this.splitContainer1.Panel2.Controls.Add(this.pb_game_shortcut);
this.splitContainer1.TabStop = false;
//
// btn_help
//
resources.ApplyResources(this.btn_help, "btn_help");
this.btn_help.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_help.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_help.ForeColor = System.Drawing.Color.White;
this.btn_help.Name = "btn_help";
this.btn_help.UseVisualStyleBackColor = true;
this.btn_help.Click += new System.EventHandler(this.btn_help_Click);
//
// btn_donate
//
resources.ApplyResources(this.btn_donate, "btn_donate");
@ -270,16 +280,6 @@
resources.ApplyResources(this.exitToolStripMenuItem, "exitToolStripMenuItem");
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// btn_help
//
resources.ApplyResources(this.btn_help, "btn_help");
this.btn_help.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_help.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_help.ForeColor = System.Drawing.Color.White;
this.btn_help.Name = "btn_help";
this.btn_help.UseVisualStyleBackColor = true;
this.btn_help.Click += new System.EventHandler(this.btn_help_Click);
//
// MainForm
//
resources.ApplyResources(this, "$this");

View File

@ -177,6 +177,19 @@ namespace DisplayMagician.UIForms
{
cb_minimise_notification_area.Checked = false;
}
// Set the notifyIcon text with the current profile
if (notifyIcon != null)
{
string shortProfileName = ProfileRepository.CurrentProfile.Name;
if (shortProfileName.Length >= 64)
{
shortProfileName = ProfileRepository.CurrentProfile.Name.Substring(0, 45);
}
notifyIcon.Text = $"DisplayMagician ({shortProfileName })";
Application.DoEvents();
}
// If we've been handed a Form of some kind, then open it straight away
if (formToOpen is DisplayProfileForm)

View File

@ -10870,7 +10870,7 @@
<value>NoControl</value>
</data>
<data name="lbl_create_shortcut.Location" type="System.Drawing.Point, System.Drawing">
<value>282, 248</value>
<value>282, 250</value>
</data>
<data name="lbl_create_shortcut.Size" type="System.Drawing.Size, System.Drawing">
<value>222, 22</value>
@ -10912,7 +10912,7 @@
<value>NoControl</value>
</data>
<data name="cb_minimise_notification_area.Location" type="System.Drawing.Point, System.Drawing">
<value>162, 354</value>
<value>162, 357</value>
</data>
<data name="cb_minimise_notification_area.Size" type="System.Drawing.Size, System.Drawing">
<value>460, 20</value>
@ -10945,7 +10945,7 @@
<value>Microsoft Sans Serif, 9.75pt</value>
</data>
<data name="lbl_version.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 355</value>
<value>12, 358</value>
</data>
<data name="lbl_version.Size" type="System.Drawing.Size, System.Drawing">
<value>25, 16</value>
@ -10981,7 +10981,7 @@
<value>Microsoft Sans Serif, 21.75pt</value>
</data>
<data name="btn_setup_game_shortcuts.Location" type="System.Drawing.Point, System.Drawing">
<value>212, 175</value>
<value>212, 177</value>
</data>
<data name="btn_setup_game_shortcuts.Size" type="System.Drawing.Size, System.Drawing">
<value>360, 50</value>
@ -11014,7 +11014,7 @@
<value>NoControl</value>
</data>
<data name="btn_exit.Location" type="System.Drawing.Point, System.Drawing">
<value>700, 351</value>
<value>700, 354</value>
</data>
<data name="btn_exit.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
@ -63370,81 +63370,6 @@
<metadata name="mainContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>152, 17</value>
</metadata>
<data name="toolStripMenuItemHeading.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="toolStripMenuItemHeading.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Italic</value>
</data>
<data name="toolStripMenuItemHeading.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="toolStripMenuItemHeading.Text" xml:space="preserve">
<value>DisplayMagician</value>
</data>
<data name="toolStripSeparator.Size" type="System.Drawing.Size, System.Drawing">
<value>215, 6</value>
</data>
<data name="openApplicationWindowToolStripMenuItem.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Bold</value>
</data>
<data name="openApplicationWindowToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="openApplicationWindowToolStripMenuItem.Text" xml:space="preserve">
<value>Open Application Window</value>
</data>
<data name="profilesToolStripMenuItemHeading.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="profilesToolStripMenuItemHeading.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Italic</value>
</data>
<data name="profilesToolStripMenuItemHeading.Size" type="System.Drawing.Size, System.Drawing">
<value>155, 22</value>
</data>
<data name="profilesToolStripMenuItemHeading.Text" xml:space="preserve">
<value>Display Profiles</value>
</data>
<data name="profileToolStripSeparator.Size" type="System.Drawing.Size, System.Drawing">
<value>152, 6</value>
</data>
<data name="profileToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="profileToolStripMenuItem.Text" xml:space="preserve">
<value>Change Display Profile</value>
</data>
<data name="shortcutsToolStripMenuItemHeading.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="shortcutsToolStripMenuItemHeading.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Italic</value>
</data>
<data name="shortcutsToolStripMenuItemHeading.Size" type="System.Drawing.Size, System.Drawing">
<value>156, 22</value>
</data>
<data name="shortcutsToolStripMenuItemHeading.Text" xml:space="preserve">
<value>Game Shortcuts</value>
</data>
<data name="shortcutToolStripSeparator.Size" type="System.Drawing.Size, System.Drawing">
<value>153, 6</value>
</data>
<data name="shortcutToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="shortcutToolStripMenuItem.Text" xml:space="preserve">
<value>Run Game Shortcut</value>
</data>
<data name="toolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
<value>215, 6</value>
</data>
<data name="exitToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>Exit DisplayMagician</value>
</data>
<data name="mainContextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
<value>219, 126</value>
</data>
@ -71274,6 +71199,81 @@
<data name="notifyIcon.Visible" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="toolStripMenuItemHeading.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="toolStripMenuItemHeading.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Italic</value>
</data>
<data name="toolStripMenuItemHeading.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="toolStripMenuItemHeading.Text" xml:space="preserve">
<value>DisplayMagician</value>
</data>
<data name="toolStripSeparator.Size" type="System.Drawing.Size, System.Drawing">
<value>215, 6</value>
</data>
<data name="openApplicationWindowToolStripMenuItem.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Bold</value>
</data>
<data name="openApplicationWindowToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="openApplicationWindowToolStripMenuItem.Text" xml:space="preserve">
<value>Open Application Window</value>
</data>
<data name="profileToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="profileToolStripMenuItem.Text" xml:space="preserve">
<value>Change Display Profile</value>
</data>
<data name="profilesToolStripMenuItemHeading.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="profilesToolStripMenuItemHeading.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Italic</value>
</data>
<data name="profilesToolStripMenuItemHeading.Size" type="System.Drawing.Size, System.Drawing">
<value>155, 22</value>
</data>
<data name="profilesToolStripMenuItemHeading.Text" xml:space="preserve">
<value>Display Profiles</value>
</data>
<data name="profileToolStripSeparator.Size" type="System.Drawing.Size, System.Drawing">
<value>152, 6</value>
</data>
<data name="shortcutToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="shortcutToolStripMenuItem.Text" xml:space="preserve">
<value>Run Game Shortcut</value>
</data>
<data name="shortcutsToolStripMenuItemHeading.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="shortcutsToolStripMenuItemHeading.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Italic</value>
</data>
<data name="shortcutsToolStripMenuItemHeading.Size" type="System.Drawing.Size, System.Drawing">
<value>156, 22</value>
</data>
<data name="shortcutsToolStripMenuItemHeading.Text" xml:space="preserve">
<value>Game Shortcuts</value>
</data>
<data name="shortcutToolStripSeparator.Size" type="System.Drawing.Size, System.Drawing">
<value>153, 6</value>
</data>
<data name="toolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
<value>215, 6</value>
</data>
<data name="exitToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 22</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>Exit DisplayMagician</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
@ -79103,14 +79103,11 @@
rjGJe6619efaHz2S/5D4v/OFla+gZqVXAAAAAElFTkSuQmCC
</value>
</data>
<data name="$this.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="$this.MaximumSize" type="System.Drawing.Size, System.Drawing">
<value>1100, 950</value>
</data>
<data name="$this.MinimumSize" type="System.Drawing.Size, System.Drawing">
<value>550, 400</value>
<value>700, 400</value>
</data>
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
<value>CenterScreen</value>

View File

@ -68,11 +68,14 @@ namespace DisplayMagician.UIForms
this.rb_change_audio = new System.Windows.Forms.RadioButton();
this.rb_no_change_audio = new System.Windows.Forms.RadioButton();
this.tabp_before = new System.Windows.Forms.TabPage();
this.p_start_program = new System.Windows.Forms.Panel();
this.btn_find_examples_startprograms = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.btn_add_new_start_program = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.flp_start_programs = new System.Windows.Forms.FlowLayoutPanel();
this.tabp_game = new System.Windows.Forms.TabPage();
this.ilv_games = new Manina.Windows.Forms.ImageListView();
this.p_gametostart = new System.Windows.Forms.Panel();
this.btn_find_examples_game = new System.Windows.Forms.Button();
this.p_standalone = new System.Windows.Forms.Panel();
this.btn_choose_exe_icon = new System.Windows.Forms.Button();
@ -98,7 +101,6 @@ namespace DisplayMagician.UIForms
this.pb_game_icon = new System.Windows.Forms.PictureBox();
this.lbl_no_game_libraries = new System.Windows.Forms.Label();
this.cbx_game_priority = new System.Windows.Forms.ComboBox();
this.ilv_games = new Manina.Windows.Forms.ImageListView();
this.cb_wait_alternative_game = new System.Windows.Forms.CheckBox();
this.btn_choose_alternative_game = new System.Windows.Forms.Button();
this.txt_alternative_game = new System.Windows.Forms.TextBox();
@ -144,7 +146,9 @@ namespace DisplayMagician.UIForms
this.gb_audio_volume.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nud_audio_volume)).BeginInit();
this.tabp_before.SuspendLayout();
this.p_start_program.SuspendLayout();
this.tabp_game.SuspendLayout();
this.p_gametostart.SuspendLayout();
this.p_standalone.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pb_exe_icon)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nud_timeout_executable)).BeginInit();
@ -160,15 +164,14 @@ namespace DisplayMagician.UIForms
//
// btn_save
//
this.btn_save.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.btn_save.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btn_save.Enabled = false;
this.btn_save.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_save.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_save.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_save.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_save.ForeColor = System.Drawing.Color.White;
this.btn_save.Location = new System.Drawing.Point(560, 891);
this.btn_save.Location = new System.Drawing.Point(545, 891);
this.btn_save.Name = "btn_save";
this.btn_save.Size = new System.Drawing.Size(120, 40);
this.btn_save.TabIndex = 6;
@ -184,7 +187,7 @@ namespace DisplayMagician.UIForms
this.btn_cancel.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_cancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_cancel.ForeColor = System.Drawing.Color.White;
this.btn_cancel.Location = new System.Drawing.Point(1008, 906);
this.btn_cancel.Location = new System.Drawing.Point(978, 906);
this.btn_cancel.Name = "btn_cancel";
this.btn_cancel.Size = new System.Drawing.Size(94, 25);
this.btn_cancel.TabIndex = 5;
@ -223,7 +226,7 @@ namespace DisplayMagician.UIForms
this.tabc_shortcut.Name = "tabc_shortcut";
this.tabc_shortcut.SelectedIndex = 0;
this.tabc_shortcut.ShowToolTips = true;
this.tabc_shortcut.Size = new System.Drawing.Size(1090, 767);
this.tabc_shortcut.Size = new System.Drawing.Size(1060, 767);
this.tabc_shortcut.TabIndex = 28;
//
// tabp_display
@ -239,7 +242,7 @@ namespace DisplayMagician.UIForms
this.tabp_display.Location = new System.Drawing.Point(4, 32);
this.tabp_display.Name = "tabp_display";
this.tabp_display.Padding = new System.Windows.Forms.Padding(3);
this.tabp_display.Size = new System.Drawing.Size(1082, 731);
this.tabp_display.Size = new System.Drawing.Size(1052, 731);
this.tabp_display.TabIndex = 0;
this.tabp_display.Text = "1. Choose Display Profile";
this.tabp_display.ToolTipText = "Choose which previously saved Display Profile you will use with this shortcut.";
@ -248,7 +251,7 @@ namespace DisplayMagician.UIForms
//
this.pbLogo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.pbLogo.BackColor = System.Drawing.Color.DimGray;
this.pbLogo.Location = new System.Drawing.Point(953, 20);
this.pbLogo.Location = new System.Drawing.Point(923, 20);
this.pbLogo.Name = "pbLogo";
this.pbLogo.Size = new System.Drawing.Size(100, 49);
this.pbLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
@ -286,14 +289,13 @@ namespace DisplayMagician.UIForms
this.ilv_saved_profiles.AllowColumnResize = false;
this.ilv_saved_profiles.AllowItemReorder = false;
this.ilv_saved_profiles.AllowPaneResize = false;
this.ilv_saved_profiles.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.ilv_saved_profiles.Location = new System.Drawing.Point(0, 477);
this.ilv_saved_profiles.Dock = System.Windows.Forms.DockStyle.Fill;
this.ilv_saved_profiles.Location = new System.Drawing.Point(3, 475);
this.ilv_saved_profiles.MultiSelect = false;
this.ilv_saved_profiles.Name = "ilv_saved_profiles";
this.ilv_saved_profiles.PersistentCacheDirectory = "";
this.ilv_saved_profiles.PersistentCacheSize = ((long)(100));
this.ilv_saved_profiles.Size = new System.Drawing.Size(1086, 258);
this.ilv_saved_profiles.Size = new System.Drawing.Size(1046, 253);
this.ilv_saved_profiles.TabIndex = 24;
this.ilv_saved_profiles.UseWIC = true;
this.ilv_saved_profiles.View = Manina.Windows.Forms.View.HorizontalStrip;
@ -312,7 +314,7 @@ namespace DisplayMagician.UIForms
this.dv_profile.PaddingX = 100;
this.dv_profile.PaddingY = 100;
this.dv_profile.Profile = null;
this.dv_profile.Size = new System.Drawing.Size(1076, 472);
this.dv_profile.Size = new System.Drawing.Size(1046, 472);
this.dv_profile.TabIndex = 23;
//
// tabp_audio
@ -326,20 +328,20 @@ namespace DisplayMagician.UIForms
this.tabp_audio.Location = new System.Drawing.Point(4, 32);
this.tabp_audio.Name = "tabp_audio";
this.tabp_audio.Padding = new System.Windows.Forms.Padding(3);
this.tabp_audio.Size = new System.Drawing.Size(1082, 731);
this.tabp_audio.Size = new System.Drawing.Size(1052, 731);
this.tabp_audio.TabIndex = 4;
this.tabp_audio.Text = "2. Choose Audio";
//
// lbl_no_active_capture_devices
//
this.lbl_no_active_capture_devices.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.lbl_no_active_capture_devices.Anchor = System.Windows.Forms.AnchorStyles.None;
this.lbl_no_active_capture_devices.AutoSize = true;
this.lbl_no_active_capture_devices.BackColor = System.Drawing.Color.Brown;
this.lbl_no_active_capture_devices.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbl_no_active_capture_devices.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
this.lbl_no_active_capture_devices.ForeColor = System.Drawing.Color.White;
this.lbl_no_active_capture_devices.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.lbl_no_active_capture_devices.Location = new System.Drawing.Point(126, 438);
this.lbl_no_active_capture_devices.Location = new System.Drawing.Point(111, 438);
this.lbl_no_active_capture_devices.Name = "lbl_no_active_capture_devices";
this.lbl_no_active_capture_devices.Size = new System.Drawing.Size(831, 22);
this.lbl_no_active_capture_devices.TabIndex = 36;
@ -356,7 +358,7 @@ namespace DisplayMagician.UIForms
this.lbl_no_active_audio_devices.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
this.lbl_no_active_audio_devices.ForeColor = System.Drawing.Color.White;
this.lbl_no_active_audio_devices.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.lbl_no_active_audio_devices.Location = new System.Drawing.Point(131, 153);
this.lbl_no_active_audio_devices.Location = new System.Drawing.Point(116, 153);
this.lbl_no_active_audio_devices.Name = "lbl_no_active_audio_devices";
this.lbl_no_active_audio_devices.Size = new System.Drawing.Size(804, 22);
this.lbl_no_active_audio_devices.TabIndex = 35;
@ -366,14 +368,14 @@ namespace DisplayMagician.UIForms
//
// lbl_disabled_shortcut_audio_chipset
//
this.lbl_disabled_shortcut_audio_chipset.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.lbl_disabled_shortcut_audio_chipset.Anchor = System.Windows.Forms.AnchorStyles.None;
this.lbl_disabled_shortcut_audio_chipset.AutoSize = true;
this.lbl_disabled_shortcut_audio_chipset.BackColor = System.Drawing.Color.Brown;
this.lbl_disabled_shortcut_audio_chipset.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbl_disabled_shortcut_audio_chipset.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
this.lbl_disabled_shortcut_audio_chipset.ForeColor = System.Drawing.Color.White;
this.lbl_disabled_shortcut_audio_chipset.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.lbl_disabled_shortcut_audio_chipset.Location = new System.Drawing.Point(263, 303);
this.lbl_disabled_shortcut_audio_chipset.Location = new System.Drawing.Point(248, 303);
this.lbl_disabled_shortcut_audio_chipset.Name = "lbl_disabled_shortcut_audio_chipset";
this.lbl_disabled_shortcut_audio_chipset.Size = new System.Drawing.Size(557, 22);
this.lbl_disabled_shortcut_audio_chipset.TabIndex = 34;
@ -382,13 +384,14 @@ namespace DisplayMagician.UIForms
//
// gb_capture_settings
//
this.gb_capture_settings.Anchor = System.Windows.Forms.AnchorStyles.None;
this.gb_capture_settings.Controls.Add(this.gb_capture_volume);
this.gb_capture_settings.Controls.Add(this.btn_rescan_capture);
this.gb_capture_settings.Controls.Add(this.cb_capture_device);
this.gb_capture_settings.Controls.Add(this.rb_change_capture);
this.gb_capture_settings.Controls.Add(this.rb_no_change_capture);
this.gb_capture_settings.ForeColor = System.Drawing.Color.White;
this.gb_capture_settings.Location = new System.Drawing.Point(65, 317);
this.gb_capture_settings.Location = new System.Drawing.Point(48, 317);
this.gb_capture_settings.Name = "gb_capture_settings";
this.gb_capture_settings.Size = new System.Drawing.Size(953, 256);
this.gb_capture_settings.TabIndex = 21;
@ -513,13 +516,14 @@ namespace DisplayMagician.UIForms
//
// gb_audio_settings
//
this.gb_audio_settings.Anchor = System.Windows.Forms.AnchorStyles.None;
this.gb_audio_settings.Controls.Add(this.gb_audio_volume);
this.gb_audio_settings.Controls.Add(this.btn_rescan_audio);
this.gb_audio_settings.Controls.Add(this.cb_audio_device);
this.gb_audio_settings.Controls.Add(this.rb_change_audio);
this.gb_audio_settings.Controls.Add(this.rb_no_change_audio);
this.gb_audio_settings.ForeColor = System.Drawing.Color.White;
this.gb_audio_settings.Location = new System.Drawing.Point(65, 30);
this.gb_audio_settings.Location = new System.Drawing.Point(48, 30);
this.gb_audio_settings.Name = "gb_audio_settings";
this.gb_audio_settings.Size = new System.Drawing.Size(953, 272);
this.gb_audio_settings.TabIndex = 0;
@ -645,61 +649,68 @@ namespace DisplayMagician.UIForms
// tabp_before
//
this.tabp_before.BackColor = System.Drawing.Color.Black;
this.tabp_before.Controls.Add(this.btn_find_examples_startprograms);
this.tabp_before.Controls.Add(this.label3);
this.tabp_before.Controls.Add(this.btn_add_new_start_program);
this.tabp_before.Controls.Add(this.p_start_program);
this.tabp_before.Controls.Add(this.flp_start_programs);
this.tabp_before.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tabp_before.ForeColor = System.Drawing.Color.White;
this.tabp_before.Location = new System.Drawing.Point(4, 32);
this.tabp_before.Name = "tabp_before";
this.tabp_before.Padding = new System.Windows.Forms.Padding(3);
this.tabp_before.Size = new System.Drawing.Size(1082, 731);
this.tabp_before.Size = new System.Drawing.Size(1052, 731);
this.tabp_before.TabIndex = 1;
this.tabp_before.Text = "3. Choose what happens before";
//
// p_start_program
//
this.p_start_program.Controls.Add(this.btn_find_examples_startprograms);
this.p_start_program.Controls.Add(this.btn_add_new_start_program);
this.p_start_program.Controls.Add(this.label3);
this.p_start_program.Dock = System.Windows.Forms.DockStyle.Top;
this.p_start_program.Location = new System.Drawing.Point(3, 3);
this.p_start_program.Name = "p_start_program";
this.p_start_program.Size = new System.Drawing.Size(1046, 121);
this.p_start_program.TabIndex = 41;
//
// btn_find_examples_startprograms
//
this.btn_find_examples_startprograms.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btn_find_examples_startprograms.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.btn_find_examples_startprograms.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_find_examples_startprograms.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_find_examples_startprograms.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_find_examples_startprograms.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_find_examples_startprograms.ForeColor = System.Drawing.Color.White;
this.btn_find_examples_startprograms.Location = new System.Drawing.Point(953, 76);
this.btn_find_examples_startprograms.Location = new System.Drawing.Point(912, 78);
this.btn_find_examples_startprograms.Name = "btn_find_examples_startprograms";
this.btn_find_examples_startprograms.Size = new System.Drawing.Size(117, 25);
this.btn_find_examples_startprograms.TabIndex = 40;
this.btn_find_examples_startprograms.TabIndex = 43;
this.btn_find_examples_startprograms.Text = "Show me &Examples";
this.btn_find_examples_startprograms.UseVisualStyleBackColor = true;
this.btn_find_examples_startprograms.Click += new System.EventHandler(this.btn_find_examples_startprograms_Click);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(138, 24);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(807, 20);
this.label3.TabIndex = 39;
this.label3.Text = "Add one or more additional programs to start before the main Game starts. They wi" +
"ll start in the order listed below.";
//
// btn_add_new_start_program
//
this.btn_add_new_start_program.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.btn_add_new_start_program.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.btn_add_new_start_program.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_add_new_start_program.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_add_new_start_program.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_add_new_start_program.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_add_new_start_program.ForeColor = System.Drawing.Color.White;
this.btn_add_new_start_program.Location = new System.Drawing.Point(424, 65);
this.btn_add_new_start_program.Location = new System.Drawing.Point(400, 63);
this.btn_add_new_start_program.Name = "btn_add_new_start_program";
this.btn_add_new_start_program.Size = new System.Drawing.Size(235, 40);
this.btn_add_new_start_program.TabIndex = 38;
this.btn_add_new_start_program.Size = new System.Drawing.Size(246, 40);
this.btn_add_new_start_program.TabIndex = 41;
this.btn_add_new_start_program.Text = "&Add Start Program";
this.btn_add_new_start_program.UseVisualStyleBackColor = true;
this.btn_add_new_start_program.Click += new System.EventHandler(this.btn_add_new_start_program_Click);
//
// label3
//
this.label3.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(136, 21);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(807, 20);
this.label3.TabIndex = 42;
this.label3.Text = "Add one or more additional programs to start before the main Game starts. They wi" +
"ll start in the order listed below.";
//
// flp_start_programs
//
@ -708,30 +719,55 @@ namespace DisplayMagician.UIForms
this.flp_start_programs.AutoScrollMargin = new System.Drawing.Size(5, 0);
this.flp_start_programs.AutoScrollMinSize = new System.Drawing.Size(5, 0);
this.flp_start_programs.BackColor = System.Drawing.Color.White;
this.flp_start_programs.Dock = System.Windows.Forms.DockStyle.Bottom;
this.flp_start_programs.Location = new System.Drawing.Point(3, 130);
this.flp_start_programs.Dock = System.Windows.Forms.DockStyle.Fill;
this.flp_start_programs.Location = new System.Drawing.Point(3, 3);
this.flp_start_programs.Name = "flp_start_programs";
this.flp_start_programs.Size = new System.Drawing.Size(1076, 598);
this.flp_start_programs.Size = new System.Drawing.Size(1046, 725);
this.flp_start_programs.TabIndex = 0;
//
// tabp_game
//
this.tabp_game.BackColor = System.Drawing.Color.Black;
this.tabp_game.Controls.Add(this.btn_find_examples_game);
this.tabp_game.Controls.Add(this.p_standalone);
this.tabp_game.Controls.Add(this.rb_standalone);
this.tabp_game.Controls.Add(this.rb_no_game);
this.tabp_game.Controls.Add(this.p_game);
this.tabp_game.Controls.Add(this.rb_launcher);
this.tabp_game.Controls.Add(this.ilv_games);
this.tabp_game.Controls.Add(this.p_gametostart);
this.tabp_game.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tabp_game.ForeColor = System.Drawing.Color.White;
this.tabp_game.Location = new System.Drawing.Point(4, 32);
this.tabp_game.Name = "tabp_game";
this.tabp_game.Padding = new System.Windows.Forms.Padding(3);
this.tabp_game.Size = new System.Drawing.Size(1082, 731);
this.tabp_game.Size = new System.Drawing.Size(1052, 731);
this.tabp_game.TabIndex = 2;
this.tabp_game.Text = "4. Choose Game to start";
//
// ilv_games
//
this.ilv_games.Dock = System.Windows.Forms.DockStyle.Fill;
this.ilv_games.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ilv_games.IntegralScroll = true;
this.ilv_games.Location = new System.Drawing.Point(3, 523);
this.ilv_games.Name = "ilv_games";
this.ilv_games.PersistentCacheDirectory = "";
this.ilv_games.PersistentCacheSize = ((long)(100));
this.ilv_games.Size = new System.Drawing.Size(1046, 205);
this.ilv_games.SortOrder = Manina.Windows.Forms.SortOrder.Ascending;
this.ilv_games.TabIndex = 42;
this.ilv_games.UseWIC = true;
this.ilv_games.ItemClick += new Manina.Windows.Forms.ItemClickEventHandler(this.ilv_games_ItemClick);
//
// p_gametostart
//
this.p_gametostart.Controls.Add(this.btn_find_examples_game);
this.p_gametostart.Controls.Add(this.p_standalone);
this.p_gametostart.Controls.Add(this.rb_standalone);
this.p_gametostart.Controls.Add(this.rb_no_game);
this.p_gametostart.Controls.Add(this.p_game);
this.p_gametostart.Controls.Add(this.rb_launcher);
this.p_gametostart.Dock = System.Windows.Forms.DockStyle.Top;
this.p_gametostart.Location = new System.Drawing.Point(3, 3);
this.p_gametostart.Name = "p_gametostart";
this.p_gametostart.Size = new System.Drawing.Size(1046, 520);
this.p_gametostart.TabIndex = 43;
//
// btn_find_examples_game
//
this.btn_find_examples_game.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
@ -740,16 +776,17 @@ namespace DisplayMagician.UIForms
this.btn_find_examples_game.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_find_examples_game.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_find_examples_game.ForeColor = System.Drawing.Color.White;
this.btn_find_examples_game.Location = new System.Drawing.Point(924, 19);
this.btn_find_examples_game.Location = new System.Drawing.Point(924, 11);
this.btn_find_examples_game.Name = "btn_find_examples_game";
this.btn_find_examples_game.Size = new System.Drawing.Size(117, 25);
this.btn_find_examples_game.TabIndex = 41;
this.btn_find_examples_game.TabIndex = 47;
this.btn_find_examples_game.Text = "Show me &Examples";
this.btn_find_examples_game.UseVisualStyleBackColor = true;
this.btn_find_examples_game.Click += new System.EventHandler(this.btn_find_examples_game_Click);
//
// p_standalone
//
this.p_standalone.Anchor = System.Windows.Forms.AnchorStyles.None;
this.p_standalone.Controls.Add(this.btn_choose_exe_icon);
this.p_standalone.Controls.Add(this.pb_exe_icon);
this.p_standalone.Controls.Add(this.cbx_exe_priority);
@ -766,10 +803,10 @@ namespace DisplayMagician.UIForms
this.p_standalone.Controls.Add(this.label2);
this.p_standalone.Controls.Add(this.nud_timeout_executable);
this.p_standalone.Enabled = false;
this.p_standalone.Location = new System.Drawing.Point(3, 86);
this.p_standalone.Location = new System.Drawing.Point(3, 79);
this.p_standalone.Name = "p_standalone";
this.p_standalone.Size = new System.Drawing.Size(1076, 201);
this.p_standalone.TabIndex = 10;
this.p_standalone.Size = new System.Drawing.Size(1046, 201);
this.p_standalone.TabIndex = 46;
//
// btn_choose_exe_icon
//
@ -795,13 +832,14 @@ namespace DisplayMagician.UIForms
this.pb_exe_icon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pb_exe_icon.TabIndex = 37;
this.pb_exe_icon.TabStop = false;
this.pb_exe_icon.Click += new System.EventHandler(this.pb_exe_icon_Click);
//
// cbx_exe_priority
//
this.cbx_exe_priority.AllowDrop = true;
this.cbx_exe_priority.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbx_exe_priority.FormattingEnabled = true;
this.cbx_exe_priority.Location = new System.Drawing.Point(917, 82);
this.cbx_exe_priority.Location = new System.Drawing.Point(888, 82);
this.cbx_exe_priority.Name = "cbx_exe_priority";
this.cbx_exe_priority.Size = new System.Drawing.Size(150, 28);
this.cbx_exe_priority.TabIndex = 31;
@ -810,11 +848,12 @@ namespace DisplayMagician.UIForms
//
this.lbl_exe_priority.AutoSize = true;
this.lbl_exe_priority.ForeColor = System.Drawing.Color.White;
this.lbl_exe_priority.Location = new System.Drawing.Point(770, 85);
this.lbl_exe_priority.Location = new System.Drawing.Point(741, 85);
this.lbl_exe_priority.Name = "lbl_exe_priority";
this.lbl_exe_priority.Size = new System.Drawing.Size(143, 20);
this.lbl_exe_priority.TabIndex = 30;
this.lbl_exe_priority.Text = "Executable Priority:";
this.lbl_exe_priority.Paint += new System.Windows.Forms.PaintEventHandler(this.label_Paint);
//
// btn_exe_to_start
//
@ -833,7 +872,7 @@ namespace DisplayMagician.UIForms
this.txt_args_executable.Enabled = false;
this.txt_args_executable.Location = new System.Drawing.Point(425, 46);
this.txt_args_executable.Name = "txt_args_executable";
this.txt_args_executable.Size = new System.Drawing.Size(642, 26);
this.txt_args_executable.Size = new System.Drawing.Size(613, 26);
this.txt_args_executable.TabIndex = 11;
//
// cb_args_executable
@ -854,7 +893,7 @@ namespace DisplayMagician.UIForms
//
this.btn_choose_alternative_executable.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_choose_alternative_executable.ForeColor = System.Drawing.Color.White;
this.btn_choose_alternative_executable.Location = new System.Drawing.Point(981, 155);
this.btn_choose_alternative_executable.Location = new System.Drawing.Point(953, 155);
this.btn_choose_alternative_executable.Name = "btn_choose_alternative_executable";
this.btn_choose_alternative_executable.Size = new System.Drawing.Size(85, 27);
this.btn_choose_alternative_executable.TabIndex = 9;
@ -867,9 +906,9 @@ namespace DisplayMagician.UIForms
this.txt_alternative_executable.Enabled = false;
this.txt_alternative_executable.Location = new System.Drawing.Point(633, 156);
this.txt_alternative_executable.Name = "txt_alternative_executable";
this.txt_alternative_executable.Size = new System.Drawing.Size(342, 26);
this.txt_alternative_executable.Size = new System.Drawing.Size(314, 26);
this.txt_alternative_executable.TabIndex = 4;
this.txt_alternative_executable.TextChanged += new System.EventHandler(this.txt_alternative_executable_TextChanged);
this.txt_alternative_executable.Click += new System.EventHandler(this.txt_alternative_executable_TextChanged);
//
// rb_wait_alternative_executable
//
@ -905,7 +944,7 @@ namespace DisplayMagician.UIForms
this.txt_executable.Name = "txt_executable";
this.txt_executable.Size = new System.Drawing.Size(489, 26);
this.txt_executable.TabIndex = 1;
this.txt_executable.TextChanged += new System.EventHandler(this.txt_executable_TextChanged);
this.txt_executable.Click += new System.EventHandler(this.txt_executable_TextChanged);
//
// lbl_app_executable
//
@ -923,7 +962,7 @@ namespace DisplayMagician.UIForms
//
this.label2.AutoSize = true;
this.label2.ForeColor = System.Drawing.Color.Transparent;
this.label2.Location = new System.Drawing.Point(881, 13);
this.label2.Location = new System.Drawing.Point(852, 13);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(125, 20);
this.label2.TabIndex = 5;
@ -932,7 +971,7 @@ namespace DisplayMagician.UIForms
//
// nud_timeout_executable
//
this.nud_timeout_executable.Location = new System.Drawing.Point(1012, 10);
this.nud_timeout_executable.Location = new System.Drawing.Point(983, 10);
this.nud_timeout_executable.Maximum = new decimal(new int[] {
240,
0,
@ -951,34 +990,36 @@ namespace DisplayMagician.UIForms
//
this.rb_standalone.AutoSize = true;
this.rb_standalone.ForeColor = System.Drawing.Color.White;
this.rb_standalone.Location = new System.Drawing.Point(16, 60);
this.rb_standalone.Location = new System.Drawing.Point(16, 53);
this.rb_standalone.Name = "rb_standalone";
this.rb_standalone.Size = new System.Drawing.Size(222, 24);
this.rb_standalone.TabIndex = 9;
this.rb_standalone.TabIndex = 45;
this.rb_standalone.Text = "Launch a Game executable";
this.rb_standalone.UseVisualStyleBackColor = true;
this.rb_standalone.CheckedChanged += new System.EventHandler(this.rb_standalone_CheckedChanged);
this.rb_standalone.Paint += new System.Windows.Forms.PaintEventHandler(this.radiobutton_Paint);
//
// rb_no_game
//
this.rb_no_game.AutoSize = true;
this.rb_no_game.ForeColor = System.Drawing.Color.White;
this.rb_no_game.Location = new System.Drawing.Point(15, 18);
this.rb_no_game.Location = new System.Drawing.Point(15, 11);
this.rb_no_game.Name = "rb_no_game";
this.rb_no_game.Size = new System.Drawing.Size(162, 24);
this.rb_no_game.TabIndex = 8;
this.rb_no_game.TabIndex = 44;
this.rb_no_game.Text = "Don\'t start a Game";
this.rb_no_game.UseVisualStyleBackColor = true;
this.rb_no_game.CheckedChanged += new System.EventHandler(this.rb_no_game_CheckedChanged);
this.rb_no_game.Paint += new System.Windows.Forms.PaintEventHandler(this.radiobutton_Paint);
//
// p_game
//
this.p_game.Anchor = System.Windows.Forms.AnchorStyles.None;
this.p_game.Controls.Add(this.btn_refresh_games_list);
this.p_game.Controls.Add(this.btn_choose_game_icon);
this.p_game.Controls.Add(this.pb_game_icon);
this.p_game.Controls.Add(this.lbl_no_game_libraries);
this.p_game.Controls.Add(this.cbx_game_priority);
this.p_game.Controls.Add(this.ilv_games);
this.p_game.Controls.Add(this.cb_wait_alternative_game);
this.p_game.Controls.Add(this.btn_choose_alternative_game);
this.p_game.Controls.Add(this.txt_alternative_game);
@ -990,20 +1031,20 @@ namespace DisplayMagician.UIForms
this.p_game.Controls.Add(this.lbl_game_timeout);
this.p_game.Controls.Add(this.nud_timeout_game);
this.p_game.Controls.Add(this.lbl_game_library);
this.p_game.Location = new System.Drawing.Point(3, 338);
this.p_game.Location = new System.Drawing.Point(3, 331);
this.p_game.Name = "p_game";
this.p_game.Size = new System.Drawing.Size(1076, 389);
this.p_game.TabIndex = 7;
this.p_game.Size = new System.Drawing.Size(1046, 181);
this.p_game.TabIndex = 43;
//
// btn_refresh_games_list
//
this.btn_refresh_games_list.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btn_refresh_games_list.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.btn_refresh_games_list.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_refresh_games_list.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_refresh_games_list.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_refresh_games_list.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_refresh_games_list.ForeColor = System.Drawing.Color.White;
this.btn_refresh_games_list.Location = new System.Drawing.Point(950, 162);
this.btn_refresh_games_list.Location = new System.Drawing.Point(921, 147);
this.btn_refresh_games_list.Name = "btn_refresh_games_list";
this.btn_refresh_games_list.Size = new System.Drawing.Size(117, 25);
this.btn_refresh_games_list.TabIndex = 42;
@ -1035,6 +1076,7 @@ namespace DisplayMagician.UIForms
this.pb_game_icon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pb_game_icon.TabIndex = 35;
this.pb_game_icon.TabStop = false;
this.pb_game_icon.Click += new System.EventHandler(this.pb_game_icon_Click);
//
// lbl_no_game_libraries
//
@ -1045,7 +1087,7 @@ namespace DisplayMagician.UIForms
this.lbl_no_game_libraries.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
this.lbl_no_game_libraries.ForeColor = System.Drawing.Color.White;
this.lbl_no_game_libraries.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.lbl_no_game_libraries.Location = new System.Drawing.Point(267, 162);
this.lbl_no_game_libraries.Location = new System.Drawing.Point(208, 147);
this.lbl_no_game_libraries.Name = "lbl_no_game_libraries";
this.lbl_no_game_libraries.Size = new System.Drawing.Size(613, 22);
this.lbl_no_game_libraries.TabIndex = 34;
@ -1059,43 +1101,29 @@ namespace DisplayMagician.UIForms
this.cbx_game_priority.AllowDrop = true;
this.cbx_game_priority.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbx_game_priority.FormattingEnabled = true;
this.cbx_game_priority.Location = new System.Drawing.Point(679, 11);
this.cbx_game_priority.Location = new System.Drawing.Point(666, 12);
this.cbx_game_priority.Name = "cbx_game_priority";
this.cbx_game_priority.Size = new System.Drawing.Size(164, 28);
this.cbx_game_priority.TabIndex = 29;
//
// ilv_games
//
this.ilv_games.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ilv_games.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ilv_games.IntegralScroll = true;
this.ilv_games.Location = new System.Drawing.Point(0, 200);
this.ilv_games.Name = "ilv_games";
this.ilv_games.PersistentCacheDirectory = "";
this.ilv_games.PersistentCacheSize = ((long)(100));
this.ilv_games.Size = new System.Drawing.Size(1076, 189);
this.ilv_games.SortOrder = Manina.Windows.Forms.SortOrder.Ascending;
this.ilv_games.TabIndex = 28;
this.ilv_games.UseWIC = true;
this.ilv_games.ItemClick += new Manina.Windows.Forms.ItemClickEventHandler(this.ilv_games_ItemClick);
//
// cb_wait_alternative_game
//
this.cb_wait_alternative_game.AutoSize = true;
this.cb_wait_alternative_game.Location = new System.Drawing.Point(165, 111);
this.cb_wait_alternative_game.Location = new System.Drawing.Point(165, 100);
this.cb_wait_alternative_game.Name = "cb_wait_alternative_game";
this.cb_wait_alternative_game.Size = new System.Drawing.Size(229, 24);
this.cb_wait_alternative_game.TabIndex = 27;
this.cb_wait_alternative_game.Text = "Monitor different executable:";
this.cb_wait_alternative_game.UseVisualStyleBackColor = true;
this.cb_wait_alternative_game.CheckedChanged += new System.EventHandler(this.cb_wait_alternative_game_CheckedChanged);
this.cb_wait_alternative_game.Paint += new System.Windows.Forms.PaintEventHandler(this.checkbox_Paint);
//
// btn_choose_alternative_game
//
this.btn_choose_alternative_game.Enabled = false;
this.btn_choose_alternative_game.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_choose_alternative_game.ForeColor = System.Drawing.Color.White;
this.btn_choose_alternative_game.Location = new System.Drawing.Point(981, 109);
this.btn_choose_alternative_game.Location = new System.Drawing.Point(953, 98);
this.btn_choose_alternative_game.Name = "btn_choose_alternative_game";
this.btn_choose_alternative_game.Size = new System.Drawing.Size(85, 27);
this.btn_choose_alternative_game.TabIndex = 26;
@ -1106,13 +1134,14 @@ namespace DisplayMagician.UIForms
// txt_alternative_game
//
this.txt_alternative_game.Enabled = false;
this.txt_alternative_game.Location = new System.Drawing.Point(399, 109);
this.txt_alternative_game.Location = new System.Drawing.Point(399, 98);
this.txt_alternative_game.Name = "txt_alternative_game";
this.txt_alternative_game.Size = new System.Drawing.Size(576, 26);
this.txt_alternative_game.Size = new System.Drawing.Size(548, 26);
this.txt_alternative_game.TabIndex = 24;
//
// txt_game_name
//
this.txt_game_name.Enabled = false;
this.txt_game_name.Location = new System.Drawing.Point(150, 11);
this.txt_game_name.Name = "txt_game_name";
this.txt_game_name.ReadOnly = true;
@ -1124,7 +1153,7 @@ namespace DisplayMagician.UIForms
//
this.lbl_game_priority.AutoSize = true;
this.lbl_game_priority.ForeColor = System.Drawing.Color.White;
this.lbl_game_priority.Location = new System.Drawing.Point(570, 14);
this.lbl_game_priority.Location = new System.Drawing.Point(557, 15);
this.lbl_game_priority.Name = "lbl_game_priority";
this.lbl_game_priority.Size = new System.Drawing.Size(108, 20);
this.lbl_game_priority.TabIndex = 18;
@ -1146,16 +1175,16 @@ namespace DisplayMagician.UIForms
// txt_args_game
//
this.txt_args_game.Enabled = false;
this.txt_args_game.Location = new System.Drawing.Point(399, 72);
this.txt_args_game.Location = new System.Drawing.Point(399, 61);
this.txt_args_game.Name = "txt_args_game";
this.txt_args_game.Size = new System.Drawing.Size(667, 26);
this.txt_args_game.Size = new System.Drawing.Size(639, 26);
this.txt_args_game.TabIndex = 13;
//
// cb_args_game
//
this.cb_args_game.AutoSize = true;
this.cb_args_game.ForeColor = System.Drawing.Color.White;
this.cb_args_game.Location = new System.Drawing.Point(166, 74);
this.cb_args_game.Location = new System.Drawing.Point(166, 63);
this.cb_args_game.Name = "cb_args_game";
this.cb_args_game.Size = new System.Drawing.Size(213, 24);
this.cb_args_game.TabIndex = 12;
@ -1169,7 +1198,7 @@ namespace DisplayMagician.UIForms
//
this.lbl_game_timeout.AutoSize = true;
this.lbl_game_timeout.ForeColor = System.Drawing.Color.White;
this.lbl_game_timeout.Location = new System.Drawing.Point(881, 14);
this.lbl_game_timeout.Location = new System.Drawing.Point(853, 14);
this.lbl_game_timeout.Name = "lbl_game_timeout";
this.lbl_game_timeout.Size = new System.Drawing.Size(125, 20);
this.lbl_game_timeout.TabIndex = 4;
@ -1178,7 +1207,7 @@ namespace DisplayMagician.UIForms
//
// nud_timeout_game
//
this.nud_timeout_game.Location = new System.Drawing.Point(1012, 13);
this.nud_timeout_game.Location = new System.Drawing.Point(984, 13);
this.nud_timeout_game.Maximum = new decimal(new int[] {
240,
0,
@ -1198,7 +1227,7 @@ namespace DisplayMagician.UIForms
this.lbl_game_library.Anchor = System.Windows.Forms.AnchorStyles.None;
this.lbl_game_library.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lbl_game_library.ForeColor = System.Drawing.Color.White;
this.lbl_game_library.Location = new System.Drawing.Point(408, 40);
this.lbl_game_library.Location = new System.Drawing.Point(393, -64);
this.lbl_game_library.Name = "lbl_game_library";
this.lbl_game_library.Size = new System.Drawing.Size(127, 22);
this.lbl_game_library.TabIndex = 30;
@ -1210,14 +1239,15 @@ namespace DisplayMagician.UIForms
this.rb_launcher.AutoSize = true;
this.rb_launcher.Checked = true;
this.rb_launcher.ForeColor = System.Drawing.Color.White;
this.rb_launcher.Location = new System.Drawing.Point(15, 309);
this.rb_launcher.Location = new System.Drawing.Point(15, 302);
this.rb_launcher.Name = "rb_launcher";
this.rb_launcher.Size = new System.Drawing.Size(466, 24);
this.rb_launcher.TabIndex = 6;
this.rb_launcher.TabIndex = 42;
this.rb_launcher.TabStop = true;
this.rb_launcher.Text = "Launch a Game installed in Steam, Origin, Uplay, Epic or GOG";
this.rb_launcher.UseVisualStyleBackColor = true;
this.rb_launcher.CheckedChanged += new System.EventHandler(this.rb_launcher_CheckedChanged);
this.rb_launcher.Paint += new System.Windows.Forms.PaintEventHandler(this.radiobutton_Paint);
//
// tabp_after
//
@ -1231,12 +1261,13 @@ namespace DisplayMagician.UIForms
this.tabp_after.Location = new System.Drawing.Point(4, 32);
this.tabp_after.Name = "tabp_after";
this.tabp_after.Padding = new System.Windows.Forms.Padding(3);
this.tabp_after.Size = new System.Drawing.Size(1082, 731);
this.tabp_after.Size = new System.Drawing.Size(1052, 731);
this.tabp_after.TabIndex = 3;
this.tabp_after.Text = "5. Choose what happens afterwards";
//
// groupBox3
//
this.groupBox3.Anchor = System.Windows.Forms.AnchorStyles.None;
this.groupBox3.Controls.Add(this.txt_run_cmd_afterwards_args);
this.groupBox3.Controls.Add(this.cb_run_cmd_afterwards_args);
this.groupBox3.Controls.Add(this.btn_run_cmd_afterwards);
@ -1306,6 +1337,7 @@ namespace DisplayMagician.UIForms
//
// groupBox2
//
this.groupBox2.Anchor = System.Windows.Forms.AnchorStyles.None;
this.groupBox2.Controls.Add(this.rb_switch_capture_permanent);
this.groupBox2.Controls.Add(this.rb_switch_capture_temp);
this.groupBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
@ -1345,6 +1377,7 @@ namespace DisplayMagician.UIForms
//
// groupBox1
//
this.groupBox1.Anchor = System.Windows.Forms.AnchorStyles.None;
this.groupBox1.Controls.Add(this.rb_switch_audio_permanent);
this.groupBox1.Controls.Add(this.rb_switch_audio_temp);
this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
@ -1384,6 +1417,7 @@ namespace DisplayMagician.UIForms
//
// gb_display_after
//
this.gb_display_after.Anchor = System.Windows.Forms.AnchorStyles.None;
this.gb_display_after.Controls.Add(this.rb_switch_display_permanent);
this.gb_display_after.Controls.Add(this.rb_switch_display_temp);
this.gb_display_after.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
@ -1429,7 +1463,7 @@ namespace DisplayMagician.UIForms
this.txt_shortcut_save_name.Location = new System.Drawing.Point(207, 844);
this.txt_shortcut_save_name.MaxLength = 200;
this.txt_shortcut_save_name.Name = "txt_shortcut_save_name";
this.txt_shortcut_save_name.Size = new System.Drawing.Size(744, 35);
this.txt_shortcut_save_name.Size = new System.Drawing.Size(714, 35);
this.txt_shortcut_save_name.TabIndex = 29;
this.txt_shortcut_save_name.Click += new System.EventHandler(this.txt_shortcut_save_name_Click);
this.txt_shortcut_save_name.TextChanged += new System.EventHandler(this.txt_shortcut_save_name_TextChanged);
@ -1460,13 +1494,11 @@ namespace DisplayMagician.UIForms
//
// cb_autosuggest
//
this.cb_autosuggest.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.cb_autosuggest.AutoSize = true;
this.cb_autosuggest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cb_autosuggest.Checked = true;
this.cb_autosuggest.CheckState = System.Windows.Forms.CheckState.Checked;
this.cb_autosuggest.ForeColor = System.Drawing.Color.White;
this.cb_autosuggest.Location = new System.Drawing.Point(969, 853);
this.cb_autosuggest.Location = new System.Drawing.Point(954, 853);
this.cb_autosuggest.Name = "cb_autosuggest";
this.cb_autosuggest.Size = new System.Drawing.Size(117, 17);
this.cb_autosuggest.TabIndex = 32;
@ -1476,14 +1508,13 @@ namespace DisplayMagician.UIForms
//
// btn_hotkey
//
this.btn_hotkey.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.btn_hotkey.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btn_hotkey.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_hotkey.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_hotkey.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_hotkey.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_hotkey.ForeColor = System.Drawing.Color.White;
this.btn_hotkey.Location = new System.Drawing.Point(434, 891);
this.btn_hotkey.Location = new System.Drawing.Point(419, 891);
this.btn_hotkey.Name = "btn_hotkey";
this.btn_hotkey.Size = new System.Drawing.Size(120, 40);
this.btn_hotkey.TabIndex = 36;
@ -1513,7 +1544,7 @@ namespace DisplayMagician.UIForms
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
this.CancelButton = this.btn_cancel;
this.ClientSize = new System.Drawing.Size(1114, 943);
this.ClientSize = new System.Drawing.Size(1084, 943);
this.Controls.Add(this.lbl_hotkey_assigned);
this.Controls.Add(this.btn_hotkey);
this.Controls.Add(this.cb_autosuggest);
@ -1523,9 +1554,9 @@ namespace DisplayMagician.UIForms
this.Controls.Add(this.tabc_shortcut);
this.Controls.Add(this.btn_cancel);
this.Controls.Add(this.btn_save);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(1100, 982);
this.Name = "ShortcutForm";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
@ -1549,9 +1580,11 @@ namespace DisplayMagician.UIForms
this.gb_audio_volume.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nud_audio_volume)).EndInit();
this.tabp_before.ResumeLayout(false);
this.tabp_before.PerformLayout();
this.p_start_program.ResumeLayout(false);
this.p_start_program.PerformLayout();
this.tabp_game.ResumeLayout(false);
this.tabp_game.PerformLayout();
this.p_gametostart.ResumeLayout(false);
this.p_gametostart.PerformLayout();
this.p_standalone.ResumeLayout(false);
this.p_standalone.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pb_exe_icon)).EndInit();
@ -1585,34 +1618,11 @@ namespace DisplayMagician.UIForms
private System.Windows.Forms.Label lbl_profile_shown;
private Manina.Windows.Forms.ImageListView ilv_saved_profiles;
private DisplayView dv_profile;
private System.Windows.Forms.TabPage tabp_before;
private System.Windows.Forms.TabPage tabp_game;
private System.Windows.Forms.TabPage tabp_after;
private System.Windows.Forms.TextBox txt_shortcut_save_name;
private System.Windows.Forms.Panel p_game;
private System.Windows.Forms.TextBox txt_game_name;
private System.Windows.Forms.Label lbl_game_name;
private System.Windows.Forms.TextBox txt_args_game;
private System.Windows.Forms.CheckBox cb_args_game;
private System.Windows.Forms.Label lbl_game_timeout;
private System.Windows.Forms.NumericUpDown nud_timeout_game;
private System.Windows.Forms.RadioButton rb_launcher;
private System.Windows.Forms.RadioButton rb_no_game;
private System.Windows.Forms.Panel p_standalone;
private System.Windows.Forms.TextBox txt_args_executable;
private System.Windows.Forms.CheckBox cb_args_executable;
private System.Windows.Forms.Button btn_choose_alternative_executable;
private System.Windows.Forms.TextBox txt_alternative_executable;
private System.Windows.Forms.RadioButton rb_wait_alternative_executable;
private System.Windows.Forms.RadioButton rb_wait_executable;
private System.Windows.Forms.TextBox txt_executable;
private System.Windows.Forms.Label lbl_app_executable;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.NumericUpDown nud_timeout_executable;
private System.Windows.Forms.RadioButton rb_standalone;
private System.Windows.Forms.Label lbl_title;
private System.Windows.Forms.Label lbl_shortcut_name;
private System.Windows.Forms.Button btn_exe_to_start;
private System.Windows.Forms.CheckBox cb_autosuggest;
private System.Windows.Forms.TabPage tabp_audio;
private System.Windows.Forms.GroupBox gb_display_after;
@ -1644,37 +1654,62 @@ namespace DisplayMagician.UIForms
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.RadioButton rb_switch_capture_permanent;
private System.Windows.Forms.RadioButton rb_switch_capture_temp;
private System.Windows.Forms.Label lbl_no_game_libraries;
private System.Windows.Forms.Label lbl_disabled_shortcut_audio_chipset;
private System.Windows.Forms.Label lbl_no_active_audio_devices;
private System.Windows.Forms.Label lbl_no_active_capture_devices;
private System.Windows.Forms.Button btn_choose_alternative_game;
private System.Windows.Forms.TextBox txt_alternative_game;
private System.Windows.Forms.CheckBox cb_wait_alternative_game;
private System.Windows.Forms.Button btn_hotkey;
private System.Windows.Forms.Label lbl_hotkey_assigned;
private System.Windows.Forms.FlowLayoutPanel flp_start_programs;
private System.Windows.Forms.Button btn_add_new_start_program;
private System.Windows.Forms.Label label3;
internal Manina.Windows.Forms.ImageListView ilv_games;
private System.Windows.Forms.Button btn_find_examples_startprograms;
private System.Windows.Forms.ComboBox cbx_exe_priority;
private System.Windows.Forms.Label lbl_exe_priority;
private System.Windows.Forms.Button btn_find_examples_game;
private System.Windows.Forms.Label lbl_game_library;
private System.Windows.Forms.ComboBox cbx_game_priority;
private System.Windows.Forms.Label lbl_game_priority;
private System.Windows.Forms.PictureBox pbLogo;
private System.Windows.Forms.Button btn_choose_exe_icon;
private System.Windows.Forms.PictureBox pb_exe_icon;
private System.Windows.Forms.Button btn_choose_game_icon;
private System.Windows.Forms.PictureBox pb_game_icon;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.Button btn_run_cmd_afterwards;
private System.Windows.Forms.TextBox txt_run_cmd_afterwards;
private System.Windows.Forms.CheckBox cb_run_cmd_afterwards;
private System.Windows.Forms.TextBox txt_run_cmd_afterwards_args;
private System.Windows.Forms.CheckBox cb_run_cmd_afterwards_args;
private System.Windows.Forms.TabPage tabp_before;
private System.Windows.Forms.Panel p_start_program;
private System.Windows.Forms.Button btn_find_examples_startprograms;
private System.Windows.Forms.Button btn_add_new_start_program;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.FlowLayoutPanel flp_start_programs;
private System.Windows.Forms.Panel p_gametostart;
private System.Windows.Forms.Button btn_find_examples_game;
private System.Windows.Forms.Panel p_standalone;
private System.Windows.Forms.Button btn_choose_exe_icon;
private System.Windows.Forms.PictureBox pb_exe_icon;
private System.Windows.Forms.ComboBox cbx_exe_priority;
private System.Windows.Forms.Label lbl_exe_priority;
private System.Windows.Forms.Button btn_exe_to_start;
private System.Windows.Forms.TextBox txt_args_executable;
private System.Windows.Forms.CheckBox cb_args_executable;
private System.Windows.Forms.Button btn_choose_alternative_executable;
private System.Windows.Forms.TextBox txt_alternative_executable;
private System.Windows.Forms.RadioButton rb_wait_alternative_executable;
private System.Windows.Forms.RadioButton rb_wait_executable;
private System.Windows.Forms.TextBox txt_executable;
private System.Windows.Forms.Label lbl_app_executable;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.NumericUpDown nud_timeout_executable;
private System.Windows.Forms.RadioButton rb_standalone;
private System.Windows.Forms.RadioButton rb_no_game;
private System.Windows.Forms.Panel p_game;
private System.Windows.Forms.Button btn_refresh_games_list;
private System.Windows.Forms.Button btn_choose_game_icon;
private System.Windows.Forms.PictureBox pb_game_icon;
private System.Windows.Forms.Label lbl_no_game_libraries;
private System.Windows.Forms.ComboBox cbx_game_priority;
private System.Windows.Forms.CheckBox cb_wait_alternative_game;
private System.Windows.Forms.Button btn_choose_alternative_game;
private System.Windows.Forms.TextBox txt_alternative_game;
private System.Windows.Forms.TextBox txt_game_name;
private System.Windows.Forms.Label lbl_game_priority;
private System.Windows.Forms.Label lbl_game_name;
private System.Windows.Forms.TextBox txt_args_game;
private System.Windows.Forms.CheckBox cb_args_game;
private System.Windows.Forms.Label lbl_game_timeout;
private System.Windows.Forms.NumericUpDown nud_timeout_game;
private System.Windows.Forms.Label lbl_game_library;
private System.Windows.Forms.RadioButton rb_launcher;
internal Manina.Windows.Forms.ImageListView ilv_games;
}
}

View File

@ -43,7 +43,7 @@ namespace DisplayMagician.UIForms
private bool _setCaptureVolume = false;
private decimal _captureVolume = -1;
private ShortcutItem _shortcutToEdit = null;
//List<Game> allGames = new List<Game>();
Game _selectedGame = null;
private bool _isUnsaved = true;
private bool _loadedShortcut = false;
private bool _autoName = true;
@ -966,8 +966,6 @@ namespace DisplayMagician.UIForms
private void LoadShortcut()
{
Game shortcutGame = null;
// Load all the profiles to prepare things
bool foundChosenProfileInLoadedProfiles = false;
ProfileItem chosenProfile = null;
@ -1223,7 +1221,7 @@ namespace DisplayMagician.UIForms
ilv_games.Items.Add(newItem, _gameAdaptor);
if (_editingExistingShortcut && game.Name.Equals(_shortcutToEdit.GameName))
{
shortcutGame = game;
_selectedGame = game;
}
}
@ -1478,12 +1476,12 @@ namespace DisplayMagician.UIForms
// If this is a shortcut we're editing
_availableImages = new List<ShortcutBitmap>();
// If the game is selected, then grab images from the game
if (shortcutGame != null)
if (_selectedGame != null)
{
_availableImages.AddRange(ImageUtils.GetMeAllBitmapsFromFile(shortcutGame.IconPath));
if (shortcutGame.ExePath != shortcutGame.IconPath)
_availableImages.AddRange(ImageUtils.GetMeAllBitmapsFromFile(_selectedGame.IconPath));
if (_selectedGame.ExePath != _selectedGame.IconPath)
{
_availableImages.AddRange(ImageUtils.GetMeAllBitmapsFromFile(shortcutGame.ExePath));
_availableImages.AddRange(ImageUtils.GetMeAllBitmapsFromFile(_selectedGame.ExePath));
}
}
@ -1731,9 +1729,10 @@ namespace DisplayMagician.UIForms
p_standalone.Enabled = true;
// Disable the Game Panel
p_game.Enabled = false;
ilv_games.Enabled = false;
// Empty the bitmaps
EmptyTheImages();
// EmptyTheImages();
if (!String.IsNullOrWhiteSpace(txt_executable.Text) && File.Exists(txt_executable.Text))
{
@ -1757,11 +1756,25 @@ namespace DisplayMagician.UIForms
// Enable the Game Panel
p_game.Enabled = true;
ilv_games.Enabled = true;
// Disable the Standalone Panel
p_standalone.Enabled = false;
// Empty the bitmaps
EmptyTheImages();
//EmptyTheImages();
if (!String.IsNullOrWhiteSpace(txt_game_name.Text) && ilv_games.SelectedItems.Count == 1 && _selectedGame != null && pb_game_icon.Image == null)
{
_gameLauncher = _selectedGame.GameLibrary.ToString("G");
lbl_game_library.Text = $"Game Library: {_gameLauncher}";
_gameId = _selectedGame.Id;
_availableImages = _selectedGame.AvailableGameBitmaps;
_shortcutToEdit.AvailableImages = _selectedGame.AvailableGameBitmaps;
_selectedImage = ImageUtils.GetMeLargestAvailableBitmap(_availableImages);
_shortcutToEdit.SelectedImage = _selectedImage;
pb_game_icon.Image = _selectedImage.Image;
btn_choose_game_icon.Enabled = true;
}
SuggestShortcutName();
EnableSaveButtonIfValid();
@ -1789,6 +1802,7 @@ namespace DisplayMagician.UIForms
// Disable the Standalone Panel
p_standalone.Enabled = false;
// Disable the Game Panel
ilv_games.Enabled = false;
p_game.Enabled = false;
SuggestShortcutName();
@ -2777,6 +2791,7 @@ namespace DisplayMagician.UIForms
{
if (_loadedShortcut)
_isUnsaved = true;
_selectedGame = game;
_gameLauncher = game.GameLibrary.ToString("G");
lbl_game_library.Text = $"Game Library: {_gameLauncher}";
_gameId = game.Id;
@ -2932,6 +2947,16 @@ namespace DisplayMagician.UIForms
MessageBoxIcon.Exclamation);
}
private void pb_game_icon_Click(object sender, EventArgs e)
{
btn_choose_game_icon.PerformClick();
}
private void pb_exe_icon_Click(object sender, EventArgs e)
{
btn_choose_exe_icon.PerformClick();
}
}
// Class used to populate combo boxes

View File

@ -51,6 +51,7 @@
this.btn_help = new System.Windows.Forms.Button();
this.btn_donate = new System.Windows.Forms.Button();
this.btn_copy = new System.Windows.Forms.Button();
this.btn_cancel = new System.Windows.Forms.Button();
this.cms_shortcuts.SuspendLayout();
this.SuspendLayout();
//
@ -323,6 +324,25 @@
this.btn_copy.UseVisualStyleBackColor = false;
this.btn_copy.Click += new System.EventHandler(this.btn_copy_Click);
//
// btn_cancel
//
this.btn_cancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btn_cancel.BackColor = System.Drawing.Color.Black;
this.btn_cancel.Enabled = false;
this.btn_cancel.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_cancel.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_cancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_cancel.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_cancel.ForeColor = System.Drawing.Color.White;
this.btn_cancel.Location = new System.Drawing.Point(503, 488);
this.btn_cancel.Name = "btn_cancel";
this.btn_cancel.Size = new System.Drawing.Size(120, 40);
this.btn_cancel.TabIndex = 37;
this.btn_cancel.Text = "&Cancel";
this.btn_cancel.UseVisualStyleBackColor = false;
this.btn_cancel.Visible = false;
this.btn_cancel.Click += new System.EventHandler(this.btn_cancel_Click);
//
// ShortcutLibraryForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -330,6 +350,7 @@
this.BackColor = System.Drawing.Color.Black;
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.ClientSize = new System.Drawing.Size(1134, 716);
this.Controls.Add(this.btn_cancel);
this.Controls.Add(this.btn_copy);
this.Controls.Add(this.btn_donate);
this.Controls.Add(this.btn_help);
@ -383,5 +404,6 @@
private System.Windows.Forms.Button btn_donate;
private System.Windows.Forms.Button btn_copy;
private System.Windows.Forms.ToolStripMenuItem tsmi_copy;
private System.Windows.Forms.Button btn_cancel;
}
}

View File

@ -453,6 +453,11 @@ namespace DisplayMagician.UIForms
lbl_mask.BringToFront();
lbl_mask.Visible = true;
// Show the cancel button
btn_cancel.Visible = true;
btn_cancel.Enabled = true;
btn_cancel.BringToFront();
ilv_saved_shortcuts.SuspendLayout();
ilv_saved_shortcuts.Refresh();
@ -478,6 +483,11 @@ namespace DisplayMagician.UIForms
lbl_mask.Visible = false;
lbl_mask.SendToBack();
// Hide the cancel button
btn_cancel.Visible = false;
btn_cancel.Enabled = false;
// Also refresh the right-click menu (if we have a main form loaded)
if (Program.AppMainForm is Form)
{
@ -588,5 +598,10 @@ namespace DisplayMagician.UIForms
}
}
private void btn_cancel_Click(object sender, EventArgs e)
{
// Inform the ShortcutRepository that it needs to cancel the running shortcut.
ShortcutRepository.CancelWait = true;
}
}
}

View File

@ -23,7 +23,7 @@
<WarningLevel>4</WarningLevel>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<UseVSHostingProcess>true</UseVSHostingProcess>
<PlatformTarget>x64</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -116,7 +116,7 @@
<Version>0.73.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers">
<Version>5.0.3</Version>
<Version>6.0.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
@ -130,7 +130,7 @@
<Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="NLog">
<Version>4.7.12</Version>
<Version>4.7.13</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

View File

@ -23,6 +23,7 @@ namespace DisplayMagicianShared
public int ScreenWidth;
public int ScreenHeight;
public string Name;
public string AdapterName;
public string Library;
public bool IsPrimary;
public bool IsClone;
@ -391,7 +392,7 @@ namespace DisplayMagicianShared
{
if (!NVIDIALibrary.GetLibrary().IsValidConfig(_nvidiaDisplayConfig))
{
SharedLogger.logger.Error($"ProfileRepository/IsValid: The profile {Name} has an invalid NVIDIA display config");
SharedLogger.logger.Error($"ProfileItem/IsValid: The profile {Name} has an invalid NVIDIA display config");
return false;
}
}
@ -399,7 +400,7 @@ namespace DisplayMagicianShared
{
if (!AMDLibrary.GetLibrary().IsValidConfig(_amdDisplayConfig))
{
SharedLogger.logger.Error($"ProfileRepository/IsValid: The profile {Name} has an invalid AMD display config");
SharedLogger.logger.Error($"ProfileItem/IsValid: The profile {Name} has an invalid AMD display config");
return false;
}
}
@ -407,13 +408,13 @@ namespace DisplayMagicianShared
{
if (!WinLibrary.GetLibrary().IsValidConfig(_windowsDisplayConfig))
{
SharedLogger.logger.Error($"ProfileRepository/IsValid: The profile {Name} has an invalid Windows CCD display config");
SharedLogger.logger.Error($"ProfileItem/IsValid: The profile {Name} has an invalid Windows CCD display config");
return false;
}
}
else
{
SharedLogger.logger.Error($"ProfileRepository/IsValid: The profile {Name} has an unknown video mode!");
SharedLogger.logger.Error($"ProfileItem/IsValid: The profile {Name} has an unknown video mode!");
}
// The rest of the
@ -507,7 +508,7 @@ namespace DisplayMagicianShared
}
catch (Exception ex)
{
SharedLogger.logger.Error(ex, $"ProfileRepository/CreateProfileFromCurrentDisplaySettings: Exception getting the config settings!");
SharedLogger.logger.Error(ex, $"ProfileItem/CreateProfileFromCurrentDisplaySettings: Exception getting the config settings!");
return false;
}
}
@ -566,7 +567,7 @@ namespace DisplayMagicianShared
}
catch (Exception ex)
{
SharedLogger.logger.Warn(ex, $"ShortcutItem/CreateShortcut: Execption while creating desktop shortcut!");
SharedLogger.logger.Warn(ex, $"ProfileItem/CreateShortcut: Execption while creating desktop shortcut!");
// Clean up a failed attempt
if (System.IO.File.Exists(shortcutFileName))
@ -586,7 +587,7 @@ namespace DisplayMagicianShared
// Check whether this profile is the same as the video mode, otherwise it's not possible
if (ProfileRepository.CurrentVideoMode != VideoMode)
{
SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The NVIDIA profile {Name} is NOT possible!");
SharedLogger.logger.Debug($"ProfileItem/IsPossibleRefresh: The NVIDIA profile {Name} is NOT possible!");
_isPossible = false;
return;
}
@ -597,13 +598,13 @@ namespace DisplayMagicianShared
if (NVIDIALibrary.GetLibrary().IsPossibleConfig(_nvidiaDisplayConfig))
{
SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The NVIDIA profile {Name} is possible!");
SharedLogger.logger.Debug($"ProfileItem/IsPossibleRefresh: The NVIDIA profile {Name} is possible!");
_isPossible = true;
}
else
{
SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The NVIDIA profile {Name} is NOT possible!");
SharedLogger.logger.Debug($"ProfileItem/IsPossibleRefresh: The NVIDIA profile {Name} is NOT possible!");
_isPossible = false;
}
}
@ -612,13 +613,13 @@ namespace DisplayMagicianShared
if (AMDLibrary.GetLibrary().IsPossibleConfig(_amdDisplayConfig))
{
SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The AMD profile {Name} is possible!");
SharedLogger.logger.Debug($"ProfileItem/IsPossibleRefresh: The AMD profile {Name} is possible!");
_isPossible = true;
}
else
{
SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The AMD profile {Name} is NOT possible!");
SharedLogger.logger.Debug($"ProfileItem/IsPossibleRefresh: The AMD profile {Name} is NOT possible!");
_isPossible = false;
}
}
@ -627,19 +628,19 @@ namespace DisplayMagicianShared
if (WinLibrary.GetLibrary().IsPossibleConfig(_windowsDisplayConfig))
{
SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The Windows CCD profile {Name} is possible!");
SharedLogger.logger.Debug($"ProfileItem/IsPossibleRefresh: The Windows CCD profile {Name} is possible!");
_isPossible = true;
}
else
{
SharedLogger.logger.Debug($"ProfileRepository/IsPossibleRefresh: The Windows CCD profile {Name} is NOT possible!");
SharedLogger.logger.Debug($"ProfileItem/IsPossibleRefresh: The Windows CCD profile {Name} is NOT possible!");
_isPossible = false;
}
}
else
{
SharedLogger.logger.Warn($"ProfileRepository/IsPossibleRefresh: We have a current video mode we don't understand, or it's not installed! The current video mode is {ProfileRepository.CurrentVideoMode}. The profile {Name} has a {VideoMode.ToString("G")} video mode and NVIDIALibrary IsInstalled is {NVIDIALibrary.GetLibrary().IsInstalled}, AMDLibrary IsInstalled is {AMDLibrary.GetLibrary().IsInstalled} and WinLibrary IsInstalled is {WinLibrary.GetLibrary().IsInstalled} ");
SharedLogger.logger.Warn($"ProfileItem/IsPossibleRefresh: We have a current video mode we don't understand, or it's not installed! The current video mode is {ProfileRepository.CurrentVideoMode}. The profile {Name} has a {VideoMode.ToString("G")} video mode and NVIDIALibrary IsInstalled is {NVIDIALibrary.GetLibrary().IsInstalled}, AMDLibrary IsInstalled is {AMDLibrary.GetLibrary().IsInstalled} and WinLibrary IsInstalled is {WinLibrary.GetLibrary().IsInstalled} ");
_isPossible = false;
}
}
@ -657,15 +658,20 @@ namespace DisplayMagicianShared
{
if (nvidiaLibrary.IsPossibleConfig(_nvidiaDisplayConfig))
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The NVIDIA display settings within profile {Name} are possible to use right now, so we'll use attempt to use them.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The NVIDIA display settings within profile {Name} are possible to use right now, so we'll use attempt to use them.");
bool itWorkedforNVIDIA = nvidiaLibrary.SetActiveConfig(_nvidiaDisplayConfig);
if (itWorkedforNVIDIA)
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The NVIDIA display settings within profile {Name} were successfully applied.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The NVIDIA display settings within profile {Name} were successfully applied.");
/*SharedLogger.logger.Trace($"ProfileItem/SetActive: Waiting 0.5 seconds to let the NVIDIA display change take place before setting the Windows CCD display settings");
System.Threading.Thread.Sleep(500);*/
// Lets update the screens so Windows knows whats happening
// NVIDIA makes such large changes to the available screens in windows, we need to do this.
winLibrary.UpdateActiveConfig();
SharedLogger.logger.Trace($"ProfileRepository/SetActive: Waiting 0.5 seconds to let the NVIDIA display change take place before setting the Windows CCD display settings");
System.Threading.Thread.Sleep(500);
// Then let's try to also apply the windows changes
// Note: we are unable to check if the Windows CCD display config is possible, as it won't match if either the current display config is a Mosaic config,
@ -677,34 +683,34 @@ namespace DisplayMagicianShared
if (itWorkedforNVIDIAColor)
{
SharedLogger.logger.Trace($"NVIDIAInfo/loadFromFile: The NVIDIA display settings that override windows within the profile {Name} were successfully applied.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The NVIDIA display settings that override windows within the profile {Name} were successfully applied.");
return true;
}
else
{
SharedLogger.logger.Trace($"NVIDIAInfo/loadFromFile: The NVIDIA display settings that override windows within the profile {Name} were NOT applied correctly.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The NVIDIA display settings that override windows within the profile {Name} were NOT applied correctly.");
}
}
else
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The Windows CCD display settings within profile {Name} were NOT applied correctly.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The Windows CCD display settings within profile {Name} were NOT applied correctly.");
}
}
else
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The NVIDIA display settings within profile {Name} were NOT applied correctly.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The NVIDIA display settings within profile {Name} were NOT applied correctly.");
}
}
else
{
SharedLogger.logger.Error($"ProfileRepository/SetActive: ERROR - Cannot apply the NVIDIA display config in profile {Name} as it is not currently possible to use it.");
SharedLogger.logger.Error($"ProfileItem/SetActive: ERROR - Cannot apply the NVIDIA display config in profile {Name} as it is not currently possible to use it.");
}
}
else
{
SharedLogger.logger.Info($"ProfileRepository/SetActive: The display settings in profile {Name} are already installed. No need to install them again. Exiting.");
SharedLogger.logger.Info($"ProfileItem/SetActive: The display settings in profile {Name} are already installed. No need to install them again. Exiting.");
}
}
}
@ -718,19 +724,23 @@ namespace DisplayMagicianShared
{
if (amdLibrary.IsPossibleConfig(_amdDisplayConfig))
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The AMD display settings within profile {Name} are possible to use right now, so we'll use attempt to use them.");
bool itWorkedforNVIDIA = amdLibrary.SetActiveConfig(_amdDisplayConfig);
SharedLogger.logger.Trace($"ProfileItem/SetActive: The AMD display settings within profile {Name} are possible to use right now, so we'll use attempt to use them.");
bool itWorkedforAMD = amdLibrary.SetActiveConfig(_amdDisplayConfig);
if (itWorkedforNVIDIA)
if (itWorkedforAMD)
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The AMD display settings within profile {Name} were successfully applied.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The AMD display settings within profile {Name} were successfully applied.");
SharedLogger.logger.Trace($"ProfileRepository/SetActive: Waiting 0.5 seconds to let the AMD display change take place before setting the Windows CCD display settings");
/*SharedLogger.logger.Trace($"ProfileItem/SetActive: Waiting 0.5 seconds to let the AMD display change take place before setting the Windows CCD display settings");
System.Threading.Thread.Sleep(500);
*/
// Lets update the screens so Windows knows whats happening
// AMD makes such large changes to the available screens in windows, we need to do this.
winLibrary.UpdateActiveConfig();
// Then let's try to also apply the windows changes
// Note: we are unable to check if the Windows CCD display config is possible, as it won't match if either the current display config is a Mosaic config,
// or if the display config we want to change to is a Mosaic config. So we just have to assume that it will work!
// Note: we are unable to check if the Windows CCD display config is possible, as it won't match if either the current display config is an Eyefinity config,
// or if the display config we want to change to is an Eyefinity config. So we just have to assume that it will work!
bool itWorkedforWindows = winLibrary.SetActiveConfig(_windowsDisplayConfig);
if (itWorkedforWindows)
{
@ -738,34 +748,34 @@ namespace DisplayMagicianShared
if (itWorkedforAMDColor)
{
SharedLogger.logger.Trace($"AMDInfo/loadFromFile: The AMD display settings that override windows within the profile {Name} were successfully applied.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The AMD display settings that override windows within the profile {Name} were successfully applied.");
return true;
}
else
{
SharedLogger.logger.Trace($"AMDInfo/loadFromFile: The AMD display settings that override windows within the profile {Name} were NOT applied correctly.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The AMD display settings that override windows within the profile {Name} were NOT applied correctly.");
}
}
else
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The Windows CCD display settings within profile {Name} were NOT applied correctly.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The Windows CCD display settings within profile {Name} were NOT applied correctly.");
}
}
else
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The AMD display settings within profile {Name} were NOT applied correctly.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The AMD display settings within profile {Name} were NOT applied correctly.");
}
}
else
{
SharedLogger.logger.Error($"ProfileRepository/SetActive: ERROR - Cannot apply the AMD display config in profile {Name} as it is not currently possible to use it.");
SharedLogger.logger.Error($"ProfileItem/SetActive: ERROR - Cannot apply the AMD display config in profile {Name} as it is not currently possible to use it.");
}
}
else
{
SharedLogger.logger.Info($"ProfileRepository/SetActive: The display settings in profile {Name} are already installed. No need to install them again. Exiting.");
SharedLogger.logger.Info($"ProfileItem/SetActive: The display settings in profile {Name} are already installed. No need to install them again. Exiting.");
}
}
}
@ -778,17 +788,17 @@ namespace DisplayMagicianShared
{
if (winLibrary.SetActiveConfig(_windowsDisplayConfig))
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The Windows CCD display settings within profile {Name} were successfully applied.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The Windows CCD display settings within profile {Name} were successfully applied.");
return true;
}
else
{
SharedLogger.logger.Trace($"ProfileRepository/SetActive: The Windows CCD display settings within profile {Name} were NOT applied correctly.");
SharedLogger.logger.Trace($"ProfileItem/SetActive: The Windows CCD display settings within profile {Name} were NOT applied correctly.");
}
}
else
{
SharedLogger.logger.Info($"ProfileRepository/SetActive: The display settings in profile {Name} are already installed. No need to install them again. Exiting.");
SharedLogger.logger.Info($"ProfileItem/SetActive: The display settings in profile {Name} are already installed. No need to install them again. Exiting.");
}
}
@ -832,12 +842,10 @@ namespace DisplayMagicianShared
// Return an empty screen if we have no Display Config Paths to use!
return _screens;
}
// Now we need to check for Spanned screens
// Now we need to check for Spanned screens (Surround)
if (_nvidiaDisplayConfig.MosaicConfig.IsMosaicEnabled)
{
// Create a dictionary of all the screen sizes we want
//Dictionary<string,SpannedScreenPosition> MosaicScreens = new Dictionary<string,SpannedScreenPosition>();
for (int i = 0; i < _nvidiaDisplayConfig.MosaicConfig.MosaicGridCount; i++)
{
ScreenPosition screen = new ScreenPosition();
@ -912,6 +920,7 @@ namespace DisplayMagicianShared
// Add the spanned screen to the screen
screen.SpannedScreens.Add(spannedScreen);
}
// Need to look for the Windows layout details now we know the size of this display
@ -976,150 +985,109 @@ namespace DisplayMagicianShared
}
}
else if (_nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].DisplayCount == 1)
SharedLogger.logger.Trace($"ProfileItem/GetNVIDIAScreenPositions: Added a new NVIDIA Spanned Screen {screen.Name} ({screen.ScreenWidth}x{screen.ScreenHeight}) at position {screen.ScreenX},{screen.ScreenY}.");
_screens.Add(screen);
}
}
// Now we go through all the windows displays, and we skip the Windows one that matches the NVIDIA one (as we added it earlier)
foreach (var path in _windowsDisplayConfig.DisplayConfigPaths)
{
// For each path we go through and get the relevant info we need.
if (_windowsDisplayConfig.DisplayConfigPaths.Length > 0)
{
UInt64 adapterId = path.SourceInfo.AdapterId.Value;
UInt32 sourceId = path.SourceInfo.Id;
UInt32 targetId = path.TargetInfo.Id;
// Set some basics about the screen
ScreenPosition screen = new ScreenPosition();
screen.Library = "NVIDIA";
//screen.AdapterName = adapterId.ToString();
screen.IsSpanned = false;
screen.Colour = normalScreenColor; // this is the default unless overridden by the primary screen
screen.IsClone = false;
screen.ClonedCopies = 0;
//screen.DisplayConnector = path.TargetInfo.OutputTechnology.ToString("G");
foreach (var displaySource in _windowsDisplayConfig.DisplaySources)
{
// This is a single screen with an adjoining mosaic screen
// Set some basics about the screen
try
if (displaySource.Value.Contains(sourceId))
{
string displayId = _nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].Displays[0].DisplayId.ToString();
string windowsDisplayName = _nvidiaDisplayConfig.DisplayNames[displayId];
List<uint> sourceIndexes = _windowsDisplayConfig.DisplaySources[windowsDisplayName];
for (int x = 0; x < _windowsDisplayConfig.DisplayConfigModes.Length; x++)
if (displaySource.Value.Count > 1)
{
// Skip this if its not a source info config type
if (_windowsDisplayConfig.DisplayConfigModes[x].InfoType != DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE)
{
continue;
}
// If the source index matches the index of the source info object we're looking at, then process it!
if (sourceIndexes.Contains(_windowsDisplayConfig.DisplayConfigModes[x].Id))
{
screen.Name = displayId.ToString();
screen.ScreenX = (int)_windowsDisplayConfig.DisplayConfigModes[x].SourceMode.Position.X;
screen.ScreenY = (int)_windowsDisplayConfig.DisplayConfigModes[x].SourceMode.Position.Y;
screen.ScreenWidth = (int)_windowsDisplayConfig.DisplayConfigModes[x].SourceMode.Width;
screen.ScreenHeight = (int)_windowsDisplayConfig.DisplayConfigModes[x].SourceMode.Height;
break;
}
// We have a cloned display
screen.IsClone = true;
screen.ClonedCopies = displaySource.Value.Count;
}
break;
}
}
// Go through the screens as Windows knows them, and then enhance the info with Mosaic data if it applies
foreach (DISPLAYCONFIG_MODE_INFO displayMode in _windowsDisplayConfig.DisplayConfigModes)
{
// Find the matching Display Config Source Mode
if (displayMode.InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == sourceId && displayMode.AdapterId.Value == adapterId)
{
screen.Name = targetId.ToString();
//screen.DisplayConnector = displayMode.DisplayConnector;
screen.ScreenX = displayMode.SourceMode.Position.X;
screen.ScreenY = displayMode.SourceMode.Position.Y;
screen.ScreenWidth = (int)displayMode.SourceMode.Width;
screen.ScreenHeight = (int)displayMode.SourceMode.Height;
// If we're at the 0,0 coordinate then we're the primary monitor
if (screen.ScreenX == 0 && screen.ScreenY == 0)
{
screen.IsPrimary = true;
screen.Colour = primaryScreenColor;
}
break;
}
catch (KeyNotFoundException ex)
{
// Thrown if the Windows display doesn't match the NVIDIA display.
// Typically happens during configuration of a new Mosaic mode.
// If we hit this issue, then we just want to skip over it, as we can update it later when the user pushes the button.
// This only happens due to the auto detection stuff functionality we have built in to try and update as quickly as we can.
// So its something that we can safely ignore if we hit this exception as it is part of the expect behaviour
continue;
}
catch (Exception ex)
{
// Some other exception has occurred and we need to report it.
SharedLogger.logger.Info(ex, $"ProfileRepository/GetNVIDIAScreenPositions: An exception happened when trying to create a screen from a single Mosaic desktop");
continue;
}
}
_screens.Add(screen);
}
}
else
{
foreach (var path in _windowsDisplayConfig.DisplayConfigPaths)
{
// For each path we go through and get the relevant info we need.
if (_windowsDisplayConfig.DisplayConfigPaths.Length > 0)
// Decide if this screen is one we've had earlier, and if so, skip it
if (_screens.Any( s => s.ScreenX == screen.ScreenX && s.ScreenY == screen.ScreenY && s.ScreenWidth == screen.ScreenWidth && s.ScreenHeight == screen.ScreenHeight))
{
// Set some basics about the screen
ScreenPosition screen = new ScreenPosition();
screen.Library = "NVIDIA";
screen.IsSpanned = false;
screen.Colour = normalScreenColor; // this is the default unless overridden by the primary screen
SharedLogger.logger.Trace($"ProfileItem/GetNVIDIAScreenPositions: We've already got the {screen.Name} ({screen.ScreenWidth}x{screen.ScreenHeight}) screen from the NVIDIA driver, so skipping it from the Windows driver.");
continue;
}
UInt32 sourceId = path.SourceInfo.Id;
UInt32 targetId = path.TargetInfo.Id;
screen.IsClone = false;
screen.ClonedCopies = 0;
foreach (var displaySource in _windowsDisplayConfig.DisplaySources)
foreach (ADVANCED_HDR_INFO_PER_PATH hdrInfo in _windowsDisplayConfig.DisplayHDRStates)
{
// Find the matching HDR information
if (hdrInfo.Id == targetId)
{
if (displaySource.Value.Contains(sourceId))
// HDR information
if (hdrInfo.AdvancedColorInfo.AdvancedColorSupported)
{
if (displaySource.Value.Count > 1)
screen.HDRSupported = true;
if (hdrInfo.AdvancedColorInfo.AdvancedColorEnabled)
{
// We have a cloned display
screen.IsClone = true;
screen.ClonedCopies = displaySource.Value.Count;
}
break;
}
}
// Go through the screens as Windows knows them, and then enhance the info with Mosaic data if it applies
foreach (DISPLAYCONFIG_MODE_INFO displayMode in _windowsDisplayConfig.DisplayConfigModes)
{
// Find the matching Display Config Source Mode
if (displayMode.InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == sourceId)
{
screen.Name = targetId.ToString();
//screen.DisplayConnector = displayMode.DisplayConnector;
screen.ScreenX = displayMode.SourceMode.Position.X;
screen.ScreenY = displayMode.SourceMode.Position.Y;
screen.ScreenWidth = (int)displayMode.SourceMode.Width;
screen.ScreenHeight = (int)displayMode.SourceMode.Height;
// If we're at the 0,0 coordinate then we're the primary monitor
if (screen.ScreenX == 0 && screen.ScreenY == 0)
{
screen.IsPrimary = true;
screen.Colour = primaryScreenColor;
}
break;
}
}
foreach (ADVANCED_HDR_INFO_PER_PATH hdrInfo in _windowsDisplayConfig.DisplayHDRStates)
{
// Find the matching HDR information
if (hdrInfo.Id == targetId)
{
// HDR information
if (hdrInfo.AdvancedColorInfo.AdvancedColorSupported)
{
screen.HDRSupported = true;
if (hdrInfo.AdvancedColorInfo.AdvancedColorEnabled)
{
screen.HDREnabled = true;
}
else
{
screen.HDREnabled = false;
}
screen.HDREnabled = true;
}
else
{
screen.HDRSupported = false;
screen.HDREnabled = false;
}
break;
}
}
_screens.Add(screen);
}
else
{
screen.HDRSupported = false;
screen.HDREnabled = false;
}
break;
}
}
SharedLogger.logger.Trace($"ProfileItem/GetNVIDIAScreenPositions: Added a new Screen {screen.Name} ({screen.ScreenWidth}x{screen.ScreenHeight}) at position {screen.ScreenX},{screen.ScreenY}.");
_screens.Add(screen);
}
}
@ -1183,7 +1151,8 @@ namespace DisplayMagicianShared
// Return an empty screen if we have no Display Config Paths to use!
return _screens;
}
// Now we need to check for Spanned screens
// Go through the AMD Eyefinity screens
if (_amdDisplayConfig.SlsConfig.IsSlsEnabled)
{
for (int i = 0; i < _amdDisplayConfig.DisplayMaps.Count; i++)
@ -1275,96 +1244,109 @@ namespace DisplayMagicianShared
{
screen.Colour = primaryScreenColor;
}
}
}
SharedLogger.logger.Trace($"ProfileItem/GetAMDScreenPositions: Added a new AMD Spanned Screen {screen.Name} ({screen.ScreenWidth}x{screen.ScreenHeight}) at position {screen.ScreenX},{screen.ScreenY}.");
_screens.Add(screen);
}
}
else
// Next, go through the screens as Windows knows them, and then enhance the info with Eyefinity data if it applies
foreach (var path in _windowsDisplayConfig.DisplayConfigPaths)
{
foreach (var path in _windowsDisplayConfig.DisplayConfigPaths)
// For each path we go through and get the relevant info we need.
if (_windowsDisplayConfig.DisplayConfigPaths.Length > 0)
{
// For each path we go through and get the relevant info we need.
if (_windowsDisplayConfig.DisplayConfigPaths.Length > 0)
UInt64 adapterId = path.SourceInfo.AdapterId.Value;
UInt32 sourceId = path.SourceInfo.Id;
UInt32 targetId = path.TargetInfo.Id;
// Set some basics about the screen
ScreenPosition screen = new ScreenPosition();
screen.Library = "AMD";
//screen.AdapterName = adapterId.ToString();
screen.IsSpanned = false;
screen.Colour = normalScreenColor; // this is the default unless overridden by the primary screen
screen.IsClone = false;
screen.ClonedCopies = 0;
//screen.DisplayConnector = path.TargetInfo.OutputTechnology.ToString("G");
foreach (var displaySource in _windowsDisplayConfig.DisplaySources)
{
// Set some basics about the screen
ScreenPosition screen = new ScreenPosition();
screen.Library = "AMD";
screen.IsSpanned = false;
screen.Colour = normalScreenColor; // this is the default unless overridden by the primary screen
UInt32 sourceId = path.SourceInfo.Id;
UInt32 targetId = path.TargetInfo.Id;
screen.IsClone = false;
screen.ClonedCopies = 0;
foreach (var displaySource in _windowsDisplayConfig.DisplaySources)
if (displaySource.Value.Contains(sourceId))
{
if (displaySource.Value.Contains(sourceId))
if (displaySource.Value.Count > 1)
{
if (displaySource.Value.Count > 1)
{
// We have a cloned display
screen.IsClone = true;
screen.ClonedCopies = displaySource.Value.Count;
}
break;
// We have a cloned display
screen.IsClone = true;
screen.ClonedCopies = displaySource.Value.Count;
}
break;
}
}
// Go through the screens as Windows knows them, and then enhance the info with Mosaic data if it applies
foreach (DISPLAYCONFIG_MODE_INFO displayMode in _windowsDisplayConfig.DisplayConfigModes)
// Go through the screens as Windows knows them, and then enhance the info with Mosaic data if it applies
foreach (DISPLAYCONFIG_MODE_INFO displayMode in _windowsDisplayConfig.DisplayConfigModes)
{
// Find the matching Display Config Source Mode
if (displayMode.InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == sourceId && displayMode.AdapterId.Value == adapterId)
{
// Find the matching Display Config Source Mode
if (displayMode.InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == sourceId)
{
screen.Name = targetId.ToString();
//screen.DisplayConnector = displayMode.DisplayConnector;
screen.ScreenX = displayMode.SourceMode.Position.X;
screen.ScreenY = displayMode.SourceMode.Position.Y;
screen.ScreenWidth = (int)displayMode.SourceMode.Width;
screen.ScreenHeight = (int)displayMode.SourceMode.Height;
screen.Name = targetId.ToString();
//screen.DisplayConnector = displayMode.DisplayConnector;
screen.ScreenX = displayMode.SourceMode.Position.X;
screen.ScreenY = displayMode.SourceMode.Position.Y;
screen.ScreenWidth = (int)displayMode.SourceMode.Width;
screen.ScreenHeight = (int)displayMode.SourceMode.Height;
// If we're at the 0,0 coordinate then we're the primary monitor
if (screen.ScreenX == 0 && screen.ScreenY == 0)
{
screen.IsPrimary = true;
screen.Colour = primaryScreenColor;
}
break;
// If we're at the 0,0 coordinate then we're the primary monitor
if (screen.ScreenX == 0 && screen.ScreenY == 0)
{
screen.IsPrimary = true;
screen.Colour = primaryScreenColor;
}
break;
}
}
foreach (ADVANCED_HDR_INFO_PER_PATH hdrInfo in _windowsDisplayConfig.DisplayHDRStates)
// Decide if this screen is one we've had earlier, and if so, skip it
if (_screens.Any(s => s.ScreenX == screen.ScreenX && s.ScreenY == screen.ScreenY && s.ScreenWidth == screen.ScreenWidth && s.ScreenHeight == screen.ScreenHeight))
{
SharedLogger.logger.Trace($"ProfileItem/GetAMDScreenPositions: We've already got the {screen.Name} ({screen.ScreenWidth}x{screen.ScreenHeight}) screen from the AMD driver, so skipping it from the Windows driver.");
continue;
}
foreach (ADVANCED_HDR_INFO_PER_PATH hdrInfo in _windowsDisplayConfig.DisplayHDRStates)
{
// Find the matching HDR information
if (hdrInfo.Id == targetId)
{
// Find the matching HDR information
if (hdrInfo.Id == targetId)
// HDR information
if (hdrInfo.AdvancedColorInfo.AdvancedColorSupported)
{
// HDR information
if (hdrInfo.AdvancedColorInfo.AdvancedColorSupported)
screen.HDRSupported = true;
if (hdrInfo.AdvancedColorInfo.AdvancedColorEnabled)
{
screen.HDRSupported = true;
if (hdrInfo.AdvancedColorInfo.AdvancedColorEnabled)
{
screen.HDREnabled = true;
}
else
{
screen.HDREnabled = false;
}
screen.HDREnabled = true;
}
else
{
screen.HDRSupported = false;
screen.HDREnabled = false;
}
break;
}
}
_screens.Add(screen);
}
else
{
screen.HDRSupported = false;
screen.HDREnabled = false;
}
break;
}
}
SharedLogger.logger.Trace($"ProfileItem/GetAMDScreenPositions: Added a new Screen {screen.Name} ({screen.ScreenWidth}x{screen.ScreenHeight}) at position {screen.ScreenX},{screen.ScreenY}.");
_screens.Add(screen);
}
}
@ -1393,17 +1375,19 @@ namespace DisplayMagicianShared
// For each path we go through and get the relevant info we need.
if (_windowsDisplayConfig.DisplayConfigPaths.Length > 0)
{
// Set some basics about the screen
ScreenPosition screen = new ScreenPosition();
screen.Library = "WINDOWS";
screen.IsSpanned = false;
screen.Colour = normalScreenColor; // this is the default unless overridden by the primary screen
UInt64 adapterId = path.SourceInfo.AdapterId.Value;
UInt32 sourceId = path.SourceInfo.Id;
UInt32 targetId = path.TargetInfo.Id;
// Set some basics about the screen
ScreenPosition screen = new ScreenPosition();
screen.Library = "WINDOWS";
//screen.AdapterName = adapterId.ToString();
screen.IsSpanned = false;
screen.Colour = normalScreenColor; // this is the default unless overridden by the primary screen
screen.IsClone = false;
screen.ClonedCopies = 0;
//screen.DisplayConnector = path.TargetInfo.OutputTechnology.ToString("G");
foreach (var displaySource in _windowsDisplayConfig.DisplaySources)
{
if (displaySource.Value.Contains(sourceId))
@ -1422,7 +1406,7 @@ namespace DisplayMagicianShared
foreach (DISPLAYCONFIG_MODE_INFO displayMode in _windowsDisplayConfig.DisplayConfigModes)
{
// Find the matching Display Config Source Mode
if (displayMode.InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == sourceId)
if (displayMode.InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == sourceId && displayMode.AdapterId.Value == adapterId)
{
screen.Name = targetId.ToString();
//screen.DisplayConnector = displayMode.DisplayConnector;
@ -1469,6 +1453,8 @@ namespace DisplayMagicianShared
}
}
SharedLogger.logger.Trace($"ProfileItem/GetWindowsScreenPositions: Added a new Screen {screen.Name} ({screen.ScreenWidth}x{screen.ScreenHeight}) at position {screen.ScreenX},{screen.ScreenY}.");
_screens.Add(screen);
}
}

View File

@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.1.1.0")]
[assembly: AssemblyFileVersion("2.1.1.0")]
[assembly: AssemblyVersion("2.1.2.0")]
[assembly: AssemblyFileVersion("2.1.2.0")]

View File

@ -1,10 +1,10 @@
using System.Runtime.InteropServices;
//using System.Runtime.InteropServices;
namespace DisplayMagicianShared
/*namespace DisplayMagicianShared
{
public class ShellUtils
{
public static string AUMID = "LittleBitBig.DisplayMagician";
public const string AUMID = "LittleBitBig.DisplayMagician";
// Add the ability to set an Application AUMID so that Windows 10+ recognises the
// application and things like Toasts, Tasbar pinning and similar functionality
@ -20,4 +20,4 @@ namespace DisplayMagicianShared
}
}
}
}*/

View File

@ -203,15 +203,21 @@ namespace DisplayMagicianShared.UserControls
Rectangle wordRect = new Rectangle(screen.ScreenX + screenBezel + screenWordBuffer, screen.ScreenY + screenBezel + screenWordBuffer, screen.ScreenWidth - (screenBezel * 2) - (screenWordBuffer * 2), screen.ScreenHeight - (screenBezel * 2) - (screenWordBuffer * 2));
Color wordTextColour = pickTextColorBasedOnBgColour(screen.Colour, lightTextColour, darkTextColour);
// Draw the name of the screen and the size of it
string str = $"{screen.Name}{Environment.NewLine}{screen.ScreenWidth}×{screen.ScreenHeight}{Environment.NewLine}{screen.DisplayConnector}";
string str = $"{screen.Name}{Environment.NewLine}";
str += $"{screen.ScreenWidth}×{ screen.ScreenHeight}{ Environment.NewLine}{ screen.DisplayConnector}";
if (screen.IsPrimary)
{
str = $"Primary Display{Environment.NewLine}" + str;
}
if (screen.IsClone)
{
str = str + $"(+{screen.ClonedCopies-1} Clone)";
str += $"(+{screen.ClonedCopies-1} Clone)";
}
if (!String.IsNullOrEmpty(screen.AdapterName))
{
str += $"Adapter {screen.AdapterName}{Environment.NewLine}";
}
DrawString(g, str, wordTextColour, selectedWordFont, wordRect.Size, wordRect.Location);

View File

@ -137,11 +137,20 @@ namespace DisplayMagicianShared.Windows
public enum QDC : uint
{
Zero = 0x0,
QDC_ALL_PATHS = 0x00000001, // Get all paths
QDC_ONLY_ACTIVE_PATHS = 0x00000002, // Get only the active paths currently in use
QDC_DATABASE_CURRENT = 0x00000004, // Get the currently active paths as stored in the display database
QDC_VIRTUAL_MODE_AWARE = 0x00000010, // Get the virtual mode aware paths
// Get all paths
QDC_ALL_PATHS = 0x00000001,
// Get only the active paths currently in use
QDC_ONLY_ACTIVE_PATHS = 0x00000002,
// Get the currently active paths as stored in the display database
QDC_DATABASE_CURRENT = 0x00000004,
// This flag should be bitwise OR'ed with other flags to indicate that the caller is aware of virtual mode support. Supported starting in Windows 10.
QDC_VIRTUAL_MODE_AWARE = 0x00000010,
// This flag should be bitwise OR'ed with QDC_ONLY_ACTIVE_PATHS to indicate that the caller would like to include head-mounted displays (HMDs) in the list of active paths. See Remarks for more information.
// Supported starting in Windows 10 1703 Creators Update.
QDC_INCLUDE_HMD = 0x00000020,
// This flag should be bitwise OR'ed with other flags to indicate that the caller is aware of virtual refresh rate support.
// Supported starting in Windows 11.
QDC_VIRTUAL_REFRESH_RATE_AWARE = 0x00000040,
}
[Flags]

View File

@ -37,7 +37,7 @@ namespace DisplayMagicianShared.Windows
public Dictionary<ulong, string> DisplayAdapters;
public DISPLAYCONFIG_PATH_INFO[] DisplayConfigPaths;
public DISPLAYCONFIG_MODE_INFO[] DisplayConfigModes;
public ADVANCED_HDR_INFO_PER_PATH[] DisplayHDRStates;
public List<ADVANCED_HDR_INFO_PER_PATH> DisplayHDRStates;
public Dictionary<string, GDI_DISPLAY_SETTING> GdiDisplaySettings;
public bool IsCloned;
// Note: We purposely have left out the DisplaySources from the Equals as it's order keeps changing after each reboot and after each profile swap
@ -159,7 +159,7 @@ namespace DisplayMagicianShared.Windows
myDefaultConfig.DisplayAdapters = new Dictionary<ulong, string>();
myDefaultConfig.DisplayConfigModes = new DISPLAYCONFIG_MODE_INFO[0];
myDefaultConfig.DisplayConfigPaths = new DISPLAYCONFIG_PATH_INFO[0];
myDefaultConfig.DisplayHDRStates = new ADVANCED_HDR_INFO_PER_PATH[0];
myDefaultConfig.DisplayHDRStates = new List<ADVANCED_HDR_INFO_PER_PATH>();
myDefaultConfig.DisplayIdentifiers = new List<string>();
myDefaultConfig.DisplaySources = new Dictionary<string, List<uint>>();
myDefaultConfig.IsCloned = false;
@ -168,24 +168,33 @@ namespace DisplayMagicianShared.Windows
return myDefaultConfig;
}
private void PatchAdapterIDs(ref WINDOWS_DISPLAY_CONFIG savedDisplayConfig, Dictionary<ulong, string> currentAdapterMap)
private void PatchAdapterIDs(ref WINDOWS_DISPLAY_CONFIG savedDisplayConfig)
{
Dictionary<ulong, ulong> adapterOldToNewMap = new Dictionary<ulong, ulong>();
Dictionary<ulong, string> currentAdapterMap = GetCurrentAdapterIDs();
SharedLogger.logger.Trace("WinLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to figure out the old adapterIDs");
foreach (KeyValuePair<ulong, string> savedAdapter in savedDisplayConfig.DisplayAdapters)
{
bool adapterMatched = false;
foreach (KeyValuePair<ulong, string> currentAdapter in currentAdapterMap)
{
SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: Checking if saved adapter {savedAdapter.Key} (AdapterName is {savedAdapter.Value}) is equal to current adapter id {currentAdapter.Key} (AdapterName is {currentAdapter.Value})");
if (currentAdapter.Value.Equals(savedAdapter.Value))
{
// we have found the new LUID Value for the same adapter
// So we want to store it
SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: We found that saved adapter {savedAdapter.Key} has now been assigned adapter id {currentAdapter.Key} (AdapterName is {savedAdapter.Value})");
adapterOldToNewMap.Add(savedAdapter.Key, currentAdapter.Key);
adapterMatched = true;
}
}
if (!adapterMatched)
{
SharedLogger.logger.Error($"WinLibrary/PatchAdapterIDs: Saved adapter {savedAdapter.Key} (AdapterName is {savedAdapter.Value}) doesn't have a current match! The adapters have changed since the configuration was last saved.");
}
}
ulong newAdapterValue = 0;
@ -236,18 +245,19 @@ namespace DisplayMagicianShared.Windows
SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: Going through the display config HDR info to update the adapter id");
// Update the HDRInfo with the current adapter id
for (int i = 0; i < savedDisplayConfig.DisplayHDRStates.Length; i++)
for (int i = 0; i < savedDisplayConfig.DisplayHDRStates.Count; i++)
{
ADVANCED_HDR_INFO_PER_PATH hdrInfo = savedDisplayConfig.DisplayHDRStates[i];
// Change the Mode AdapterID
if (adapterOldToNewMap.ContainsKey(savedDisplayConfig.DisplayHDRStates[i].AdapterId.Value))
{
// We get here if there is a matching adapter
newAdapterValue = adapterOldToNewMap[savedDisplayConfig.DisplayHDRStates[i].AdapterId.Value];
savedDisplayConfig.DisplayHDRStates[i].AdapterId = AdapterValueToLUID(newAdapterValue);
hdrInfo.AdapterId = AdapterValueToLUID(newAdapterValue);
newAdapterValue = adapterOldToNewMap[savedDisplayConfig.DisplayHDRStates[i].AdvancedColorInfo.Header.AdapterId.Value];
savedDisplayConfig.DisplayHDRStates[i].AdvancedColorInfo.Header.AdapterId = AdapterValueToLUID(newAdapterValue);
hdrInfo.AdvancedColorInfo.Header.AdapterId = AdapterValueToLUID(newAdapterValue);
newAdapterValue = adapterOldToNewMap[savedDisplayConfig.DisplayHDRStates[i].SDRWhiteLevel.Header.AdapterId.Value];
savedDisplayConfig.DisplayHDRStates[i].SDRWhiteLevel.Header.AdapterId = AdapterValueToLUID(newAdapterValue);
hdrInfo.SDRWhiteLevel.Header.AdapterId = AdapterValueToLUID(newAdapterValue);
}
else
{
@ -255,9 +265,9 @@ namespace DisplayMagicianShared.Windows
// (it is highly likely to... its only if the user has multiple graphics cards with some weird config it may break)
newAdapterValue = currentAdapterMap.First().Key;
SharedLogger.logger.Warn($"WinLibrary/PatchAdapterIDs: Uh Oh. Adapter {savedDisplayConfig.DisplayHDRStates[i].AdapterId.Value} didn't have a current match! It's possible the adapter was swapped or disabled. Attempting to use adapter {newAdapterValue} instead.");
savedDisplayConfig.DisplayHDRStates[i].AdapterId = AdapterValueToLUID(newAdapterValue);
savedDisplayConfig.DisplayHDRStates[i].AdvancedColorInfo.Header.AdapterId = AdapterValueToLUID(newAdapterValue);
savedDisplayConfig.DisplayHDRStates[i].SDRWhiteLevel.Header.AdapterId = AdapterValueToLUID(newAdapterValue);
hdrInfo.AdapterId = AdapterValueToLUID(newAdapterValue);
hdrInfo.AdvancedColorInfo.Header.AdapterId = AdapterValueToLUID(newAdapterValue);
hdrInfo.SDRWhiteLevel.Header.AdapterId = AdapterValueToLUID(newAdapterValue);
}
}
@ -282,16 +292,18 @@ namespace DisplayMagicianShared.Windows
public WINDOWS_DISPLAY_CONFIG GetActiveConfig()
{
SharedLogger.logger.Trace($"WinLibrary/GetActiveConfig: Getting the currently active config");
return GetWindowsDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS);
// We want to include head mounted devices, inform windows we're virtual mode aware
// We'll leave virtual refresh rate aware until we can reliably detect Windows 11 versions.
return GetWindowsDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD);
}
private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS)
private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD)
{
// Get the size of the largest Active Paths and Modes arrays
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the size of the largest Active Paths and Modes arrays");
int pathCount = 0;
int modeCount = 0;
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(selector, out pathCount, out modeCount);
if (err != WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
@ -301,14 +313,14 @@ namespace DisplayMagicianShared.Windows
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the current Display Config path and mode arrays");
var paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
var modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
err = CCDImport.QueryDisplayConfig(selector, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
{
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again.");
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the size of the largest Active Paths and Modes arrays");
// Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again
// as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig
err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
err = CCDImport.GetDisplayConfigBufferSizes(selector, out pathCount, out modeCount);
if (err != WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again");
@ -317,7 +329,7 @@ namespace DisplayMagicianShared.Windows
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the current Display Config path and mode arrays");
paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
err = CCDImport.QueryDisplayConfig(selector, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
{
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
@ -338,7 +350,7 @@ namespace DisplayMagicianShared.Windows
// Prepare the empty windows display config
WINDOWS_DISPLAY_CONFIG windowsDisplayConfig = new WINDOWS_DISPLAY_CONFIG();
windowsDisplayConfig.DisplayAdapters = new Dictionary<ulong, string>();
windowsDisplayConfig.DisplayHDRStates = new ADVANCED_HDR_INFO_PER_PATH[pathCount];
windowsDisplayConfig.DisplayHDRStates = new List<ADVANCED_HDR_INFO_PER_PATH>();
windowsDisplayConfig.DisplaySources = new Dictionary<string, List<uint>>();
windowsDisplayConfig.IsCloned = false;
@ -348,28 +360,39 @@ namespace DisplayMagicianShared.Windows
// Next, extract the UID entries for the displays as that's what the Path IDs are normally supposed to be
// This is how we know the actual target id's ofd the monitors currently connected
Regex rx = new Regex(@"UID(?<uid>\d+)#", RegexOptions.Compiled | RegexOptions.IgnoreCase);
HashSet<uint> physicalTargetIdsToFind = new HashSet<uint>();
HashSet<uint> physicalTargetIdsAvailable = new HashSet<uint>();
foreach (string displayIdentifier in windowsDisplayConfig.DisplayIdentifiers)
{
MatchCollection mc = rx.Matches(displayIdentifier);
if (mc.Count > 0)
{
physicalTargetIdsToFind.Add(UInt32.Parse(mc[0].Groups["uid"].Value));
physicalTargetIdsAvailable.Add(UInt32.Parse(mc[0].Groups["uid"].Value));
}
}
// Now cycle through the paths and grab the HDR state information
// and map the adapter name to adapter id
HashSet<uint> targetIdsToChange = new HashSet<uint>();
var hdrInfos = new ADVANCED_HDR_INFO_PER_PATH[pathCount];
int hdrInfoCount = 0;
List<uint> targetPathIdsToChange = new List<uint>();
List<uint> targetModeIdsToChange = new List<uint>();
List<uint> targetIdsFound = new List<uint>();
List<uint> replacementIds = new List<uint>();
bool isClonedProfile = false;
for (int i = 0; i < paths.Length; i++)
{
bool gotSourceDeviceName = false;
bool gotAdapterName = false;
bool gotAdvancedColorInfo = false;
bool gotSdrWhiteLevel = false;
// Figure out if this path has a physical targetId, and if it doesn't store it
if (!physicalTargetIdsToFind.Contains(paths[i].TargetInfo.Id))
if (physicalTargetIdsAvailable.Contains(paths[i].TargetInfo.Id))
{
targetIdsFound.Add(paths[i].TargetInfo.Id);
}
else
{
// Add to the list of physical path target ids we need to patch later
targetIdsToChange.Add(paths[i].TargetInfo.Id);
targetPathIdsToChange.Add(paths[i].TargetInfo.Id);
}
// Track if this display is a cloned path
@ -383,12 +406,14 @@ namespace DisplayMagicianShared.Windows
err = CCDImport.DisplayConfigGetDeviceInfo(ref sourceInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
{
gotSourceDeviceName = true;
// Store it for later
if (windowsDisplayConfig.DisplaySources.ContainsKey(sourceInfo.ViewGdiDeviceName))
{
// We already have at least one display using this source, so we need to add the other cloned display to the existing list
windowsDisplayConfig.DisplaySources[sourceInfo.ViewGdiDeviceName].Add(paths[i].SourceInfo.Id);
isClonedPath = true;
isClonedProfile = true;
windowsDisplayConfig.IsCloned = true;
}
else
@ -429,6 +454,7 @@ namespace DisplayMagicianShared.Windows
err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
{
gotAdapterName = true;
// Store it for later
windowsDisplayConfig.DisplayAdapters.Add(paths[i].TargetInfo.AdapterId.Value, adapterInfo.AdapterDevicePath);
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found adapter name {adapterInfo.AdapterDevicePath} for adapter {paths[i].TargetInfo.AdapterId.Value}.");
@ -438,6 +464,12 @@ namespace DisplayMagicianShared.Windows
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to query the adapter name for adapter {paths[i].TargetInfo.AdapterId.Value}.");
}
}
else
{
// We already have the adapter name
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: We already have the adapter name {windowsDisplayConfig.DisplayAdapters[paths[i].TargetInfo.AdapterId.Value]} for adapter {paths[i].TargetInfo.AdapterId.Value} so skipping storing it.");
gotAdapterName = true;
}
// Get advanced color info
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get advanced color info for display {paths[i].TargetInfo.Id}.");
@ -449,6 +481,7 @@ namespace DisplayMagicianShared.Windows
err = CCDImport.DisplayConfigGetDeviceInfo(ref colorInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
{
gotAdvancedColorInfo = true;
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found color info for display {paths[i].TargetInfo.Id}.");
if (colorInfo.AdvancedColorSupported)
{
@ -473,7 +506,7 @@ namespace DisplayMagicianShared.Windows
}
// get SDR white levels
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get SDR white levels for adapter {paths[i].TargetInfo.AdapterId.Value}.");
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get SDR white levels for display {paths[i].TargetInfo.Id}.");
var whiteLevelInfo = new DISPLAYCONFIG_SDR_WHITE_LEVEL();
whiteLevelInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL;
whiteLevelInfo.Header.Size = (uint)Marshal.SizeOf<DISPLAYCONFIG_SDR_WHITE_LEVEL>();
@ -482,6 +515,7 @@ namespace DisplayMagicianShared.Windows
err = CCDImport.DisplayConfigGetDeviceInfo(ref whiteLevelInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
{
gotSdrWhiteLevel = true;
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found SDR White levels for display {paths[i].TargetInfo.Id}.");
}
else
@ -489,47 +523,112 @@ namespace DisplayMagicianShared.Windows
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - Unabled to get SDR White levels for display {paths[i].TargetInfo.Id}.");
}
hdrInfos[hdrInfoCount] = new ADVANCED_HDR_INFO_PER_PATH();
hdrInfos[hdrInfoCount].AdapterId = paths[i].TargetInfo.AdapterId;
hdrInfos[hdrInfoCount].Id = paths[i].TargetInfo.Id;
hdrInfos[hdrInfoCount].AdvancedColorInfo = colorInfo;
hdrInfos[hdrInfoCount].SDRWhiteLevel = whiteLevelInfo;
hdrInfoCount++;
}
// Now we need to figure out the maps between the cloned ID and the real physical target id
// the Advanced color info structure actually holds this information! So lets mine it.
Dictionary<uint, uint> targetIdMap = new Dictionary<uint, uint>();
foreach (var hdrInfo in hdrInfos)
{
targetIdMap[hdrInfo.Id] = hdrInfo.AdvancedColorInfo.Header.Id;
}
// Now we need to go through the list of paths again and patch the 'cloned' displays with a real display ID so the config works
for (int i = 0; i < paths.Length; i++)
{
if (targetIdsToChange.Contains(paths[i].TargetInfo.Id))
// Only create and add the ADVANCED_HDR_INFO_PER_PATH if the info is there
if (gotAdvancedColorInfo)
{
// Patch the cloned ids with a real working one!
paths[i].TargetInfo.Id = targetIdMap[paths[i].TargetInfo.Id];
ADVANCED_HDR_INFO_PER_PATH hdrInfo = new ADVANCED_HDR_INFO_PER_PATH();
hdrInfo.AdapterId = paths[i].TargetInfo.AdapterId;
hdrInfo.Id = paths[i].TargetInfo.Id;
hdrInfo.AdvancedColorInfo = colorInfo;
if (gotSdrWhiteLevel)
{
hdrInfo.SDRWhiteLevel = whiteLevelInfo;
}
windowsDisplayConfig.DisplayHDRStates.Add(hdrInfo);
}
}
// Go through the list of physicalTargetIdsAvailable
// ignore the ones that were found
// if one was not found, then
// go through the modes
// patch the target
if (isClonedProfile)
{
// Figure out which available displays are unused (in path priority order)
foreach (var physicalTargetId in physicalTargetIdsAvailable)
{
if (!targetIdsFound.Contains(physicalTargetId))
{
// this is a candidate physical target id to use as a replacement
replacementIds.Add(physicalTargetId);
}
}
// Now go through and figure out a mapping of old target id to new replacement id
Dictionary<uint, uint> targetIdMap = new Dictionary<uint, uint>();
for (int i = 0; i < targetPathIdsToChange.Count; i++)
{
uint targetPathId = targetPathIdsToChange[i];
if (i < replacementIds.Count)
{
targetIdMap[targetPathId] = replacementIds[i];
}
}
// Now we need to go through the list of paths again and patch the 'cloned' displays with a real display ID so the config works
for (int i = 0; i < paths.Length; i++)
{
if (targetIdMap.ContainsKey(paths[i].TargetInfo.Id))
{
// Patch the cloned ids with a real working one!
paths[i].TargetInfo.Id = targetIdMap[paths[i].TargetInfo.Id];
}
}
// And then we need to go through the list of modes again and patch the 'cloned' displays with a real display ID so the display layout is right in cloned displays
for (int i = 0; i < modes.Length; i++)
{
// We only change the ids that match in InfoType for target displays
if (modes[i].InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET && targetIdMap.ContainsKey(modes[i].Id))
{
// Patch the cloned ids with a real working one!
modes[i].Id = targetIdMap[modes[i].Id];
}
}
}
// And then we need to go through the list of modes again and patch the 'cloned' displays with a real display ID so the display layout is right in cloned displays
for (int i = 0; i < modes.Length; i++)
/*if (hdrInfos.Length > 0)
{
// We only change the ids that match in InfoType for target displays
if (modes[i].InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET && targetIdsToChange.Contains(modes[i].Id))
// If the screen
foreach (var hdrInfo in hdrInfos)
{
// Patch the cloned ids with a real working one!
modes[i].Id = targetIdMap[modes[i].Id];
targetIdMap[hdrInfo.Id] = hdrInfo.SDRWhiteLevel.Header.Id;
}
// Now we need to go through the list of paths again and patch the 'cloned' displays with a real display ID so the config works
for (int i = 0; i < paths.Length; i++)
{
if (targetIdsToChange.Contains(paths[i].TargetInfo.Id))
{
// Patch the cloned ids with a real working one!
paths[i].TargetInfo.Id = targetIdMap[paths[i].TargetInfo.Id];
}
}
// And then we need to go through the list of modes again and patch the 'cloned' displays with a real display ID so the display layout is right in cloned displays
for (int i = 0; i < modes.Length; i++)
{
// We only change the ids that match in InfoType for target displays
if (modes[i].InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET && targetIdsToChange.Contains(modes[i].Id))
{
// Patch the cloned ids with a real working one!
modes[i].Id = targetIdMap[modes[i].Id];
}
}
}
else
{
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: WARNING - There weren't any HDR Info objects created, so we have none to parse!");
}*/
// Store the active paths and modes in our display config object
windowsDisplayConfig.DisplayConfigPaths = paths;
windowsDisplayConfig.DisplayConfigModes = modes;
windowsDisplayConfig.DisplayHDRStates = hdrInfos;
windowsDisplayConfig.GdiDisplaySettings = GetGdiDisplaySettings();
return windowsDisplayConfig;
@ -678,7 +777,6 @@ namespace DisplayMagicianShared.Windows
return DisplaySources;
}
private LUID AdapterValueToLUID(ulong adapterValue)
{
LUID luid = new LUID();
@ -995,7 +1093,7 @@ namespace DisplayMagicianShared.Windows
{
// Get the all possible windows display configs
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Generating a list of all the current display configs");
WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS);
WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD);
if (displayConfig.IsCloned)
{
@ -1008,7 +1106,7 @@ namespace DisplayMagicianShared.Windows
// Now we go through the Paths to update the LUIDs as per Soroush's suggestion
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Patching the adapter IDs to make the saved config valid");
PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.DisplayAdapters);
PatchAdapterIDs(ref displayConfig);
uint myPathsCount = (uint)displayConfig.DisplayConfigPaths.Length;
uint myModesCount = (uint)displayConfig.DisplayConfigModes.Length;
@ -1122,8 +1220,8 @@ namespace DisplayMagicianShared.Windows
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: SUCCESS! The display configuration has been successfully applied");
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Waiting 0.5 seconds to let the display change take place before adjusting the Windows CCD HDR settings");
System.Threading.Thread.Sleep(500);
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Waiting 0.1 second to let the display change take place before adjusting the Windows CCD HDR settings");
System.Threading.Thread.Sleep(100);
// NOTE: There is currently no way within Windows CCD API to set the HDR settings to any particular setting
// This code will only turn on the HDR setting.
@ -1275,7 +1373,7 @@ namespace DisplayMagicianShared.Windows
public bool IsValidConfig(WINDOWS_DISPLAY_CONFIG displayConfig)
{
// Get the current windows display configs
WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS);
WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD);
SharedLogger.logger.Trace("WinLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to make sure they still exist");
// Firstly check that the Adapter Names are still currently available (i.e. the adapter hasn't been replaced).
@ -1293,7 +1391,7 @@ namespace DisplayMagicianShared.Windows
// Now we go through the Paths to update the LUIDs as per Soroush's suggestion
SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: Attemptong to patch the saved display configuration's adapter IDs so that it will still work (these change at each boot)");
PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.DisplayAdapters);
PatchAdapterIDs(ref displayConfig);
SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: Testing whether the display configuration is valid ");
// Test whether a specified display configuration is supported on the computer
@ -1339,16 +1437,16 @@ namespace DisplayMagicianShared.Windows
public List<string> GetCurrentDisplayIdentifiers()
{
SharedLogger.logger.Trace($"WinLibrary/GetCurrentDisplayIdentifiers: Getting the current display identifiers for the displays in use now");
return GetSomeDisplayIdentifiers(QDC.QDC_ONLY_ACTIVE_PATHS);
return GetSomeDisplayIdentifiers(QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD);
}
public List<string> GetAllConnectedDisplayIdentifiers()
{
SharedLogger.logger.Trace($"WinLibrary/GetAllConnectedDisplayIdentifiers: Getting all the display identifiers that can possibly be used");
return GetSomeDisplayIdentifiers(QDC.QDC_ALL_PATHS);
return GetSomeDisplayIdentifiers(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD);
}
private List<string> GetSomeDisplayIdentifiers(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS)
private List<string> GetSomeDisplayIdentifiers(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD)
{
SharedLogger.logger.Debug($"WinLibrary/GetCurrentDisplayIdentifiers: Generating the unique Display Identifiers for the currently active configuration");
@ -1545,7 +1643,7 @@ namespace DisplayMagicianShared.Windows
// Get the size of the largest Active Paths and Modes arrays
int pathCount = 0;
int modeCount = 0;
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, out pathCount, out modeCount);
if (err != WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentPCIVideoCardVendors: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
@ -1555,14 +1653,14 @@ namespace DisplayMagicianShared.Windows
SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays");
var paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
var modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
err = CCDImport.QueryDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
{
SharedLogger.logger.Warn($"WinLibrary/GetCurrentPCIVideoCardVendors: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again.");
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: Getting the size of the largest Active Paths and Modes arrays");
// Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again
// as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig
err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ALL_PATHS, out pathCount, out modeCount);
if (err != WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentPCIVideoCardVendors: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again");
@ -1571,7 +1669,7 @@ namespace DisplayMagicianShared.Windows
SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays");
paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
err = CCDImport.QueryDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentPCIVideoCardVendors: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
@ -1591,12 +1689,12 @@ namespace DisplayMagicianShared.Windows
foreach (var path in paths)
{
if (path.TargetInfo.TargetAvailable == false)
/*if (path.TargetInfo.TargetAvailable == false)
{
// We want to skip this one cause it's not valid
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: Skipping path due to TargetAvailable not existing in display #{path.TargetInfo.Id}");
continue;
}
}*/
// get display adapter name
var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME();
@ -1616,25 +1714,45 @@ namespace DisplayMagicianShared.Windows
try
{
// The AdapterDevicePath is something like "\\\\?\\PCI#VEN_10DE&DEV_2482&SUBSYS_408E1458&REV_A1#4&2283f625&0&0019#{5b45201d-f2f2-4f3b-85bb-30ff1f953599}"
// The AdapterDevicePath is something like "\\?\PCI#VEN_10DE&DEV_2482&SUBSYS_408E1458&REV_A1#4&2283f625&0&0019#{5b45201d-f2f2-4f3b-85bb-30ff1f953599}" if it's a PCI card
// or it is something like "\\?\USB#VID_17E9&PID_430C&MI_00#8&d6f23a6&1&0000#{5b45201d-f2f2-4f3b-85bb-30ff1f953599}" if it's a USB card (or USB emulating)
// or it is something like "\\?\SuperDisplay#Display#1&3343b12b&0&1234#{5b45201d-f2f2-4f3b-85bb-30ff1f953599}" if it's a SuperDisplay device (allows Android tablet device to be used as directly attached screen)
// We only want the vendor ID
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: The AdapterDevicePath for this path is :{adapterInfo.AdapterDevicePath}");
// Match against the vendor ID
string pattern = @"VEN_([\d\w]{4})&";
string pattern = @"(PCI|USB)#(?:VEN|VID)_([\d\w]{4})&";
Match match = Regex.Match(adapterInfo.AdapterDevicePath, pattern);
if (match.Success)
{
string VendorId = match.Groups[1].Value;
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: The matched PCI Vendor ID is :{VendorId }");
if (!videoCardVendorIds.Contains(VendorId))
string pciType = match.Groups[1].Value;
string vendorId = match.Groups[2].Value;
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: The matched PCI Vendor ID is :{vendorId } and the PCI device is a {pciType} device.");
if (!videoCardVendorIds.Contains(vendorId))
{
videoCardVendorIds.Add(VendorId);
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: Stored PCI vendor ID {VendorId} as we haven't already got it");
videoCardVendorIds.Add(vendorId);
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: Stored PCI vendor ID {vendorId} as we haven't already got it");
}
}
else
{
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: The PCI Vendor ID pattern wasn't matched so we didn't record a vendor ID.");
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: The device is not a USB or PCI card, sp trying to see if it is a SuperDisplay device.");
string pattern2 = @"SuperDisplay#";
Match match2 = Regex.Match(adapterInfo.AdapterDevicePath, pattern2);
if (match2.Success)
{
string pciType = "SuperDisplay";
string vendorId = "SuperDisplay";
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: The matched PCI Vendor ID is :{vendorId } and the PCI device is a {pciType} device.");
if (!videoCardVendorIds.Contains(vendorId))
{
videoCardVendorIds.Add(vendorId);
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: Stored PCI vendor ID {vendorId} as we haven't already got it");
}
}
else
{
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: The PCI Vendor ID pattern wasn't matched so we didn't record a vendor ID. AdapterDevicePath = {adapterInfo.AdapterDevicePath}");
}
}
}
@ -1649,6 +1767,91 @@ namespace DisplayMagicianShared.Windows
}
public Dictionary<ulong, string> GetCurrentAdapterIDs()
{
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Getting the current adapter ids for the videocards Windows knows about");
Dictionary<ulong, string> currentAdapterMap = new Dictionary<ulong, string>();
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Testing whether the display configuration is valid (allowing tweaks).");
// Get the size of the largest All Paths and Modes arrays
int pathCount = 0;
int modeCount = 0;
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, out pathCount, out modeCount);
if (err != WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
throw new WinLibraryException($"GetCurrentAdapterIDs returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
}
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Getting the current Display Config path and mode arrays");
var paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
var modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
err = CCDImport.QueryDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
{
SharedLogger.logger.Warn($"WinLibrary/GetCurrentAdapterIDs: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again.");
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Getting the size of the largest Active Paths and Modes arrays");
// Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again
// as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig
err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ALL_PATHS, out pathCount, out modeCount);
if (err != WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again");
throw new WinLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again");
}
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Getting the current Display Config path and mode arrays");
paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
err = CCDImport.QueryDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
throw new WinLibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
}
else if (err != WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again");
throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again.");
}
}
else if (err != WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays");
throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays.");
}
foreach (var path in paths)
{
if (path.TargetInfo.TargetAvailable == false)
{
// We want to skip this one cause it's not valid
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Skipping path due to TargetAvailable not existing in display #{path.TargetInfo.Id}");
continue;
}
// get display adapter name
var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME();
adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME;
adapterInfo.Header.Size = (uint)Marshal.SizeOf<DISPLAYCONFIG_ADAPTER_NAME>();
adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId;
adapterInfo.Header.Id = path.TargetInfo.Id;
err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo);
if (err == WIN32STATUS.ERROR_SUCCESS)
{
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Successfully got the display name info from {path.TargetInfo.Id}.");
currentAdapterMap[path.TargetInfo.AdapterId.Value] = adapterInfo.AdapterDevicePath;
}
else
{
SharedLogger.logger.Warn($"WinLibrary/GetCurrentAdapterIDs: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}");
}
}
return currentAdapterMap;
}
public static bool GDISettingsEqual(Dictionary<string, GDI_DISPLAY_SETTING> gdi1, Dictionary<string, GDI_DISPLAY_SETTING> gdi2)
{
if (gdi1.Count == gdi2.Count)

View File

@ -79,7 +79,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers">
<Version>5.0.3</Version>
<Version>6.0.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

View File

@ -20,8 +20,8 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="nunit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
</ItemGroup>
<ItemGroup>