frmMatrix.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Diagnostics; 7 using System.Diagnostics.CodeAnalysis; 8 using System.Drawing; 9 using System.Globalization; 10 using System.Text.RegularExpressions; 11 using System.Windows.Forms; 12 13 using Microsoft.PowerToys.Telemetry; 14 15 // <summary> 16 // Matrix/Settings form. 17 // </summary> 18 // <history> 19 // 2008 created by Truong Do (ductdo). 20 // 2009-... modified by Truong Do (TruongDo). 21 // 2023- Included in PowerToys. 22 // </history> 23 using MouseWithoutBorders.Class; 24 using MouseWithoutBorders.Core; 25 26 using Clipboard = MouseWithoutBorders.Core.Clipboard; 27 using Timer = System.Windows.Forms.Timer; 28 29 [module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#buttonOK_Click(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")] 30 [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#buttonSendHello_Click(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")] 31 [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")] 32 33 // [module: SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#ChangeUI2OneRow(System.Boolean)")] 34 [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#logoTimer_Tick(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")] 35 [module: SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#Dispose(System.Boolean)", MessageId = "logoBitmap", Justification = "Dotnet port with style preservation")] 36 [module: SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#frmMatrix_Shown(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")] 37 [module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#PaintMyLogo()", Justification = "Dotnet port with style preservation")] 38 [module: SuppressMessage("Style", "IDE1006:Naming Styles", Scope = "member", Target = "~M:MouseWithoutBorders.FrmMatrix.M_EnabledChanged(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")] 39 40 namespace MouseWithoutBorders 41 { 42 internal partial class FrmMatrix : System.Windows.Forms.Form, IDisposable 43 { 44 #pragma warning disable CA2213 // Disposing is done by ComponentResourceManager 45 private Timer helperTimer; 46 #pragma warning restore CA2213 47 private bool formShown; 48 private int formOrgHeight; 49 private bool matrixOneRow; 50 51 internal FrmMatrix() 52 { 53 InitializeComponent(); 54 55 textBoxEnc.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0); 56 57 Text = Application.ProductName + " " + Application.ProductVersion + " - Settings"; 58 toolTip.ToolTipTitle = Application.ProductName; 59 toolTipManual.ToolTipTitle = Application.ProductName; 60 labelExitMM.Text = "Exit the application, Ctrl+Alt+Shift+:"; 61 textBoxMachineName2IP.Text = Setting.Values.Name2IP; 62 } 63 64 private void ButtonCancel_Click(object sender, EventArgs e) 65 { 66 buttonCancel.Enabled = false; 67 Close(); 68 Common.MatrixForm = null; 69 } 70 71 private void ButtonOK_Click(object sender, EventArgs e) 72 { 73 buttonOK.Enabled = false; 74 75 if (!UpdateKey(Regex.Replace(textBoxEnc.Text, @"\s+", string.Empty))) 76 { 77 buttonOK.Enabled = true; 78 return; 79 } 80 81 string[] st = new string[MachineStuff.MAX_MACHINE]; 82 for (int i = 0; i < MachineStuff.MAX_MACHINE; i++) 83 { 84 if (machines[i].MachineEnabled) 85 { 86 for (int j = 0; j < i; j++) 87 { 88 if (st[j].Equals(machines[i].MachineName, StringComparison.OrdinalIgnoreCase)) 89 { 90 machines[i].MachineName = string.Empty; 91 machines[i].MachineEnabled = false; 92 } 93 } 94 95 st[i] = machines[i].MachineName; 96 } 97 else 98 { 99 st[i] = string.Empty; 100 } 101 } 102 103 MachineStuff.MachineMatrix = st; 104 Setting.Values.MatrixOneRow = matrixOneRow = !checkBoxTwoRow.Checked; 105 106 if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId()) 107 { 108 Program.StartService(); 109 Common.ShowToolTip("New settings applied on the physical console session!", 3000, ToolTipIcon.Warning, false); 110 } 111 else 112 { 113 SocketStuff.InvalidKeyFound = false; 114 showInvalidKeyMessage = false; 115 InitAndCleanup.ReopenSocketDueToReadError = true; 116 Common.ReopenSockets(true); 117 118 for (int i = 0; i < 10; i++) 119 { 120 if (Common.AtLeastOneSocketConnected()) 121 { 122 Common.MMSleep(0.5); 123 break; 124 } 125 126 Common.MMSleep(0.2); 127 } 128 129 MachineStuff.SendMachineMatrix(); 130 } 131 132 buttonOK.Enabled = true; 133 } 134 135 internal void UpdateKeyTextBox() 136 { 137 _ = Helper.GetUserName(); 138 textBoxEnc.Text = Encryption.MyKey; 139 } 140 141 private void InitAll() 142 { 143 formOrgHeight = Height; 144 matrixOneRow = Setting.Values.MatrixOneRow; 145 CreateMachines(); 146 LoadSettingsToUI(); 147 UpdateKeyTextBox(); 148 } 149 150 private void LoadMachines() 151 { 152 bool meAdded = false; 153 string machineName; 154 155 if (MachineStuff.MachineMatrix != null && MachineStuff.MachineMatrix.Length == MachineStuff.MAX_MACHINE) 156 { 157 Logger.LogDebug("LoadMachines: Machine Matrix: " + Setting.Values.MachineMatrixString); 158 159 for (int i = 0; i < MachineStuff.MAX_MACHINE; i++) 160 { 161 machineName = MachineStuff.MachineMatrix[i].Trim(); 162 machines[i].MachineName = machineName; 163 164 if (string.IsNullOrEmpty(machineName)) 165 { 166 machines[i].CheckAble = true; 167 } 168 else 169 { 170 machines[i].MachineEnabled = true; 171 } 172 173 bool found = MachineStuff.MachinePool.TryFindMachineByName(machineName, out MachineInf machineInfo); 174 if (found) 175 { 176 if (machineInfo.Id == Common.MachineID) 177 { 178 machines[i].LocalHost = true; 179 meAdded = true; 180 } 181 } 182 } 183 } 184 185 if (!meAdded) 186 { 187 foreach (Machine m in machines) 188 { 189 if (string.IsNullOrEmpty(m.MachineName)) 190 { 191 m.MachineName = Common.MachineName.Trim(); 192 m.LocalHost = true; 193 meAdded = true; 194 break; 195 } 196 } 197 } 198 } 199 200 private void CheckBoxShowKey_CheckedChanged(object sender, EventArgs e) 201 { 202 textBoxEnc.PasswordChar = checkBoxShowKey.Checked ? (char)0 : '*'; 203 } 204 205 private void FrmMatrix_Shown(object sender, EventArgs e) 206 { 207 if (Setting.Values.FirstRun) 208 { 209 Setting.Values.FirstRun = false; 210 Common.ReopenSockets(false); 211 212 /* 213 string fireWallLog = Path.GetDirectoryName(Application.ExecutablePath) + "\\FirewallError.log"; 214 215 if (File.Exists(fireWallLog)) 216 { 217 //@"http://bing.com/search?q=Allow+a+program+through+Windows+Firewall" 218 219 MessageBox.Show(Application.ProductName + " was unable to add itself to the Firewall exception list.\r\n" + 220 "The following application needs to be added to the Firewall exception list:\r\n\r\n" + 221 Application.ExecutablePath + 222 "\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.", 223 Application.ProductName, 224 MessageBoxButtons.OK, MessageBoxIcon.Error); 225 } 226 227 linkLabelHelp_LinkClicked(null, null); 228 * */ 229 } 230 231 InitAll(); 232 233 if (Setting.Values.IsMyKeyRandom) 234 { 235 Setting.Values.IsMyKeyRandom = false; 236 checkBoxShowKey.Checked = true; 237 } 238 239 if (helperTimer == null) 240 { 241 helperTimer = new Timer(); 242 helperTimer.Interval = 200; 243 helperTimer.Tick += new EventHandler(HelperTimer_Tick); 244 helperTimer.Start(); 245 } 246 247 formShown = true; 248 } 249 250 private void FrmMatrix_FormClosed(object sender, FormClosedEventArgs e) 251 { 252 /* 253 if (logoTimer != null) 254 { 255 logoTimer.Stop(); 256 logoTimer.Dispose(); 257 logoTimer = null; 258 } 259 * */ 260 261 if (helperTimer != null) 262 { 263 helperTimer.Stop(); 264 helperTimer.Dispose(); 265 helperTimer = null; 266 } 267 268 // if (logoBitmap != null) logoBitmap.Dispose(); 269 Common.MatrixForm = null; 270 } 271 272 private int pivot; 273 private Bitmap logoBitmap; 274 275 private void PaintMyLogo() 276 { 277 if (!Visible || !(tabControlSetting.SelectedTab == tabPageAdvancedSettings)) 278 { 279 return; 280 } 281 282 uint rv = 0; 283 try 284 { 285 Color c; 286 uint cl; 287 double dC; 288 logoBitmap ??= new Bitmap(pictureBoxMouseWithoutBorders0.BackgroundImage); 289 int bWidth = logoBitmap.Width; 290 int bHeight = logoBitmap.Height; 291 double dx = (double)pictureBoxMouseWithoutBorders.Width / bWidth; 292 double dy = (double)pictureBoxMouseWithoutBorders.Height / bHeight; 293 294 IntPtr hdc = NativeMethods.GetWindowDC(pictureBoxMouseWithoutBorders.Handle); 295 for (int i = 0; i < bWidth; i++) 296 { 297 for (int j = 0; j < bHeight; j++) 298 { 299 c = logoBitmap.GetPixel(i, j); 300 301 // c.G > 245 302 if (c.R < 240 && c.B < 240) 303 { 304 dC = Math.Abs(pivot - i); 305 if (bWidth - pivot + i < dC) 306 { 307 dC = bWidth - pivot + i; 308 } 309 310 if (bWidth - i + pivot < dC) 311 { 312 dC = bWidth - i + pivot; 313 } 314 315 dC /= bWidth; 316 317 // c = Color.FromArgb(80, (int)(255 - 255 * dC), 80); 318 cl = (160 << 16) | ((uint)(255 - (255 * dC)) << 8) | 160; 319 320 // Using GDI SetPixel so we dont have to assign the image later on 321 // b.SetPixel(i, j, c); 322 rv = NativeMethods.SetPixel(hdc, (int)(i * dx), (int)(j * dy), cl); 323 } 324 } 325 } 326 327 // Image im = pictureBoxMouseWithoutBorders.BackgroundImage; 328 // pictureBoxMouseWithoutBorders.BackgroundImage = b; 329 // if (im != null) im.Dispose(); 330 rv = (uint)NativeMethods.ReleaseDC(pictureBoxMouseWithoutBorders.Handle, hdc); 331 pivot = (pivot + 5) % bWidth; 332 } 333 catch (Exception ee) 334 { 335 Logger.Log(ee); 336 Logger.Log(rv.ToString(CultureInfo.CurrentCulture)); 337 } 338 } 339 340 private void AddNewMachine() 341 { 342 string newMachine; 343 Machine unUsedMachine; 344 345 foreach (MachineInf inf in MachineStuff.MachinePool.ListAllMachines()) 346 { 347 bool found = false; 348 unUsedMachine = null; 349 newMachine = inf.Name.Trim(); 350 foreach (Machine m in machines) 351 { 352 if (m.MachineName.Equals( 353 newMachine, 354 StringComparison.OrdinalIgnoreCase)) 355 { 356 found = true; 357 } 358 else if (unUsedMachine == null && string.IsNullOrEmpty(m.MachineName.Trim())) 359 { 360 unUsedMachine = m; 361 } 362 } 363 364 if (!found && unUsedMachine != null) 365 { 366 unUsedMachine.MachineName = newMachine; 367 } 368 } 369 } 370 371 private int helperTimerCounter; 372 private bool showInvalidKeyMessage; 373 374 private void HelperTimer_Tick(object sender, EventArgs e) 375 { 376 string keyNotMatchedMachines = string.Empty; 377 378 if (Setting.Values.Changed) 379 { 380 Setting.Values.Changed = false; 381 matrixOneRow = Setting.Values.MatrixOneRow; 382 LoadSettingsToUI(); 383 384 /* 385 if (!Common.InMachineMatrix(Common.MachineName)) 386 { 387 foreach (Machine m in machines) 388 { 389 if (!m.LocalHost) 390 { 391 m.MachineEnabled = false; 392 } 393 } 394 } 395 * */ 396 } 397 398 helperTimerCounter++; 399 400 // 1 sec 401 if (helperTimerCounter % 5 == 0) 402 { 403 comboBoxEasyMouseOption.Text = ((EasyMouseOption)Setting.Values.EasyMouse).ToString(); 404 405 if (!textBoxMachineName2IP.Text.Equals(Setting.Values.Name2IP, StringComparison.OrdinalIgnoreCase)) 406 { 407 Setting.Values.Name2IP = textBoxMachineName2IP.Text; 408 } 409 410 // 2 times 411 if (helperTimerCounter < 15) 412 { 413 Common.SendHello(); 414 } 415 416 AddNewMachine(); 417 } 418 419 // NOTE(@yuyoyuppe): this option is deprecated 420 // checkBoxVKMap.Checked = Setting.Values.UseVKMap; 421 foreach (Machine m in machines) 422 { 423 if (m.StatusClient != SocketStatus.NA) 424 { 425 m.StatusClient = SocketStatus.NA; 426 } 427 428 if (m.StatusServer != SocketStatus.NA) 429 { 430 m.StatusServer = SocketStatus.NA; 431 } 432 } 433 434 SocketStuff sk = Common.Sk; 435 436 if (sk != null) 437 { 438 lock (sk.TcpSocketsLock) 439 { 440 if (sk.TcpSockets != null) 441 { 442 foreach (TcpSk t in sk.TcpSockets) 443 { 444 if (t.Status == SocketStatus.InvalidKey) 445 { 446 keyNotMatchedMachines += string.Format(CultureInfo.CurrentCulture, "[{0}]", t.MachineName); 447 } 448 449 foreach (Machine m in machines) 450 { 451 if (m.MachineEnabled) 452 { 453 if (m.MachineName.Equals(t.MachineName, StringComparison.OrdinalIgnoreCase)) 454 { 455 if (t.IsClient) 456 { 457 if (t.Status > m.StatusClient) 458 { 459 m.StatusClient = t.Status; 460 } 461 } 462 else 463 { 464 if (t.Status > m.StatusServer) 465 { 466 m.StatusServer = t.Status; 467 } 468 } 469 } 470 } 471 } 472 } 473 } 474 } 475 } 476 477 if (SocketStuff.InvalidKeyFound) 478 { 479 if (!showInvalidKeyMessage) 480 { 481 showInvalidKeyMessage = true; 482 483 Common.ShowToolTip( 484 "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 " 485 + Application.ProductName + " in all machines.\r\n" + keyNotMatchedMachines + "\r\nThis version: " + FrmAbout.AssemblyVersion, 486 20000, 487 ToolTipIcon.Warning, 488 Setting.Values.ShowClipNetStatus); 489 } 490 } 491 else 492 { 493 showInvalidKeyMessage = false; 494 } 495 496 PaintMyLogo(); 497 } 498 499 private void ShowKeyErrorMsg(string msg) 500 { 501 Common.ShowToolTip(msg, 10000, ToolTipIcon.Error, false); 502 _ = textBoxEnc.Focus(); 503 textBoxEnc.SelectAll(); 504 } 505 506 private bool UpdateKey(string newKey) 507 { 508 if (!Encryption.IsKeyValid(newKey, out string rv)) 509 { 510 ShowKeyErrorMsg(rv); 511 return false; 512 } 513 514 if (!newKey.Equals(Encryption.MyKey, StringComparison.OrdinalIgnoreCase)) 515 { 516 Encryption.MyKey = newKey; 517 Encryption.GeneratedKey = false; 518 } 519 520 Encryption.MagicNumber = Encryption.Get24BitHash(Encryption.MyKey); 521 return true; 522 } 523 524 private readonly Machine[] machines = new Machine[MachineStuff.MAX_MACHINE]; 525 private Machine dragDropMachine; 526 private Machine desMachine; 527 private Machine desMachineX; 528 private Machine desMachineY; 529 private Machine oldDesMachine; 530 private Point desMachinePos; 531 private Point oldDesMachinePos; 532 533 private void CreateMachines() 534 { 535 for (int i = 0; i < MachineStuff.MAX_MACHINE; i++) 536 { 537 Machine m = new(); 538 m.MouseDown += Machine_MouseDown; 539 m.EnabledChanged += new EventHandler(M_EnabledChanged); 540 m.Parent = groupBoxMachineMatrix; 541 m.MachineEnabled = false; 542 machines[i] = m; 543 } 544 545 FrmMatrix_Resize(this, EventArgs.Empty); 546 ArrangeMachines(); 547 } 548 549 private void ArrangeMachines() 550 { 551 Height = matrixOneRow ? formOrgHeight : formOrgHeight + 60; 552 int dx = (groupBoxMachineMatrix.Width - 40) / 4; 553 int yOffset = groupBoxMachineMatrix.Height / 3; 554 555 for (int i = 0; i < MachineStuff.MAX_MACHINE; i++) 556 { 557 machines[i].Left = matrixOneRow ? 22 + (i * dx) : 22 + dx + ((i % 2) * dx); 558 machines[i].Top = matrixOneRow ? yOffset : (yOffset / 2) + (i / 2 * (machines[i].Width + 2)); 559 machines[i].Visible = true; 560 } 561 } 562 563 private void M_EnabledChanged(object sender, EventArgs e) 564 { 565 Machine m = sender as Machine; 566 567 SocketStuff sk = Common.Sk; 568 569 if (!m.MachineEnabled && sk != null) 570 { 571 lock (sk.TcpSocketsLock) 572 { 573 if (sk.TcpSockets != null) 574 { 575 foreach (TcpSk t in sk.TcpSockets) 576 { 577 if (t.MachineName != null && t.MachineName.Equals(m.MachineName.Trim(), StringComparison.OrdinalIgnoreCase)) 578 { 579 t.Status = SocketStatus.NA; 580 } 581 } 582 } 583 } 584 } 585 } 586 587 private void Machine_MouseDown(object sender, MouseEventArgs e) 588 { 589 oldDesMachine = desMachine = dragDropMachine = sender as Machine; 590 desMachinePos.X = desMachine.Left; 591 desMachinePos.Y = desMachine.Top; 592 oldDesMachinePos.X = oldDesMachine.Left; 593 oldDesMachinePos.Y = oldDesMachine.Top; 594 595 dragDropMachineOrgX = dragDropMachine.Left; 596 dragDropMachineOrgY = dragDropMachine.Top; 597 dragDropMachine.BringToFront(); 598 _ = DoDragDrop(dragDropMachine, DragDropEffects.Move); 599 } 600 601 private int startX; 602 private int startY; 603 private int dragDropMachineOrgX; 604 private int dragDropMachineOrgY; 605 606 private void Form_DragEnter(object sender, DragEventArgs e) 607 { 608 startX = e.X; 609 startY = e.Y; 610 e.Effect = DragDropEffects.Move; 611 } 612 613 private bool IsOnSameRow(Machine m1, Machine m2) 614 { 615 return matrixOneRow || (m1 == dragDropMachine ? desMachinePos.Y : m1.Top) == m2.Top; 616 } 617 618 private bool IsOnSameCol(Machine m1, Machine m2) 619 { 620 return !matrixOneRow && (m1 == dragDropMachine ? desMachinePos.X : m1.Left) == m2.Left; 621 } 622 623 private long lastMove; 624 625 private void Form_DragOver(object sender, DragEventArgs e) 626 { 627 if (dragDropMachine == null) 628 { 629 return; 630 } 631 632 e.Effect = DragDropEffects.Move; 633 634 dragDropMachine.Left = dragDropMachineOrgX + (e.X - startX); 635 dragDropMachine.Top = dragDropMachineOrgY + (e.Y - startY); 636 637 /* 638 dragDropMachine.Left = e.X - dragDropMachine.MouseDownPos.X - Left - 3 639 - groupBoxMachineMatrix.Left - tabControlSetting.Left; 640 dragDropMachine.Top = e.Y - dragDropMachine.MouseDownPos.Y - Top - 25 641 - groupBoxMachineMatrix.Top - tabControlSetting.Top; 642 * */ 643 644 if (!matrixOneRow && Common.GetTick() - lastMove < 500) 645 { 646 return; 647 } 648 649 int minX = Math.Abs(dragDropMachine.Left - desMachinePos.X); 650 int minY = Math.Abs(dragDropMachine.Top - desMachinePos.Y); 651 652 desMachineX = desMachineY = desMachine; 653 654 for (int i = 0; i < MachineStuff.MAX_MACHINE; i++) 655 { 656 if (machines[i] == dragDropMachine) 657 { 658 continue; 659 } 660 661 if (IsOnSameRow(oldDesMachine, machines[i])) 662 { 663 if (minX > Math.Abs(dragDropMachine.Left - machines[i].Left)) 664 { 665 minX = Math.Abs(dragDropMachine.Left - machines[i].Left); 666 desMachineX = machines[i]; 667 } 668 } 669 670 if (IsOnSameCol(oldDesMachine, machines[i])) 671 { 672 if (minY > Math.Abs(dragDropMachine.Top - machines[i].Top)) 673 { 674 minY = Math.Abs(dragDropMachine.Top - machines[i].Top); 675 desMachineY = machines[i]; 676 } 677 } 678 } 679 680 oldDesMachine = desMachine; 681 desMachine = desMachineY == oldDesMachine ? desMachineX : desMachineX == oldDesMachine ? desMachineY : minX < minY ? desMachineX : desMachineY; 682 683 if (desMachine != oldDesMachine) 684 { 685 oldDesMachinePos.X = desMachinePos.X; 686 desMachinePos.X = desMachine.Left; 687 688 oldDesMachinePos.Y = desMachinePos.Y; 689 desMachinePos.Y = desMachine.Top; 690 691 desMachine.Left = oldDesMachinePos.X; 692 desMachine.Top = oldDesMachinePos.Y; 693 694 desMachine = dragDropMachine; 695 696 lastMove = Common.GetTick(); 697 } 698 } 699 700 private void Form_DragDrop(object sender, DragEventArgs e) 701 { 702 if (desMachine != null) 703 { 704 dragDropMachine.Left = desMachinePos.X; 705 dragDropMachine.Top = desMachinePos.Y; 706 707 Machine tmp; 708 for (int i = 0; i < MachineStuff.MAX_MACHINE - 1; i++) 709 { 710 for (int j = 0; j < MachineStuff.MAX_MACHINE - 1 - i; j++) 711 { 712 if (machines[j + 1].Top < machines[j].Top || (machines[j + 1].Top == machines[j].Top && machines[j + 1].Left < machines[j].Left)) 713 { 714 tmp = machines[j]; 715 machines[j] = machines[j + 1]; 716 machines[j + 1] = tmp; 717 } 718 } 719 } 720 } 721 } 722 723 private void FrmMatrix_DragLeave(object sender, EventArgs e) 724 { 725 Form_DragDrop(sender, null); 726 InputSimulation.MouseUp(); 727 } 728 729 private void LoadSettingsToUI() 730 { 731 checkBoxCircle.Checked = Setting.Values.MatrixCircle; 732 checkBoxTwoRow.Checked = !matrixOneRow; 733 checkBoxBlockMouseAtCorners.Checked = Setting.Values.BlockMouseAtCorners; 734 checkBoxDrawMouse.Checked = Setting.Values.DrawMouse; 735 checkBoxReverseLookup.Checked = Setting.Values.ReverseLookup; 736 checkBoxSameSubNet.Checked = Setting.Values.SameSubNetOnly; 737 738 // NOTE(@yuyoyuppe): this option is deprecated 739 // checkBoxVKMap.Checked = Setting.Values.UseVKMap; 740 foreach (Machine m in machines) 741 { 742 m.MachineName = string.Empty; 743 m.MachineEnabled = false; 744 m.LocalHost = false; 745 } 746 747 LoadMachines(); 748 } 749 750 internal static readonly string[] Separator = new string[] { "\r\n" }; 751 752 internal void ShowTip(ToolTipIcon icon, string text, int duration) 753 { 754 int x = 0; 755 text += "\r\n "; 756 int y = (-text.Split(Separator, StringSplitOptions.None).Length * 15) - 30; 757 758 toolTipManual.Hide(this); 759 760 toolTipManual.ToolTipIcon = icon; 761 toolTipManual.Show(text, this, x, y, duration); 762 } 763 764 private void LinkLabelHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 765 { 766 linkLabelHelp.Enabled = false; 767 linkLabelHelp.Enabled = true; 768 } 769 770 private void CheckBoxShareClipboard_CheckedChanged(object sender, EventArgs e) 771 { 772 Setting.Values.ShareClipboard = checkBoxShareClipboard.Checked; 773 774 checkBoxTransferFile.Enabled = checkBoxTransferFile.Checked = Setting.Values.ShareClipboard; 775 776 ShowUpdateMessage(); 777 } 778 779 private void CheckBoxTransferFile_CheckedChanged(object sender, EventArgs e) 780 { 781 Setting.Values.TransferFile = checkBoxTransferFile.Checked; 782 783 ShowUpdateMessage(); 784 785 Clipboard.HasSwitchedMachineSinceLastCopy = true; 786 } 787 788 private void CheckBoxDisableCAD_CheckedChanged(object sender, EventArgs e) 789 { 790 if (!Common.RunWithNoAdminRight) 791 { 792 Helper.ApplyCADSetting(); 793 ShowUpdateMessage(); 794 } 795 } 796 797 private void FrmMatrix_Load(object sender, EventArgs e) 798 { 799 if (Common.RunWithNoAdminRight) 800 { 801 checkBoxDisableCAD.Enabled = false; 802 checkBoxHideLogo.Enabled = false; 803 } 804 805 // Note(@htcfreek): Disable checkboxes of settings that we don't support in the PowerToys implementation 806 checkBoxDisableCAD.Enabled = false; 807 checkBoxDisableCAD.Text = checkBoxDisableCAD.Text + " [Unsupported!]"; 808 checkBoxHideLogo.Enabled = false; 809 checkBoxHideLogo.Text = checkBoxHideLogo.Text + " [Unsupported!]"; 810 checkBoxSendLog.Enabled = false; 811 checkBoxSendLog.Text = checkBoxSendLog.Text + " [Unsupported!]"; 812 813 checkBoxShareClipboard.Checked = Setting.Values.ShareClipboard; 814 815 if (!Setting.Values.ShareClipboard) 816 { 817 checkBoxTransferFile.Enabled = checkBoxTransferFile.Checked = false; 818 } 819 else 820 { 821 checkBoxTransferFile.Checked = Setting.Values.TransferFile; 822 } 823 824 checkBoxDisableCAD.Checked = Setting.Values.DisableCAD; 825 checkBoxHideLogo.Checked = Setting.Values.HideLogonLogo; 826 checkBoxHideMouse.Checked = Setting.Values.HideMouse; 827 checkBoxBlockScreenSaver.Checked = Setting.Values.BlockScreenSaver; 828 checkBoxMouseMoveRelatively.Checked = Setting.Values.MoveMouseRelatively; 829 checkBoxClipNetStatus.Checked = Setting.Values.ShowClipNetStatus; 830 checkBoxSendLog.Checked = Setting.Values.SendErrorLogV2; 831 832 if (Setting.Values.HotKeySwitchMachine == (int)VK.F1) 833 { 834 radioButtonF1.Checked = true; 835 } 836 else if (Setting.Values.HotKeySwitchMachine == '1') 837 { 838 radioButtonNum.Checked = true; 839 } 840 else 841 { 842 radioButtonDisable.Checked = true; 843 } 844 845 comboBoxShowSettings.Text = "Disable"; 846 847 comboBoxExitMM.Text = Setting.Values.HotKeyExitMM == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeyExitMM }); 848 #if OBSOLETE_SHORTCUTS 849 comboBoxLockMachine.Text = Setting.Values.HotKeyLockMachine == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeyLockMachine }); 850 851 comboBoxReconnect.Text = Setting.Values.HotKeyReconnect == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeyReconnect }); 852 853 comboBoxSwitchToAllPC.Text = Setting.Values.HotKeySwitch2AllPC == 1 854 ? "Ctrl*3" 855 : Setting.Values.HotKeySwitch2AllPC == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeySwitch2AllPC }); 856 857 comboBoxEasyMouseOption.Text = ((EasyMouseOption)Setting.Values.EasyMouse).ToString(); 858 859 comboBoxEasyMouse.Text = Setting.Values.HotKeyToggleEasyMouse == 0 ? "Disable" : new string(new char[] { (char)Setting.Values.HotKeyToggleEasyMouse }); 860 #endif 861 862 // Apply policy configuration on UI elements 863 // Has to be the last action 864 if (Setting.Values.ShareClipboardIsGpoConfigured) 865 { 866 checkBoxShareClipboard.Enabled = false; 867 checkBoxShareClipboard.Text += " [Managed]"; 868 869 // transfer file setting depends on clipboard sharing 870 checkBoxTransferFile.Enabled = false; 871 } 872 873 if (Setting.Values.TransferFileIsGpoConfigured) 874 { 875 checkBoxTransferFile.Enabled = false; 876 checkBoxTransferFile.Text += " [Managed]"; 877 } 878 879 if (Setting.Values.BlockScreenSaverIsGpoConfigured) 880 { 881 checkBoxBlockScreenSaver.Enabled = false; 882 checkBoxBlockScreenSaver.Text += " [Managed]"; 883 } 884 885 if (Setting.Values.SameSubNetOnlyIsGpoConfigured) 886 { 887 checkBoxSameSubNet.Enabled = false; 888 checkBoxSameSubNet.Text += " [Managed]"; 889 } 890 891 if (Setting.Values.ReverseLookupIsGpoConfigured) 892 { 893 checkBoxReverseLookup.Enabled = false; 894 checkBoxReverseLookup.Text += " [Managed]"; 895 } 896 897 if (Setting.Values.Name2IpIsGpoConfigured) 898 { 899 textBoxMachineName2IP.Enabled = false; 900 groupBoxDNS.ForeColor = Color.DimGray; 901 groupBoxDNS.Text += " [Managed]"; 902 } 903 904 if (Setting.Values.Name2IpPolicyListIsGpoConfigured) 905 { 906 pictureBoxMouseWithoutBorders.Visible = false; 907 groupBoxName2IPPolicyList.Visible = true; 908 textBoxMachineName2IPPolicyList.Visible = true; 909 textBoxMachineName2IPPolicyList.Text = Setting.Values.Name2IpPolicyList; 910 } 911 } 912 913 private void RadioButton_CheckedChanged(object sender, EventArgs e) 914 { 915 RadioButton r = sender as RadioButton; 916 917 if (r.Checked) 918 { 919 Setting.Values.HotKeySwitchMachine = sender.Equals(radioButtonF1) ? (int)VK.F1 : sender.Equals(radioButtonNum) ? '1' : 0; 920 921 ShowUpdateMessage(); 922 } 923 } 924 925 private void ComboBoxShowSettings_TextChanged(object sender, EventArgs e) 926 { 927 ShowUpdateMessage(); 928 } 929 930 private void ComboBoxExitMM_TextChanged(object sender, EventArgs e) 931 { 932 ShowUpdateMessage(); 933 } 934 935 private void ComboBoxLockMachine_TextChanged(object sender, EventArgs e) 936 { 937 #if OBSOLETE_SHORTCUTS 938 if (comboBoxLockMachine.Text.Contains("Disable")) 939 { 940 Setting.Values.HotKeyLockMachine = 0; 941 } 942 else if (comboBoxLockMachine.Text.Length > 0) 943 { 944 Setting.Values.HotKeyLockMachine = comboBoxLockMachine.Text[0]; 945 } 946 #endif 947 } 948 949 private void ComboBoxSwitchToAllPC_TextChanged(object sender, EventArgs e) 950 { 951 #if OBSOLETE_SHORTCUTS 952 if (comboBoxSwitchToAllPC.Text.Contains("Disable")) 953 { 954 Setting.Values.HotKeySwitch2AllPC = 0; 955 } 956 else if (comboBoxSwitchToAllPC.Text.Contains("Ctrl*3")) 957 { 958 Setting.Values.HotKeySwitch2AllPC = 1; 959 } 960 else if (comboBoxSwitchToAllPC.Text.Length > 0) 961 { 962 Setting.Values.HotKeySwitch2AllPC = comboBoxSwitchToAllPC.Text[0]; 963 } 964 #endif 965 ShowUpdateMessage(); 966 } 967 968 private void CheckBoxHideLogo_CheckedChanged(object sender, EventArgs e) 969 { 970 ShowUpdateMessage(); 971 } 972 973 private void ShowUpdateMessage() 974 { 975 if (!formShown) 976 { 977 return; 978 } 979 980 foreach (Control c in tabPageOther.Controls) 981 { 982 if (c != groupBoxShortcuts) 983 { 984 c.Enabled = false; 985 } 986 } 987 988 foreach (Control c in groupBoxShortcuts.Controls) 989 { 990 if (c != pictureBoxMouseWithoutBorders) 991 { 992 c.Enabled = false; 993 } 994 } 995 996 for (int i = 0; i < 3; i++) 997 { 998 Application.DoEvents(); 999 Thread.Sleep(20); 1000 } 1001 1002 foreach (Control c in tabPageOther.Controls) 1003 { 1004 if (c != groupBoxShortcuts) 1005 { 1006 c.Enabled = true; 1007 } 1008 } 1009 1010 foreach (Control c in groupBoxShortcuts.Controls) 1011 { 1012 if (c != pictureBoxMouseWithoutBorders && c != comboBoxExitMM && c != comboBoxShowSettings && c != comboBoxScreenCapture) 1013 { 1014 c.Enabled = true; 1015 } 1016 } 1017 } 1018 1019 private void CheckBoxBlockScreenSaver_CheckedChanged(object sender, EventArgs e) 1020 { 1021 Setting.Values.BlockScreenSaver = checkBoxBlockScreenSaver.Checked; 1022 ShowUpdateMessage(); 1023 } 1024 1025 private void ComboBoxReconnect_TextChanged(object sender, EventArgs e) 1026 { 1027 #if OBSOLETE_SHORTCUTS 1028 if (comboBoxReconnect.Text.Contains("Disable")) 1029 { 1030 Setting.Values.HotKeyReconnect = 0; 1031 } 1032 else if (comboBoxReconnect.Text.Length > 0) 1033 { 1034 Setting.Values.HotKeyReconnect = comboBoxReconnect.Text[0]; 1035 } 1036 #endif 1037 ShowUpdateMessage(); 1038 } 1039 1040 private void CheckBoxCircle_CheckedChanged(object sender, EventArgs e) 1041 { 1042 if (Setting.Values.MatrixCircle != checkBoxCircle.Checked) 1043 { 1044 Setting.Values.MatrixCircle = checkBoxCircle.Checked; 1045 ShowUpdateMessage(); 1046 MachineStuff.SendMachineMatrix(); 1047 } 1048 } 1049 1050 private void CheckBoxBlockMouseAtCorners_CheckedChanged(object sender, EventArgs e) 1051 { 1052 Setting.Values.BlockMouseAtCorners = checkBoxBlockMouseAtCorners.Checked; 1053 ShowUpdateMessage(); 1054 } 1055 1056 private void CheckBoxHideMouse_CheckedChanged(object sender, EventArgs e) 1057 { 1058 Setting.Values.HideMouse = checkBoxHideMouse.Checked; 1059 ShowUpdateMessage(); 1060 } 1061 1062 private void ComboBoxEasyMouseOption_TextChanged(object sender, EventArgs e) 1063 { 1064 string selectedOption = comboBoxEasyMouseOption.Text; 1065 int oldEasyMouseOption = Setting.Values.EasyMouse; 1066 1067 Setting.Values.EasyMouse = Enum.TryParse<EasyMouseOption>(selectedOption, out EasyMouseOption easyMouseOption) ? (int)easyMouseOption : (int)EasyMouseOption.Enable; 1068 1069 if (oldEasyMouseOption != Setting.Values.EasyMouse) 1070 { 1071 ShowUpdateMessage(); 1072 } 1073 } 1074 1075 private void ComboBoxEasyMouse_TextChanged(object sender, EventArgs e) 1076 { 1077 #if OBSOLETE_SHORTCUTS 1078 if (comboBoxEasyMouse.Text.Contains("Disable")) 1079 { 1080 Setting.Values.HotKeyToggleEasyMouse = 0; 1081 } 1082 else if (comboBoxEasyMouse.Text.Length > 0) 1083 { 1084 Setting.Values.HotKeyToggleEasyMouse = comboBoxEasyMouse.Text[0]; 1085 } 1086 #endif 1087 ShowUpdateMessage(); 1088 } 1089 1090 private void CheckBoxMouseMoveRelatively_CheckedChanged(object sender, EventArgs e) 1091 { 1092 Setting.Values.MoveMouseRelatively = checkBoxMouseMoveRelatively.Checked; 1093 ShowUpdateMessage(); 1094 } 1095 1096 private void CheckBoxDrawMouse_CheckedChanged(object sender, EventArgs e) 1097 { 1098 if (!(Setting.Values.DrawMouse = checkBoxDrawMouse.Checked)) 1099 { 1100 CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue); 1101 } 1102 1103 ShowUpdateMessage(); 1104 } 1105 1106 private void CheckBoxTwoRow_CheckedChanged(object sender, EventArgs e) 1107 { 1108 matrixOneRow = !checkBoxTwoRow.Checked; 1109 ArrangeMachines(); 1110 } 1111 1112 private void ButtonNewKey_Click(object sender, EventArgs e) 1113 { 1114 string message = "Do you really want to generate a new key?\r\n" + 1115 "(You would need to enter this key in all other machines to re-establish the connections)"; 1116 1117 if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) 1118 { 1119 Setting.Values.MyKey = Encryption.MyKey = Encryption.CreateRandomKey(); 1120 textBoxEnc.Text = Encryption.MyKey; 1121 checkBoxShowKey.Checked = true; 1122 Encryption.GeneratedKey = true; 1123 ButtonOK_Click(null, null); 1124 Common.ShowToolTip("New security key was generated, update other machines to the same key.", 10000, ToolTipIcon.Info, false); 1125 } 1126 } 1127 1128 private void CheckBoxClipNetStatus_CheckedChanged(object sender, EventArgs e) 1129 { 1130 Setting.Values.ShowClipNetStatus = checkBoxClipNetStatus.Checked; 1131 ShowUpdateMessage(); 1132 } 1133 1134 private void CheckBoxSendLog_CheckedChanged(object sender, EventArgs e) 1135 { 1136 ShowUpdateMessage(); 1137 } 1138 1139 private void FrmMatrix_Resize(object sender, EventArgs e) 1140 { 1141 if (WindowState != FormWindowState.Minimized) 1142 { 1143 groupBoxMachineMatrix.Top = groupBoxKeySetup.Top + groupBoxKeySetup.Height + 10; 1144 groupBoxMachineMatrix.Height = ClientSize.Height - groupBoxKeySetup.Height - (int)(buttonOK.Height * 3.5); 1145 checkBoxTwoRow.Top = groupBoxMachineMatrix.Height - (int)(checkBoxTwoRow.Height * 1.4); 1146 buttonOK.Top = groupBoxMachineMatrix.Bottom + (int)(buttonOK.Height * 0.3); 1147 buttonCancel.Top = groupBoxMachineMatrix.Bottom + (int)(buttonCancel.Height * 0.3); 1148 groupBoxShortcuts.Height = ClientSize.Height - groupBoxOtherOptions.Bottom - 40; 1149 groupBoxDNS.Height = ClientSize.Height - pictureBoxMouseWithoutBorders.Height - textBoxDNS.Height - 70; 1150 } 1151 } 1152 1153 private void CheckBoxReverseLookup_CheckedChanged(object sender, EventArgs e) 1154 { 1155 Setting.Values.ReverseLookup = checkBoxReverseLookup.Checked; 1156 ShowUpdateMessage(); 1157 } 1158 1159 private void CheckBoxVKMap_CheckedChanged(object sender, EventArgs e) 1160 { 1161 // NOTE(@yuyoyuppe): this option is deprecated 1162 // Setting.Values.UseVKMap = checkBoxVKMap.Checked; 1163 ShowUpdateMessage(); 1164 } 1165 1166 private void LinkLabelMiniLog_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 1167 { 1168 string miniLog = Helper.GetMiniLog(new[] { groupBoxOtherOptions.Controls, groupBoxShortcuts.Controls }); 1169 1170 Clipboard.SetText(miniLog); 1171 Common.ShowToolTip("Log has been placed in the clipboard.", 30000, ToolTipIcon.Info, false); 1172 } 1173 1174 private void ComboBoxScreenCapture_TextChanged(object sender, EventArgs e) 1175 { 1176 ShowUpdateMessage(); 1177 } 1178 1179 private void LinkLabelReConfigure_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 1180 { 1181 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"; 1182 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"; 1183 message += "And then follow the steps to complete the configuration.\r\n\r\n"; 1184 message += "Are you sure you want to continue?"; 1185 1186 if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes) 1187 { 1188 PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersOldUIReconfigureEvent()); 1189 ButtonCancel_Click(this, new EventArgs()); 1190 Setting.Values.FirstRun = true; 1191 Setting.Values.EasyMouse = (int)EasyMouseOption.Enable; 1192 MachineStuff.ClearComputerMatrix(); 1193 MachineStuff.ShowSetupForm(true); 1194 } 1195 } 1196 1197 private void CheckBoxSameSubNet_CheckedChanged(object sender, EventArgs e) 1198 { 1199 Setting.Values.SameSubNetOnly = checkBoxSameSubNet.Checked; 1200 ShowUpdateMessage(); 1201 } 1202 1203 #if USE_TO_CREATE_LOGO_BITMAP 1204 private void PaintMyLogo() 1205 { 1206 Graphics g = Graphics.FromHwnd(this.Handle); 1207 Font font = new Font("Chiller", 40); 1208 g.DrawString(Common.BinaryName, font, Brushes.Lime, comboBoxIPs.Right + 50, comboBoxIPs.Bottom - 5); 1209 1210 Bitmap b = new Bitmap(220, 100); 1211 Graphics g2 = Graphics.FromImage(b); 1212 g2.FillRectangle(Brushes.WhiteSmoke, 0, 0, 220, 100); 1213 g2.DrawString(Common.BinaryName, font, Brushes.Lime, 0, 0); 1214 b.Save("c:\\zzz.bmp"); 1215 string p = ""; 1216 Color c; 1217 int l = 0; 1218 for (int i = 0; i < b.Width; i++) 1219 { 1220 for (int j = 0; j < b.Height; j++) 1221 { 1222 c = b.GetPixel(i, j); 1223 if (c.G > 0) 1224 { 1225 p += "{" + i + "," + j + "},"; 1226 l++; 1227 } 1228 } 1229 p += "\r\n"; 1230 } 1231 //File.WriteAllText("c:\\zzz.txt", l + ":" + p, Encoding.Unicode); 1232 b.Dispose(); 1233 g2.Dispose(); 1234 } 1235 #endif 1236 } 1237 }