Files
PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMatrix.cs
Michael Clayton 6515374ce9 Ready for Review - [Mouse Without Borders] - refactoring "Common" classes (Part 3) - #35155 (#36950)
* [MWB] - refactoring MachineInf from Common.MachineStuff.cs into MachineInf.cs - #35155

* [MWB] - fixing references to MachineInf - #35155

* [MWB] - cleaning up MachineInf.cs - #35155

* [MWB] - moving MyRectangle from Common.MachineStuff.cs into MyRectangle.cs - #35155

* [MWB] - cleaning up MyRectangle.cs - #35155

* [MWB] - moving Common.MachineStuff.cs to MachineStuff.cs - #35155

* [MWB] - fixing references to MachineStuff - #35155

* [MWB] - cleaning up MachineStuff.cs - #35155

* [MWB] - cleaning up MachineStuff.cs - #35155

* [MWB] - moving Common.DragDrop.cs to DragDrop.cs - #35155

* [MWB] - fixing references to DragDrop - #35155

* [MWB] - fixing unit test - #35155

* [MWB] - cleaning up DragDrop.cs - #35155

* [MWB] - cleaning up DragDrop.cs - #35155
2025-02-21 09:31:44 +01:00

1236 lines
45 KiB
C#

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Microsoft.PowerToys.Telemetry;
// <summary>
// Matrix/Settings form.
// </summary>
// <history>
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
// </history>
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
using Timer = System.Windows.Forms.Timer;
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#buttonOK_Click(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#buttonSendHello_Click(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#frmMatrix_Load(System.Object,System.EventArgs)", MessageId = "System.String.ToLower", Justification = "Dotnet port with style preservation")]
// [module: SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#ChangeUI2OneRow(System.Boolean)")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#logoTimer_Tick(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#Dispose(System.Boolean)", MessageId = "logoBitmap", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#frmMatrix_Shown(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#PaintMyLogo()", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Style", "IDE1006:Naming Styles", Scope = "member", Target = "~M:MouseWithoutBorders.FrmMatrix.M_EnabledChanged(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
namespace MouseWithoutBorders
{
internal partial class FrmMatrix : System.Windows.Forms.Form, IDisposable
{
#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager
private Timer helperTimer;
#pragma warning restore CA2213
private bool formShown;
private int formOrgHeight;
private bool matrixOneRow;
internal FrmMatrix()
{
InitializeComponent();
textBoxEnc.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0);
Text = Application.ProductName + " " + Application.ProductVersion + " - Settings";
toolTip.ToolTipTitle = Application.ProductName;
toolTipManual.ToolTipTitle = Application.ProductName;
labelExitMM.Text = "Exit the application, Ctrl+Alt+Shift+:";
textBoxMachineName2IP.Text = Setting.Values.Name2IP;
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
buttonCancel.Enabled = false;
Close();
Common.MatrixForm = null;
}
private void ButtonOK_Click(object sender, EventArgs e)
{
buttonOK.Enabled = false;
if (!UpdateKey(Regex.Replace(textBoxEnc.Text, @"\s+", string.Empty)))
{
buttonOK.Enabled = true;
return;
}
string[] st = new string[MachineStuff.MAX_MACHINE];
for (int i = 0; i < MachineStuff.MAX_MACHINE; i++)
{
if (machines[i].MachineEnabled)
{
for (int j = 0; j < i; j++)
{
if (st[j].Equals(machines[i].MachineName, StringComparison.OrdinalIgnoreCase))
{
machines[i].MachineName = string.Empty;
machines[i].MachineEnabled = false;
}
}
st[i] = machines[i].MachineName;
}
else
{
st[i] = string.Empty;
}
}
MachineStuff.MachineMatrix = st;
Setting.Values.MatrixOneRow = matrixOneRow = !checkBoxTwoRow.Checked;
if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
{
Program.StartService();
Common.ShowToolTip("New settings applied on the physical console session!", 3000, ToolTipIcon.Warning, false);
}
else
{
SocketStuff.InvalidKeyFound = false;
showInvalidKeyMessage = false;
Common.ReopenSocketDueToReadError = true;
Common.ReopenSockets(true);
for (int i = 0; i < 10; i++)
{
if (Common.AtLeastOneSocketConnected())
{
Common.MMSleep(0.5);
break;
}
Common.MMSleep(0.2);
}
MachineStuff.SendMachineMatrix();
}
buttonOK.Enabled = true;
}
internal void UpdateKeyTextBox()
{
_ = Common.GetUserName();
textBoxEnc.Text = Common.MyKey;
}
private void InitAll()
{
formOrgHeight = Height;
matrixOneRow = Setting.Values.MatrixOneRow;
CreateMachines();
LoadSettingsToUI();
UpdateKeyTextBox();
}
private void LoadMachines()
{
bool meAdded = false;
string machineName;
if (MachineStuff.MachineMatrix != null && MachineStuff.MachineMatrix.Length == MachineStuff.MAX_MACHINE)
{
Logger.LogDebug("LoadMachines: Machine Matrix: " + Setting.Values.MachineMatrixString);
for (int i = 0; i < MachineStuff.MAX_MACHINE; i++)
{
machineName = MachineStuff.MachineMatrix[i].Trim();
machines[i].MachineName = machineName;
if (string.IsNullOrEmpty(machineName))
{
machines[i].CheckAble = true;
}
else
{
machines[i].MachineEnabled = true;
}
bool found = MachineStuff.MachinePool.TryFindMachineByName(machineName, out MachineInf machineInfo);
if (found)
{
if (machineInfo.Id == Common.MachineID)
{
machines[i].LocalHost = true;
meAdded = true;
}
}
}
}
if (!meAdded)
{
foreach (Machine m in machines)
{
if (string.IsNullOrEmpty(m.MachineName))
{
m.MachineName = Common.MachineName.Trim();
m.LocalHost = true;
meAdded = true;
break;
}
}
}
}
private void CheckBoxShowKey_CheckedChanged(object sender, EventArgs e)
{
textBoxEnc.PasswordChar = checkBoxShowKey.Checked ? (char)0 : '*';
}
private void FrmMatrix_Shown(object sender, EventArgs e)
{
if (Setting.Values.FirstRun)
{
Setting.Values.FirstRun = false;
Common.ReopenSockets(false);
/*
string fireWallLog = Path.GetDirectoryName(Application.ExecutablePath) + "\\FirewallError.log";
if (File.Exists(fireWallLog))
{
//@"http://bing.com/search?q=Allow+a+program+through+Windows+Firewall"
MessageBox.Show(Application.ProductName + " was unable to add itself to the Firewall exception list.\r\n" +
"The following application needs to be added to the Firewall exception list:\r\n\r\n" +
Application.ExecutablePath +
"\r\n\r\nYou can go to bing.com and do a search on" + "\r\n'Allow a program through Windows Firewall' to know how.",
Application.ProductName,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
linkLabelHelp_LinkClicked(null, null);
* */
}
InitAll();
if (Setting.Values.IsMyKeyRandom)
{
Setting.Values.IsMyKeyRandom = false;
checkBoxShowKey.Checked = true;
}
if (helperTimer == null)
{
helperTimer = new Timer();
helperTimer.Interval = 200;
helperTimer.Tick += new EventHandler(HelperTimer_Tick);
helperTimer.Start();
}
formShown = true;
}
private void FrmMatrix_FormClosed(object sender, FormClosedEventArgs e)
{
/*
if (logoTimer != null)
{
logoTimer.Stop();
logoTimer.Dispose();
logoTimer = null;
}
* */
if (helperTimer != null)
{
helperTimer.Stop();
helperTimer.Dispose();
helperTimer = null;
}
// if (logoBitmap != null) logoBitmap.Dispose();
Common.MatrixForm = null;
}
private int pivot;
private Bitmap logoBitmap;
private void PaintMyLogo()
{
if (!Visible || !(tabControlSetting.SelectedTab == tabPageAdvancedSettings))
{
return;
}
uint rv = 0;
try
{
Color c;
uint cl;
double dC;
logoBitmap ??= new Bitmap(pictureBoxMouseWithoutBorders0.BackgroundImage);
int bWidth = logoBitmap.Width;
int bHeight = logoBitmap.Height;
double dx = (double)pictureBoxMouseWithoutBorders.Width / bWidth;
double dy = (double)pictureBoxMouseWithoutBorders.Height / bHeight;
IntPtr hdc = NativeMethods.GetWindowDC(pictureBoxMouseWithoutBorders.Handle);
for (int i = 0; i < bWidth; i++)
{
for (int j = 0; j < bHeight; j++)
{
c = logoBitmap.GetPixel(i, j);
// c.G > 245
if (c.R < 240 && c.B < 240)
{
dC = Math.Abs(pivot - i);
if (bWidth - pivot + i < dC)
{
dC = bWidth - pivot + i;
}
if (bWidth - i + pivot < dC)
{
dC = bWidth - i + pivot;
}
dC /= bWidth;
// c = Color.FromArgb(80, (int)(255 - 255 * dC), 80);
cl = (160 << 16) | ((uint)(255 - (255 * dC)) << 8) | 160;
// Using GDI SetPixel so we dont have to assign the image later on
// b.SetPixel(i, j, c);
rv = NativeMethods.SetPixel(hdc, (int)(i * dx), (int)(j * dy), cl);
}
}
}
// Image im = pictureBoxMouseWithoutBorders.BackgroundImage;
// pictureBoxMouseWithoutBorders.BackgroundImage = b;
// if (im != null) im.Dispose();
rv = (uint)NativeMethods.ReleaseDC(pictureBoxMouseWithoutBorders.Handle, hdc);
pivot = (pivot + 5) % bWidth;
}
catch (Exception ee)
{
Logger.Log(ee);
Logger.Log(rv.ToString(CultureInfo.CurrentCulture));
}
}
private void AddNewMachine()
{
string newMachine;
Machine unUsedMachine;
foreach (MachineInf inf in MachineStuff.MachinePool.ListAllMachines())
{
bool found = false;
unUsedMachine = null;
newMachine = inf.Name.Trim();
foreach (Machine m in machines)
{
if (m.MachineName.Equals(
newMachine,
StringComparison.OrdinalIgnoreCase))
{
found = true;
}
else if (unUsedMachine == null && string.IsNullOrEmpty(m.MachineName.Trim()))
{
unUsedMachine = m;
}
}
if (!found && unUsedMachine != null)
{
unUsedMachine.MachineName = newMachine;
}
}
}
private int helperTimerCounter;
private bool showInvalidKeyMessage;
private void HelperTimer_Tick(object sender, EventArgs e)
{
string keyNotMatchedMachines = string.Empty;
if (Setting.Values.Changed)
{
Setting.Values.Changed = false;
matrixOneRow = Setting.Values.MatrixOneRow;
LoadSettingsToUI();
/*
if (!Common.InMachineMatrix(Common.MachineName))
{
foreach (Machine m in machines)
{
if (!m.LocalHost)
{
m.MachineEnabled = false;
}
}
}
* */
}
helperTimerCounter++;
// 1 sec
if (helperTimerCounter % 5 == 0)
{
comboBoxEasyMouseOption.Text = ((EasyMouseOption)Setting.Values.EasyMouse).ToString();
if (!textBoxMachineName2IP.Text.Equals(Setting.Values.Name2IP, StringComparison.OrdinalIgnoreCase))
{
Setting.Values.Name2IP = textBoxMachineName2IP.Text;
}
// 2 times
if (helperTimerCounter < 15)
{
Common.SendHello();
}
AddNewMachine();
}
// NOTE(@yuyoyuppe): this option is deprecated
// checkBoxVKMap.Checked = Setting.Values.UseVKMap;
foreach (Machine m in machines)
{
if (m.StatusClient != SocketStatus.NA)
{
m.StatusClient = SocketStatus.NA;
}
if (m.StatusServer != SocketStatus.NA)
{
m.StatusServer = SocketStatus.NA;
}
}
SocketStuff sk = Common.Sk;
if (sk != null)
{
lock (sk.TcpSocketsLock)
{
if (sk.TcpSockets != null)
{
foreach (TcpSk t in sk.TcpSockets)
{
if (t.Status == SocketStatus.InvalidKey)
{
keyNotMatchedMachines += string.Format(CultureInfo.CurrentCulture, "[{0}]", t.MachineName);
}
foreach (Machine m in machines)
{
if (m.MachineEnabled)
{
if (m.MachineName.Equals(t.MachineName, StringComparison.OrdinalIgnoreCase))
{
if (t.IsClient)
{
if (t.Status > m.StatusClient)
{
m.StatusClient = t.Status;
}
}
else
{
if (t.Status > m.StatusServer)
{
m.StatusServer = t.Status;
}
}
}
}
}
}
}
}
}
if (SocketStuff.InvalidKeyFound)
{
if (!showInvalidKeyMessage)
{
showInvalidKeyMessage = true;
Common.ShowToolTip(
"Security Keys not matched.\r\nVerify that you entered the same key in all machines.\r\nAnd make sure you run the same version of "
+ Application.ProductName + " in all machines.\r\n" + keyNotMatchedMachines + "\r\nThis version: " + FrmAbout.AssemblyVersion,
20000,
ToolTipIcon.Warning,
Setting.Values.ShowClipNetStatus);
}
}
else
{
showInvalidKeyMessage = false;
}
PaintMyLogo();
}
private void ShowKeyErrorMsg(string msg)
{
Common.ShowToolTip(msg, 10000, ToolTipIcon.Error, false);
_ = textBoxEnc.Focus();
textBoxEnc.SelectAll();
}
private bool UpdateKey(string newKey)
{
if (!Common.IsKeyValid(newKey, out string rv))
{
ShowKeyErrorMsg(rv);
return false;
}
if (!newKey.Equals(Common.MyKey, StringComparison.OrdinalIgnoreCase))
{
Common.MyKey = newKey;
Common.GeneratedKey = false;
}
Common.MagicNumber = Common.Get24BitHash(Common.MyKey);
return true;
}
private readonly Machine[] machines = new Machine[MachineStuff.MAX_MACHINE];
private Machine dragDropMachine;
private Machine desMachine;
private Machine desMachineX;
private Machine desMachineY;
private Machine oldDesMachine;
private Point desMachinePos;
private Point oldDesMachinePos;
private void CreateMachines()
{
for (int i = 0; i < MachineStuff.MAX_MACHINE; i++)
{
Machine m = new();
m.MouseDown += Machine_MouseDown;
m.EnabledChanged += new EventHandler(M_EnabledChanged);
m.Parent = groupBoxMachineMatrix;
m.MachineEnabled = false;
machines[i] = m;
}
FrmMatrix_Resize(this, EventArgs.Empty);
ArrangeMachines();
}
private void ArrangeMachines()
{
Height = matrixOneRow ? formOrgHeight : formOrgHeight + 60;
int dx = (groupBoxMachineMatrix.Width - 40) / 4;
int yOffset = groupBoxMachineMatrix.Height / 3;
for (int i = 0; i < MachineStuff.MAX_MACHINE; i++)
{
machines[i].Left = matrixOneRow ? 22 + (i * dx) : 22 + dx + ((i % 2) * dx);
machines[i].Top = matrixOneRow ? yOffset : (yOffset / 2) + (i / 2 * (machines[i].Width + 2));
machines[i].Visible = true;
}
}
private void M_EnabledChanged(object sender, EventArgs e)
{
Machine m = sender as Machine;
SocketStuff sk = Common.Sk;
if (!m.MachineEnabled && sk != null)
{
lock (sk.TcpSocketsLock)
{
if (sk.TcpSockets != null)
{
foreach (TcpSk t in sk.TcpSockets)
{
if (t.MachineName != null && t.MachineName.Equals(m.MachineName.Trim(), StringComparison.OrdinalIgnoreCase))
{
t.Status = SocketStatus.NA;
}
}
}
}
}
}
private void Machine_MouseDown(object sender, MouseEventArgs e)
{
oldDesMachine = desMachine = dragDropMachine = sender as Machine;
desMachinePos.X = desMachine.Left;
desMachinePos.Y = desMachine.Top;
oldDesMachinePos.X = oldDesMachine.Left;
oldDesMachinePos.Y = oldDesMachine.Top;
dragDropMachineOrgX = dragDropMachine.Left;
dragDropMachineOrgY = dragDropMachine.Top;
dragDropMachine.BringToFront();
_ = DoDragDrop(dragDropMachine, DragDropEffects.Move);
}
private int startX;
private int startY;
private int dragDropMachineOrgX;
private int dragDropMachineOrgY;
private void Form_DragEnter(object sender, DragEventArgs e)
{
startX = e.X;
startY = e.Y;
e.Effect = DragDropEffects.Move;
}
private bool IsOnSameRow(Machine m1, Machine m2)
{
return matrixOneRow || (m1 == dragDropMachine ? desMachinePos.Y : m1.Top) == m2.Top;
}
private bool IsOnSameCol(Machine m1, Machine m2)
{
return !matrixOneRow && (m1 == dragDropMachine ? desMachinePos.X : m1.Left) == m2.Left;
}
private long lastMove;
private void Form_DragOver(object sender, DragEventArgs e)
{
if (dragDropMachine == null)
{
return;
}
e.Effect = DragDropEffects.Move;
dragDropMachine.Left = dragDropMachineOrgX + (e.X - startX);
dragDropMachine.Top = dragDropMachineOrgY + (e.Y - startY);
/*
dragDropMachine.Left = e.X - dragDropMachine.MouseDownPos.X - Left - 3
- groupBoxMachineMatrix.Left - tabControlSetting.Left;
dragDropMachine.Top = e.Y - dragDropMachine.MouseDownPos.Y - Top - 25
- groupBoxMachineMatrix.Top - tabControlSetting.Top;
* */
if (!matrixOneRow && Common.GetTick() - lastMove < 500)
{
return;
}
int minX = Math.Abs(dragDropMachine.Left - desMachinePos.X);
int minY = Math.Abs(dragDropMachine.Top - desMachinePos.Y);
desMachineX = desMachineY = desMachine;
for (int i = 0; i < MachineStuff.MAX_MACHINE; i++)
{
if (machines[i] == dragDropMachine)
{
continue;
}
if (IsOnSameRow(oldDesMachine, machines[i]))
{
if (minX > Math.Abs(dragDropMachine.Left - machines[i].Left))
{
minX = Math.Abs(dragDropMachine.Left - machines[i].Left);
desMachineX = machines[i];
}
}
if (IsOnSameCol(oldDesMachine, machines[i]))
{
if (minY > Math.Abs(dragDropMachine.Top - machines[i].Top))
{
minY = Math.Abs(dragDropMachine.Top - machines[i].Top);
desMachineY = machines[i];
}
}
}
oldDesMachine = desMachine;
desMachine = desMachineY == oldDesMachine ? desMachineX : desMachineX == oldDesMachine ? desMachineY : minX < minY ? desMachineX : desMachineY;
if (desMachine != oldDesMachine)
{
oldDesMachinePos.X = desMachinePos.X;
desMachinePos.X = desMachine.Left;
oldDesMachinePos.Y = desMachinePos.Y;
desMachinePos.Y = desMachine.Top;
desMachine.Left = oldDesMachinePos.X;
desMachine.Top = oldDesMachinePos.Y;
desMachine = dragDropMachine;
lastMove = Common.GetTick();
}
}
private void Form_DragDrop(object sender, DragEventArgs e)
{
if (desMachine != null)
{
dragDropMachine.Left = desMachinePos.X;
dragDropMachine.Top = desMachinePos.Y;
Machine tmp;
for (int i = 0; i < MachineStuff.MAX_MACHINE - 1; i++)
{
for (int j = 0; j < MachineStuff.MAX_MACHINE - 1 - i; j++)
{
if (machines[j + 1].Top < machines[j].Top || (machines[j + 1].Top == machines[j].Top && machines[j + 1].Left < machines[j].Left))
{
tmp = machines[j];
machines[j] = machines[j + 1];
machines[j + 1] = tmp;
}
}
}
}
}
private void FrmMatrix_DragLeave(object sender, EventArgs e)
{
Form_DragDrop(sender, null);
InputSimulation.MouseUp();
}
private void LoadSettingsToUI()
{
checkBoxCircle.Checked = Setting.Values.MatrixCircle;
checkBoxTwoRow.Checked = !matrixOneRow;
checkBoxBlockMouseAtCorners.Checked = Setting.Values.BlockMouseAtCorners;
checkBoxDrawMouse.Checked = Setting.Values.DrawMouse;
checkBoxReverseLookup.Checked = Setting.Values.ReverseLookup;
checkBoxSameSubNet.Checked = Setting.Values.SameSubNetOnly;
// NOTE(@yuyoyuppe): this option is deprecated
// checkBoxVKMap.Checked = Setting.Values.UseVKMap;
foreach (Machine m in machines)
{
m.MachineName = string.Empty;
m.MachineEnabled = false;
m.LocalHost = false;
}
LoadMachines();
}
internal static readonly string[] Separator = new string[] { "\r\n" };
internal void ShowTip(ToolTipIcon icon, string text, int duration)
{
int x = 0;
text += "\r\n ";
int y = (-text.Split(Separator, StringSplitOptions.None).Length * 15) - 30;
toolTipManual.Hide(this);
toolTipManual.ToolTipIcon = icon;
toolTipManual.Show(text, this, x, y, duration);
}
private void LinkLabelHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
linkLabelHelp.Enabled = false;
linkLabelHelp.Enabled = true;
}
private void CheckBoxShareClipboard_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.ShareClipboard = checkBoxShareClipboard.Checked;
checkBoxTransferFile.Enabled = checkBoxTransferFile.Checked = Setting.Values.ShareClipboard;
ShowUpdateMessage();
}
private void CheckBoxTransferFile_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.TransferFile = checkBoxTransferFile.Checked;
ShowUpdateMessage();
Common.HasSwitchedMachineSinceLastCopy = true;
}
private void CheckBoxDisableCAD_CheckedChanged(object sender, EventArgs e)
{
if (!Common.RunWithNoAdminRight)
{
Common.ApplyCADSetting();
ShowUpdateMessage();
}
}
private void FrmMatrix_Load(object sender, EventArgs e)
{
if (Common.RunWithNoAdminRight)
{
checkBoxDisableCAD.Enabled = false;
checkBoxHideLogo.Enabled = false;
}
// Note(@htcfreek): Disable checkboxes of settings that we don't support in the PowerToys implementation
checkBoxDisableCAD.Enabled = false;
checkBoxDisableCAD.Text = checkBoxDisableCAD.Text + " [Unsupported!]";
checkBoxHideLogo.Enabled = false;
checkBoxHideLogo.Text = checkBoxHideLogo.Text + " [Unsupported!]";
checkBoxSendLog.Enabled = false;
checkBoxSendLog.Text = checkBoxSendLog.Text + " [Unsupported!]";
checkBoxShareClipboard.Checked = Setting.Values.ShareClipboard;
if (!Setting.Values.ShareClipboard)
{
checkBoxTransferFile.Enabled = checkBoxTransferFile.Checked = false;
}
else
{
checkBoxTransferFile.Checked = Setting.Values.TransferFile;
}
checkBoxDisableCAD.Checked = Setting.Values.DisableCAD;
checkBoxHideLogo.Checked = Setting.Values.HideLogonLogo;
checkBoxHideMouse.Checked = Setting.Values.HideMouse;
checkBoxBlockScreenSaver.Checked = Setting.Values.BlockScreenSaver;
checkBoxMouseMoveRelatively.Checked = Setting.Values.MoveMouseRelatively;
checkBoxClipNetStatus.Checked = Setting.Values.ShowClipNetStatus;
checkBoxSendLog.Checked = Setting.Values.SendErrorLogV2;
if (Setting.Values.HotKeySwitchMachine == (int)VK.F1)
{
radioButtonF1.Checked = true;
}
else if (Setting.Values.HotKeySwitchMachine == '1')
{
radioButtonNum.Checked = true;
}
else
{
radioButtonDisable.Checked = true;
}
comboBoxShowSettings.Text = "Disable";
comboBoxExitMM.Text = Setting.Values.HotKeyExitMM == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeyExitMM });
#if OBSOLETE_SHORTCUTS
comboBoxLockMachine.Text = Setting.Values.HotKeyLockMachine == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeyLockMachine });
comboBoxReconnect.Text = Setting.Values.HotKeyReconnect == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeyReconnect });
comboBoxSwitchToAllPC.Text = Setting.Values.HotKeySwitch2AllPC == 1
? "Ctrl*3"
: Setting.Values.HotKeySwitch2AllPC == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeySwitch2AllPC });
comboBoxEasyMouseOption.Text = ((EasyMouseOption)Setting.Values.EasyMouse).ToString();
comboBoxEasyMouse.Text = Setting.Values.HotKeyToggleEasyMouse == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeyToggleEasyMouse });
#endif
// Apply policy configuration on UI elements
// Has to be the last action
if (Setting.Values.ShareClipboardIsGpoConfigured)
{
checkBoxShareClipboard.Enabled = false;
checkBoxShareClipboard.Text += " [Managed]";
// transfer file setting depends on clipboard sharing
checkBoxTransferFile.Enabled = false;
}
if (Setting.Values.TransferFileIsGpoConfigured)
{
checkBoxTransferFile.Enabled = false;
checkBoxTransferFile.Text += " [Managed]";
}
if (Setting.Values.BlockScreenSaverIsGpoConfigured)
{
checkBoxBlockScreenSaver.Enabled = false;
checkBoxBlockScreenSaver.Text += " [Managed]";
}
if (Setting.Values.SameSubNetOnlyIsGpoConfigured)
{
checkBoxSameSubNet.Enabled = false;
checkBoxSameSubNet.Text += " [Managed]";
}
if (Setting.Values.ReverseLookupIsGpoConfigured)
{
checkBoxReverseLookup.Enabled = false;
checkBoxReverseLookup.Text += " [Managed]";
}
if (Setting.Values.Name2IpIsGpoConfigured)
{
textBoxMachineName2IP.Enabled = false;
groupBoxDNS.ForeColor = Color.DimGray;
groupBoxDNS.Text += " [Managed]";
}
if (Setting.Values.Name2IpPolicyListIsGpoConfigured)
{
pictureBoxMouseWithoutBorders.Visible = false;
groupBoxName2IPPolicyList.Visible = true;
textBoxMachineName2IPPolicyList.Visible = true;
textBoxMachineName2IPPolicyList.Text = Setting.Values.Name2IpPolicyList;
}
}
private void RadioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton r = sender as RadioButton;
if (r.Checked)
{
Setting.Values.HotKeySwitchMachine = sender.Equals(radioButtonF1) ? (int)VK.F1 : sender.Equals(radioButtonNum) ? '1' : 0;
ShowUpdateMessage();
}
}
private void ComboBoxShowSettings_TextChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void ComboBoxExitMM_TextChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void ComboBoxLockMachine_TextChanged(object sender, EventArgs e)
{
#if OBSOLETE_SHORTCUTS
if (comboBoxLockMachine.Text.Contains("Disable"))
{
Setting.Values.HotKeyLockMachine = 0;
}
else if (comboBoxLockMachine.Text.Length > 0)
{
Setting.Values.HotKeyLockMachine = comboBoxLockMachine.Text[0];
}
#endif
}
private void ComboBoxSwitchToAllPC_TextChanged(object sender, EventArgs e)
{
#if OBSOLETE_SHORTCUTS
if (comboBoxSwitchToAllPC.Text.Contains("Disable"))
{
Setting.Values.HotKeySwitch2AllPC = 0;
}
else if (comboBoxSwitchToAllPC.Text.Contains("Ctrl*3"))
{
Setting.Values.HotKeySwitch2AllPC = 1;
}
else if (comboBoxSwitchToAllPC.Text.Length > 0)
{
Setting.Values.HotKeySwitch2AllPC = comboBoxSwitchToAllPC.Text[0];
}
#endif
ShowUpdateMessage();
}
private void CheckBoxHideLogo_CheckedChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void ShowUpdateMessage()
{
if (!formShown)
{
return;
}
foreach (Control c in tabPageOther.Controls)
{
if (c != groupBoxShortcuts)
{
c.Enabled = false;
}
}
foreach (Control c in groupBoxShortcuts.Controls)
{
if (c != pictureBoxMouseWithoutBorders)
{
c.Enabled = false;
}
}
for (int i = 0; i < 3; i++)
{
Application.DoEvents();
Thread.Sleep(20);
}
foreach (Control c in tabPageOther.Controls)
{
if (c != groupBoxShortcuts)
{
c.Enabled = true;
}
}
foreach (Control c in groupBoxShortcuts.Controls)
{
if (c != pictureBoxMouseWithoutBorders && c != comboBoxExitMM && c != comboBoxShowSettings && c != comboBoxScreenCapture)
{
c.Enabled = true;
}
}
}
private void CheckBoxBlockScreenSaver_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.BlockScreenSaver = checkBoxBlockScreenSaver.Checked;
ShowUpdateMessage();
}
private void ComboBoxReconnect_TextChanged(object sender, EventArgs e)
{
#if OBSOLETE_SHORTCUTS
if (comboBoxReconnect.Text.Contains("Disable"))
{
Setting.Values.HotKeyReconnect = 0;
}
else if (comboBoxReconnect.Text.Length > 0)
{
Setting.Values.HotKeyReconnect = comboBoxReconnect.Text[0];
}
#endif
ShowUpdateMessage();
}
private void CheckBoxCircle_CheckedChanged(object sender, EventArgs e)
{
if (Setting.Values.MatrixCircle != checkBoxCircle.Checked)
{
Setting.Values.MatrixCircle = checkBoxCircle.Checked;
ShowUpdateMessage();
MachineStuff.SendMachineMatrix();
}
}
private void CheckBoxBlockMouseAtCorners_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.BlockMouseAtCorners = checkBoxBlockMouseAtCorners.Checked;
ShowUpdateMessage();
}
private void CheckBoxHideMouse_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.HideMouse = checkBoxHideMouse.Checked;
ShowUpdateMessage();
}
private void ComboBoxEasyMouseOption_TextChanged(object sender, EventArgs e)
{
string selectedOption = comboBoxEasyMouseOption.Text;
int oldEasyMouseOption = Setting.Values.EasyMouse;
Setting.Values.EasyMouse = Enum.TryParse<EasyMouseOption>(selectedOption, out EasyMouseOption easyMouseOption) ? (int)easyMouseOption : (int)EasyMouseOption.Enable;
if (oldEasyMouseOption != Setting.Values.EasyMouse)
{
ShowUpdateMessage();
}
}
private void ComboBoxEasyMouse_TextChanged(object sender, EventArgs e)
{
#if OBSOLETE_SHORTCUTS
if (comboBoxEasyMouse.Text.Contains("Disable"))
{
Setting.Values.HotKeyToggleEasyMouse = 0;
}
else if (comboBoxEasyMouse.Text.Length > 0)
{
Setting.Values.HotKeyToggleEasyMouse = comboBoxEasyMouse.Text[0];
}
#endif
ShowUpdateMessage();
}
private void CheckBoxMouseMoveRelatively_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.MoveMouseRelatively = checkBoxMouseMoveRelatively.Checked;
ShowUpdateMessage();
}
private void CheckBoxDrawMouse_CheckedChanged(object sender, EventArgs e)
{
if (!(Setting.Values.DrawMouse = checkBoxDrawMouse.Checked))
{
CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);
}
ShowUpdateMessage();
}
private void CheckBoxTwoRow_CheckedChanged(object sender, EventArgs e)
{
matrixOneRow = !checkBoxTwoRow.Checked;
ArrangeMachines();
}
private void ButtonNewKey_Click(object sender, EventArgs e)
{
string message = "Do you really want to generate a new key?\r\n" +
"(You would need to enter this key in all other machines to re-establish the connections)";
if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
textBoxEnc.Text = Common.MyKey;
checkBoxShowKey.Checked = true;
Common.GeneratedKey = true;
ButtonOK_Click(null, null);
Common.ShowToolTip("New security key was generated, update other machines to the same key.", 10000, ToolTipIcon.Info, false);
}
}
private void CheckBoxClipNetStatus_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.ShowClipNetStatus = checkBoxClipNetStatus.Checked;
ShowUpdateMessage();
}
private void CheckBoxSendLog_CheckedChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void FrmMatrix_Resize(object sender, EventArgs e)
{
if (WindowState != FormWindowState.Minimized)
{
groupBoxMachineMatrix.Top = groupBoxKeySetup.Top + groupBoxKeySetup.Height + 10;
groupBoxMachineMatrix.Height = ClientSize.Height - groupBoxKeySetup.Height - (int)(buttonOK.Height * 3.5);
checkBoxTwoRow.Top = groupBoxMachineMatrix.Height - (int)(checkBoxTwoRow.Height * 1.4);
buttonOK.Top = groupBoxMachineMatrix.Bottom + (int)(buttonOK.Height * 0.3);
buttonCancel.Top = groupBoxMachineMatrix.Bottom + (int)(buttonCancel.Height * 0.3);
groupBoxShortcuts.Height = ClientSize.Height - groupBoxOtherOptions.Bottom - 40;
groupBoxDNS.Height = ClientSize.Height - pictureBoxMouseWithoutBorders.Height - textBoxDNS.Height - 70;
}
}
private void CheckBoxReverseLookup_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.ReverseLookup = checkBoxReverseLookup.Checked;
ShowUpdateMessage();
}
private void CheckBoxVKMap_CheckedChanged(object sender, EventArgs e)
{
// NOTE(@yuyoyuppe): this option is deprecated
// Setting.Values.UseVKMap = checkBoxVKMap.Checked;
ShowUpdateMessage();
}
private void LinkLabelMiniLog_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string miniLog = Common.GetMiniLog(new[] { groupBoxOtherOptions.Controls, groupBoxShortcuts.Controls });
Clipboard.SetText(miniLog);
Common.ShowToolTip("Log has been placed in the clipboard.", 30000, ToolTipIcon.Info, false);
}
private void ComboBoxScreenCapture_TextChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void LinkLabelReConfigure_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string message = "WARNING: This will clear the Computer Matrix and allows you to run the setup experience like the first time you installed the program.\r\n";
message += "You need to start this setup experience in all machines. In the next Dialog, click NO in the first machine and click YES in the rest of the machines.\r\n";
message += "And then follow the steps to complete the configuration.\r\n\r\n";
message += "Are you sure you want to continue?";
if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
{
PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersOldUIReconfigureEvent());
ButtonCancel_Click(this, new EventArgs());
Setting.Values.FirstRun = true;
Setting.Values.EasyMouse = (int)EasyMouseOption.Enable;
MachineStuff.ClearComputerMatrix();
MachineStuff.ShowSetupForm(true);
}
}
private void CheckBoxSameSubNet_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.SameSubNetOnly = checkBoxSameSubNet.Checked;
ShowUpdateMessage();
}
#if USE_TO_CREATE_LOGO_BITMAP
private void PaintMyLogo()
{
Graphics g = Graphics.FromHwnd(this.Handle);
Font font = new Font("Chiller", 40);
g.DrawString(Common.BinaryName, font, Brushes.Lime, comboBoxIPs.Right + 50, comboBoxIPs.Bottom - 5);
Bitmap b = new Bitmap(220, 100);
Graphics g2 = Graphics.FromImage(b);
g2.FillRectangle(Brushes.WhiteSmoke, 0, 0, 220, 100);
g2.DrawString(Common.BinaryName, font, Brushes.Lime, 0, 0);
b.Save("c:\\zzz.bmp");
string p = "";
Color c;
int l = 0;
for (int i = 0; i < b.Width; i++)
{
for (int j = 0; j < b.Height; j++)
{
c = b.GetPixel(i, j);
if (c.G > 0)
{
p += "{" + i + "," + j + "},";
l++;
}
}
p += "\r\n";
}
//File.WriteAllText("c:\\zzz.txt", l + ":" + p, Encoding.Unicode);
b.Dispose();
g2.Dispose();
}
#endif
}
}