using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Threading.Tasks; using System.Windows.Forms; using Windows; using Gma.System.MouseKeyHook; namespace Widow { public partial class RuleEditForm : Form { #region Public Enums, Properties and Fields public Windows.Windows Windows { get; } public MainForm Form { get; set; } public DrawOverlayForm DrawOverlayForm { get; set; } public IKeyboardMouseEvents GlobalMouseHook { get; set; } #endregion #region Constructors, Destructors and Finalizers public RuleEditForm(MainForm mainForm, Windows.Windows windows) : this(windows) { Form = mainForm; Form.WindowCreated += Form_WindowCreated; Form.WindowDestroyed += Form_WindowDestroyed; } public RuleEditForm(Windows.Windows windows) : this() { Windows = windows; foreach (var window in windows.Window) { windowRulesListBox.Items.Add(window); } } private RuleEditForm() { InitializeComponent(); desktopWindowsListBox.DisplayMember = nameof(Window.Title); desktopWindowsListBox.SetDoubleBuffered(); windowRulesListBox.DisplayMember = nameof(Window.Title); windowRulesListBox.SetDoubleBuffered(); Task.Run(RefreshWindows); } /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && components != null) { Form.WindowCreated -= Form_WindowCreated; Form.WindowDestroyed -= Form_WindowDestroyed; components.Dispose(); } base.Dispose(disposing); } #endregion #region Event Handlers private void Form_WindowDestroyed(object sender, WindowDestroyedEventArgs e) { if (string.IsNullOrEmpty(e.Title)) { return; } var indices = new List(); for (var i = 0; i < desktopWindowsListBox.Items.Count; ++i) { if (((Window) desktopWindowsListBox.Items[i]).Title == e.Title) { indices.Add(i); } } foreach (var index in indices) { desktopWindowsListBox.Items.RemoveAt(index); } } private void Form_WindowCreated(object sender, WindowCreatedEventArgs e) { if (string.IsNullOrEmpty(e.Title)) { return; } var found = false; foreach (var window in desktopWindowsListBox.Items) { if (((Window) window).Title == e.Title) { found = true; break; } } if (found) { return; } if (!Natives.GetWindowRect(e.Handle, out var rect)) { return; } var process = Helpers.GetProcessName(e.Handle); if (string.IsNullOrEmpty(process)) { return; } var newWindow = new Window(process, e.Title, rect.Top, rect.Left, rect.Right - rect.Left, rect.Bottom - rect.Top); desktopWindowsListBox.Items.Add(newWindow); } private void WindowRulesListBox_SelectedIndexChanged(object sender, EventArgs e) { var listBox = (ListBox) sender; if (listBox.SelectedIndex == -1) { WindowTitle.Text = string.Empty; ignoreLeftCheckBox.Checked = false; WindowLeft.Text = string.Empty; ignoreTopCheckBox.Checked = false; WindowTop.Text = string.Empty; ignoreWidthCheckBox.Checked = false; WindowWidth.Text = string.Empty; ignoreHeightCheckBox.Checked = false; WindowHeight.Text = string.Empty; return; } var window = (Window) listBox.SelectedItem; if (window == null) { return; } WindowTitle.Text = window.Title; ignoreLeftCheckBox.Checked = window.IgnoreLeft; WindowLeft.Text = window.Left.ToString(); ignoreTopCheckBox.Checked = window.IgnoreTop; WindowTop.Text = window.Top.ToString(); ignoreWidthCheckBox.Checked = window.IgnoreWidth; WindowWidth.Text = window.Width.ToString(); ignoreHeightCheckBox.Checked = window.IgnoreHeight; WindowHeight.Text = window.Height.ToString(); } private void RefreshButton_Click(object sender, EventArgs e) { Task.Run(RefreshWindows); } private void RemoveButton_Click(object sender, EventArgs e) { var window = (Window) windowRulesListBox.SelectedItem; if (window == null) { return; } var index = -1; for (var i = 0; i < windowRulesListBox.Items.Count; ++i) { if (((Window) windowRulesListBox.Items[i]).Title != window.Title) { continue; } index = i; break; } if (index == -1) { return; } windowRulesListBox.Items.RemoveAt(index); Windows.Window.Remove(window); } private void AddButton_Click(object sender, EventArgs e) { var window = (Window) desktopWindowsListBox.SelectedItem; if (window == null) { return; } var found = false; foreach (var windowRule in windowRulesListBox.Items) { if (((Window) windowRule).Title != window.Title) { continue; } found = true; break; } if (found) { return; } windowRulesListBox.Items.Add(window); Windows.Window.Add(window); } private void OnWindowSettings_TextChanged(object sender, EventArgs e) { var selectedWindow = (Window) windowRulesListBox.SelectedItem; if (selectedWindow == null) { WindowTitle.Text = string.Empty; WindowLeft.Text = string.Empty; WindowTop.Text = string.Empty; WindowWidth.Text = string.Empty; WindowHeight.Text = string.Empty; return; } var textBox = (TextBox) sender; switch (textBox.Name) { case nameof(WindowTitle): selectedWindow.Title = textBox.Text; break; case nameof(WindowLeft): if (int.TryParse(textBox.Text, out var left)) { selectedWindow.Left = left; } break; case nameof(WindowTop): if (int.TryParse(textBox.Text, out var top)) { selectedWindow.Top = top; } break; case nameof(WindowWidth): if (int.TryParse(textBox.Text, out var width)) { selectedWindow.Width = width; } break; case nameof(WindowHeight): if (int.TryParse(textBox.Text, out var height)) { selectedWindow.Height = height; } break; } } private void OnIgnoreWindowSettings_CheckedChanged(object sender, EventArgs e) { var selectedWindow = (Window) windowRulesListBox.SelectedItem; if (selectedWindow == null) { ignoreLeftCheckBox.Checked = false; ignoreTopCheckBox.Checked = false; ignoreWidthCheckBox.Checked = false; ignoreHeightCheckBox.Checked = false; return; } var checkBox = (CheckBox) sender; switch (checkBox.Name) { case nameof(ignoreHeightCheckBox): selectedWindow.IgnoreHeight = checkBox.Checked; break; case nameof(ignoreWidthCheckBox): selectedWindow.IgnoreWidth = checkBox.Checked; break; case nameof(ignoreTopCheckBox): selectedWindow.IgnoreTop = checkBox.Checked; break; case nameof(ignoreLeftCheckBox): selectedWindow.IgnoreLeft = checkBox.Checked; break; } } private void DrawButton_Click(object sender, EventArgs e) { var selectedWindow = (Window) windowRulesListBox.SelectedItem; if (selectedWindow == null) { return; } if (DrawOverlayForm != null) { return; } DrawOverlayForm = new DrawOverlayForm(); DrawOverlayForm.WindowDrawn += DrawOverlayForm_WindowDrawn; DrawOverlayForm.Closed += DrawOverlayForm_Closed; DrawOverlayForm.Show(); } private void DrawOverlayForm_WindowDrawn(object sender, WindowDrawnEventArgs e) { var selectedWindow = (Window) windowRulesListBox.SelectedItem; if (selectedWindow == null) { return; } WindowLeft.Text = e.Left.ToString(); WindowTop.Text = e.Top.ToString(); WindowWidth.Text = e.Width.ToString(); WindowHeight.Text = e.Height.ToString(); selectedWindow.Left = e.Left; selectedWindow.Top = e.Top; selectedWindow.Width = e.Width; selectedWindow.Height = e.Height; } private void DrawOverlayForm_Closed(object sender, EventArgs e) { DrawOverlayForm.Closed -= DrawOverlayForm_Closed; DrawOverlayForm.WindowDrawn -= DrawOverlayForm_WindowDrawn; DrawOverlayForm.Dispose(); DrawOverlayForm = null; } private void PickButton_Click(object sender, EventArgs e) { // Start global mouse key hook. GlobalMouseHook = Hook.GlobalEvents(); GlobalMouseHook.MouseClick += GlobalMouseHook_MouseClick; // Set cross cursor. foreach (var cursor in Enum.GetValues(typeof(Natives.OCR_SYSTEM_CURSORS))) { Natives.SetSystemCursor( Natives.CopyIcon(Natives.LoadCursor(IntPtr.Zero, (int) Natives.OCR_SYSTEM_CURSORS.OCR_CROSS)), (uint) cursor); } } private void GlobalMouseHook_MouseClick(object sender, MouseEventArgs e) { var hWnd = Natives.WindowFromPoint(new Point(e.X, e.Y)); Natives.GetWindowThreadProcessId(hWnd, out var pid); Process process; try { process = Process.GetProcessById((int) pid); } catch { return; } var windowTitle = Helpers.GetWindowTitle(process.MainWindowHandle); if (string.IsNullOrEmpty(windowTitle)) { return; } var windowClass = Helpers.GetWindowClass(process.MainWindowHandle); if (string.IsNullOrEmpty(windowClass)) { return; } if (!Natives.GetWindowRect(process.MainWindowHandle, out var rect)) { return; } var window = new Window(windowClass, windowTitle, rect.Top, rect.Left, rect.Right - rect.Left, rect.Bottom - rect.Top); var found = false; foreach (var windowRule in windowRulesListBox.Items) { if (((Window) windowRule).Title != window.Title) { continue; } found = true; break; } if (found) { return; } windowRulesListBox.Items.Add(window); Windows.Window.Add(window); // Revert cursor. Natives.SystemParametersInfo(0x0057, 0, null, 0); // Remove global mouse key hook. GlobalMouseHook.MouseClick -= GlobalMouseHook_MouseClick; GlobalMouseHook.Dispose(); GlobalMouseHook = null; } #endregion #region Private Methods private void RefreshWindows() { foreach (var handle in Helpers.FindWindows((wnd, param) => true)) { var windowTitle = Helpers.GetWindowTitle(handle); if (string.IsNullOrEmpty(windowTitle)) { continue; } var windowClass = Helpers.GetWindowClass(handle); if (string.IsNullOrEmpty(windowClass)) { continue; } if (!Natives.GetWindowRect(handle, out var rect)) { continue; } var window = new Window(windowClass, windowTitle, rect.Top, rect.Left, rect.Right - rect.Left, rect.Bottom - rect.Top); this.InvokeIfRequired(form => { var found = false; foreach (var item in desktopWindowsListBox.Items) { if (((Window) item).Title != window.Title) { continue; } found = true; break; } if (!found) { desktopWindowsListBox.Items.Add(window); } }); } } #endregion } }