[WIP] Attempt to get TaskBar changing to work

This commit is contained in:
Terry MacDonald 2022-03-05 18:46:47 +13:00
parent 87f62aa322
commit 72b1acfe46
5 changed files with 139 additions and 11 deletions

View File

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

View File

@ -287,15 +287,15 @@ namespace DisplayMagician.UIForms
// lbl_save_profile
//
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.BackColor = System.Drawing.Color.Firebrick;
this.lbl_save_profile.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.lbl_save_profile.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
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(290, 63);
this.lbl_save_profile.Location = new System.Drawing.Point(24, 80);
this.lbl_save_profile.Name = "lbl_save_profile";
this.lbl_save_profile.Size = new System.Drawing.Size(365, 157);
this.lbl_save_profile.Size = new System.Drawing.Size(625, 88);
this.lbl_save_profile.TabIndex = 33;
this.lbl_save_profile.Text = resources.GetString("lbl_save_profile.Text");
this.lbl_save_profile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;

View File

@ -4,10 +4,13 @@ using System.Linq;
using System.Windows.Forms;
using DisplayMagician.Resources;
using DisplayMagicianShared;
using DisplayMagicianShared.Windows;
using Manina.Windows.Forms;
using System.Drawing;
using NHotkey.WindowsForms;
using NHotkey;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace DisplayMagician.UIForms
{
@ -20,6 +23,9 @@ namespace DisplayMagician.UIForms
private static ProfileItem _profileToLoad = null;
private ProfileAdaptor _profileAdaptor = new ProfileAdaptor();
//public static Dictionary<string, bool> profileValidity = new Dictionary<string, bool>();
public Task _monitorTaskBarRegKeysForChangesTask = null;
//public bool _monitorTaskBarRegKeysForChanges = false;
//private readonly object _monitorTaskBarRegKeysForChangesLock = new object();
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
@ -521,13 +527,89 @@ namespace DisplayMagician.UIForms
const int WM_SETTINGCHANGE = 0x001A;
const int WM_DEVICECHANGE = 0x0219;
const int DBT_DEVICEARRIVAL = 0x8000;
const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
switch (m.Msg)
{
case WM_DEVICECHANGE:
case WM_SETTINGCHANGE:
switch ((int)m.WParam)
{
case DBT_DEVICEARRIVAL:
logger.Trace($"DisplayProfileForm/WndProc: Windows just sent a msg telling us a device has been added. We need to check if this was a USB display. Updating the current view by running btn_view_current.");
btn_view_current.PerformClick();
break;
case DBT_DEVICEREMOVECOMPLETE:
logger.Trace($"DisplayProfileForm/WndProc: Windows just sent a msg telling us a device has been removed. We need to check if this was a USB display. Updating the current view by running btn_view_current.");
btn_view_current.PerformClick();
break;
}
break;
case WM_DISPLAYCHANGE:
logger.Trace($"DisplayProfileForm/WndProc: Windows just sent a msg telling us the display has changed. Updating the current view by running btn_view_current.");
btn_view_current.PerformClick();
break;
// This auto taskbar detection logic just doesn't work at the moment
// It tries to set a 5 second timer when it detects a settings change, and tries every 1 second to see if the taskbar position has changed
// If taskbar position changed, then it attempts to get the new display layout.
// In reality, it appears that multiple tasks are firing for each message, and the multople tasks are confusing each other. So I'm going to leave this be for now.
/*case WM_SETTINGCHANGE:
switch ((int)m.WParam)
{
case 0x2f:
// This occurs when the taskbar is moved! We use it to set a timer to monitor the relevant registry keys for changes within the next 10 seconds
logger.Trace($"DisplayProfileForm/WndProc: Windows just sent a msg telling us a taskbar has been moved. We need to set a timer to check for registry key changes within the next 10 seconds, and update the current view if that happens.");
if (_monitorTaskBarRegKeysForChangesTask == null)
{
logger.Trace($"DisplayProfileForm/WndProc: We are starting to monitor the taskbar for changes for the next 10 seconds.");
//_monitorTaskBarRegKeysForChanges = true;
List<TaskBarStuckRectangle> original = TaskBarStuckRectangle.GetAllTaskBarStuckRectangles();
_monitorTaskBarRegKeysForChangesTask = new Task((Action)delegate
{
bool _itChanged = false;
for (int d = 0; d < 10; d++)
{
Task.Delay(1000);
List<TaskBarStuckRectangle> subsequent = TaskBarStuckRectangle.GetAllTaskBarStuckRectangles();
bool matched = true;
for (int x = 0; x < subsequent.Count; x++)
{
if (!original[x].Equals(subsequent[x]))
{
matched = false;
break;
}
}
if (!matched)
{
logger.Trace($"DisplayProfileForm/WndProc: The taskbar registry key has been updated within the 10 seconds of a taskbar move message, so updating the config again window.");
if (btn_view_current.InvokeRequired)
{
this.Invoke(new Action(() => btn_view_current.PerformClick()));
}
else
{
btn_view_current.PerformClick();
}
_itChanged = true;
break;
}
}
if (!_itChanged)
{
logger.Trace($"DisplayProfileForm/WndProc: The taskbar registry key did not update within 5 seconds of a taskbar move message. Returning without doing anything.");
}
_monitorTaskBarRegKeysForChangesTask = null;
});
_monitorTaskBarRegKeysForChangesTask.Start();
}
break;
}
break;*/
}
base.WndProc(ref m);

View File

@ -160,7 +160,7 @@
<value>248, 17</value>
</metadata>
<data name="lbl_save_profile.Text" xml:space="preserve">
<value>Setup your display layout in NVIDIA Control Panel, AMD Radeon Adrenaline or Windows Display Settings, then return to DisplayMagician and click 'Save' to store this Display Profile for later use. Taskbar changes will show up after a few seconds.</value>
<value>Setup your display layout in NVIDIA Control Panel, AMD Radeon Adrenaline or Windows Display Settings, then return to DisplayMagician and click 'Save' to store this Display Profile for later use. If you make any Taskbar changes please press 'View Current Display' button after waiting 5 seconds.</value>
</data>
<metadata name="dialog_save.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>358, 17</value>

View File

@ -15,7 +15,7 @@ using Newtonsoft.Json;
namespace DisplayMagicianShared.Windows
{
public class TaskBarStuckRectangle
public class TaskBarStuckRectangle : IEquatable<TaskBarStuckRectangle>, IComparable<TaskBarStuckRectangle>
{
public enum TaskBarEdge : UInt32
@ -118,7 +118,7 @@ namespace DisplayMagicianShared.Windows
}
else
{
SharedLogger.logger.Trace($"TaskBarStuckRectangle/TaskBarStuckRectangle: Unable to get the TaskBarStuckRectangle binary settings from {devicePath} screen.");
SharedLogger.logger.Trace($"TaskBarStuckRectangle/TaskBarStuckRectangle: Unable to get the TaskBarStuckRectangle binary settings from {devicePath} screen from the MMSuckRect. Trying the main StruckRect instead.");
}
}
}
@ -260,6 +260,21 @@ namespace DisplayMagicianShared.Windows
public static bool operator !=(TaskBarStuckRectangle lhs, TaskBarStuckRectangle rhs) => !(lhs == rhs);
public int CompareTo(TaskBarStuckRectangle other)
{
int ourHashCode = GetHashCode();
int otherHashCode = other.GetHashCode();
if (ourHashCode > otherHashCode)
return 1;
if (ourHashCode < otherHashCode)
return -1;
else
return 0;
}
static bool Xor(byte[] a, byte[] b)
{
@ -498,7 +513,38 @@ namespace DisplayMagicianShared.Windows
return true;
}
public static List<TaskBarStuckRectangle> GetAllTaskBarStuckRectangles()
{
// Now attempt to get the windows taskbar location for each display
// We use the information we already got from the display identifiers
SharedLogger.logger.Trace($"TaskBarStuckRectangles/GetAllTaskBarStuckRectangles: Attempting to get the Windows Taskbar layout.");
List<TaskBarStuckRectangle> taskBarStuckRectangles = new List<TaskBarStuckRectangle>();
foreach (var displayId in WinLibrary.GetLibrary().GetCurrentDisplayIdentifiers())
{
// e.g. "WINAPI|\\\\?\\PCI#VEN_10DE&DEV_2482&SUBSYS_408E1458&REV_A1#4&2283f625&0&0019#{5b45201d-f2f2-4f3b-85bb-30ff1f953599}|DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI|54074|4318|\\\\?\\DISPLAY#NVS10DE#5&2b46c695&0&UID185344#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}|NV Surround"
string[] winapiLine = displayId.Split('|');
string pattern = @"DISPLAY\#(.*)\#\{";
Match match = Regex.Match(winapiLine[5], pattern);
if (match.Success)
{
string devicePath = match.Groups[1].Value;
SharedLogger.logger.Trace($"TaskBarStuckRectangles/GetAllTaskBarStuckRectangles: Found devicePath {devicePath} from the display identifier {displayId}.");
TaskBarStuckRectangle taskBarStuckRectangle = new TaskBarStuckRectangle(devicePath);
taskBarStuckRectangles.Add(taskBarStuckRectangle);
}
else
{
SharedLogger.logger.Warn($"TaskBarStuckRectangles/GetAllTaskBarStuckRectangles: We were unable to figure out the DevicePath for the '{displayId}' display identifier.");
}
}
// And we get the Main Screen taskbar too
TaskBarStuckRectangle mainTaskBarStuckRectangle = new TaskBarStuckRectangle("Settings");
taskBarStuckRectangles.Add(mainTaskBarStuckRectangle);
return taskBarStuckRectangles;
}
/*public void DoMouseLeftClick(IntPtr handle, Point x)
{