Widow – Rev 18
?pathlinks?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using Windows;
using Widow.Properties;
namespace Widow
{
public class WindowManipulation : IDisposable
{
#region Public Enums, Properties and Fields
public bool OnWindowCreate { get; set; }
public int ApplyEveryTime { get; set; }
public bool ApplyEveryTimeEnabled { get; set; }
#endregion
#region Private Delegates, Events, Enums, Properties, Indexers and Fields
private MainForm Form { get; }
private Windows.Windows WindowsToManipulate { get; set; }
private CancellationTokenSource CancellationTokenSource { get; set; }
private Task ApplyEveryTask { get; }
private BufferBlock<WindowModification> WindowsBufferBlock { get; }
private ActionBlock<WindowModification> WindowsActionBlock { get; }
private IDisposable WindowsLink { get; set; }
#endregion
#region Constructors, Destructors and Finalizers
public WindowManipulation()
{
CancellationTokenSource = new CancellationTokenSource();
WindowsBufferBlock = new BufferBlock<WindowModification>();
WindowsActionBlock = new ActionBlock<WindowModification>(ManipulateWindows);
WindowsLink = WindowsBufferBlock.LinkTo(WindowsActionBlock);
ApplyEveryTask = ApplyEvery(CancellationTokenSource.Token);
}
public WindowManipulation(MainForm mainForm) : this()
{
Form = mainForm;
Form.WindowCreated += Form_WindowCreated;
}
public WindowManipulation(Settings settings, MainForm mainForm) : this(mainForm)
{
OnWindowCreate = settings.OnWindowCreate;
ApplyEveryTimeEnabled = settings.ApplyEveryTimeEnabled;
if (int.TryParse(settings.ApplyEveryTime, out var time))
{
ApplyEveryTime = time;
}
}
public void Dispose()
{
WindowsLink?.Dispose();
WindowsLink = null;
Form.WindowCreated -= Form_WindowCreated;
CancellationTokenSource.Cancel();
ApplyEveryTask.Wait();
CancellationTokenSource.Dispose();
CancellationTokenSource = null;
}
#endregion
#region Event Handlers
private async void Form_WindowCreated(object sender, WindowCreatedEventArgs e)
{
if (!OnWindowCreate)
{
return;
}
if (WindowsToManipulate == null)
{
return;
}
var @class = Helpers.GetWindowClass(e.Handle);
if (!WindowsToManipulate.TryGetWindow(new WindowHash(e.Title, @class), out _))
{
return;
}
await Apply();
}
#endregion
#region Public Methods
public void AddWindows(Windows.Windows windows)
{
WindowsToManipulate = windows;
}
public async Task Apply()
{
if (WindowsToManipulate == null)
{
return;
}
var windows = new List<WindowModification>();
foreach (var hWnd in Helpers.FindWindows((wnd, param) => true))
{
var windowTitle = Helpers.GetWindowTitle(hWnd);
if (string.IsNullOrEmpty(windowTitle))
{
continue;
}
var windowClass = Helpers.GetWindowClass(hWnd);
if (string.IsNullOrEmpty(windowClass))
{
continue;
}
var windowHash = new WindowHash(windowTitle, windowClass);
if (!WindowsToManipulate.TryGetWindow(windowHash, out var window))
{
continue;
}
windows.Add(new WindowModification(hWnd, window));
}
await Task.WhenAll(windows.Select(modification => WindowsBufferBlock.SendAsync(modification)));
}
#endregion
#region Private Methods
private static void ManipulateWindows(WindowModification modification)
{
if (modification.Handle == IntPtr.Zero)
{
return;
}
if (!Natives.GetWindowRect(modification.Handle, out var rect))
{
return;
}
var left = modification.Window.Left;
if (modification.Window.IgnoreLeft)
{
left = rect.Left;
}
var top = modification.Window.Top;
if (modification.Window.IgnoreTop)
{
top = rect.Top;
}
var width = modification.Window.Width;
if (modification.Window.IgnoreWidth)
{
width = rect.Left - rect.Right;
}
var height = modification.Window.Height;
if (modification.Window.IgnoreHeight)
{
height = rect.Top - rect.Bottom;
}
Natives.MoveWindow(modification.Handle, left, top, width, height, true);
}
private async Task ApplyEvery(CancellationToken cancellationToken)
{
do
{
if (!ApplyEveryTimeEnabled)
{
await Task.Delay(1000, cancellationToken);
continue;
}
await Task.Delay(ApplyEveryTime, cancellationToken);
await Apply();
} while (!cancellationToken.IsCancellationRequested);
}
#endregion
}
}
Generated by GNU Enscript 1.6.5.90.