/trunk/Widow/Helpers.cs |
@@ -48,26 +48,13 @@ |
return windows; |
} |
|
public static IEnumerable<IntPtr> EnumerateWindows() |
public static string GetWindowClass(IntPtr hWnd) |
{ |
var windows = new List<IntPtr>(); |
|
Natives.EnumWindows(delegate(IntPtr wnd, IntPtr param) |
{ |
windows.Add(wnd); |
return true; |
}, IntPtr.Zero); |
|
return windows; |
var windowClass = new StringBuilder(256); |
Natives.GetClassName(hWnd, windowClass, windowClass.Capacity); |
return windowClass.ToString(); |
} |
|
/// <summary> Find all windows that contain the given title text </summary> |
/// <param name="titleText"> The text that the window title must contain. </param> |
public static IEnumerable<IntPtr> FindWindowsWithText(string titleText) |
{ |
return FindWindows((wnd, param) => GetWindowText(wnd).Contains(titleText)); |
} |
|
public static string GetWindowTitle(IntPtr hWnd) |
{ |
var length = Natives.GetWindowTextLength(hWnd) + 1; |
/trunk/Widow/RuleEditForm.cs |
@@ -315,6 +315,52 @@ |
} |
} |
|
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; |
} |
|
#endregion |
|
#region Private Methods |
@@ -323,14 +369,14 @@ |
{ |
foreach (var handle in Helpers.FindWindows((wnd, param) => true)) |
{ |
var title = Helpers.GetWindowTitle(handle); |
if (string.IsNullOrEmpty(title)) |
var windowTitle = Helpers.GetWindowTitle(handle); |
if (string.IsNullOrEmpty(windowTitle)) |
{ |
continue; |
} |
|
var process = Helpers.GetProcessName(handle); |
if (string.IsNullOrEmpty(process)) |
var windowClass = Helpers.GetWindowClass(handle); |
if (string.IsNullOrEmpty(windowClass)) |
{ |
continue; |
} |
@@ -340,7 +386,7 @@ |
continue; |
} |
|
var window = new Window(process, title, rect.Top, rect.Left, rect.Right - rect.Left, |
var window = new Window(windowClass, windowTitle, rect.Top, rect.Left, rect.Right - rect.Left, |
rect.Bottom - rect.Top); |
|
this.Execute(() => |
@@ -366,52 +412,5 @@ |
} |
|
#endregion |
|
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; |
} |
} |
} |
/trunk/Widow/WindowManipulation.cs |
@@ -11,12 +11,6 @@ |
{ |
public class WindowManipulation : IDisposable |
{ |
#region Public Events & Delegates |
|
public event EventHandler<WindowManipulatedEventArgs> WindowManipulated; |
|
#endregion |
|
#region Public Enums, Properties and Fields |
|
public bool OnWindowCreate { get; set; } |
@@ -37,9 +31,9 @@ |
|
private Task ApplyEveryTask { get; } |
|
private BufferBlock<Window> WindowsBufferBlock { get; } |
private BufferBlock<WindowModification> WindowsBufferBlock { get; } |
|
private ActionBlock<Window> WindowsActionBlock { get; } |
private ActionBlock<WindowModification> WindowsActionBlock { get; } |
|
private IDisposable WindowsLink { get; set; } |
|
@@ -50,8 +44,8 @@ |
public WindowManipulation() |
{ |
CancellationTokenSource = new CancellationTokenSource(); |
WindowsBufferBlock = new BufferBlock<Window>(); |
WindowsActionBlock = new ActionBlock<Window>(ManipulateWindows); |
WindowsBufferBlock = new BufferBlock<WindowModification>(); |
WindowsActionBlock = new ActionBlock<WindowModification>(ManipulateWindows); |
WindowsLink = WindowsBufferBlock.LinkTo(WindowsActionBlock); |
|
ApplyEveryTask = ApplyEvery(CancellationTokenSource.Token); |
@@ -104,7 +98,8 @@ |
return; |
} |
|
if (!WindowsToManipulate.TryGetWindow(e.Title, out _)) |
var @class = Helpers.GetWindowClass(e.Handle); |
if (!WindowsToManipulate.TryGetWindow(new WindowHash(e.Title, @class), out _)) |
{ |
return; |
} |
@@ -118,25 +113,32 @@ |
|
public async Task Apply() |
{ |
var windows = new List<Window>(); |
foreach (var hWnd in Helpers.EnumerateWindows()) |
var windows = new List<WindowModification>(); |
foreach (var hWnd in Helpers.FindWindows((wnd, param) => true)) |
{ |
var title = Helpers.GetWindowTitle(hWnd); |
var windowTitle = Helpers.GetWindowTitle(hWnd); |
|
if (string.IsNullOrEmpty(title)) |
if (string.IsNullOrEmpty(windowTitle)) |
{ |
continue; |
} |
|
if (!WindowsToManipulate.TryGetWindow(title, out var window)) |
var windowClass = Helpers.GetWindowClass(hWnd); |
if (string.IsNullOrEmpty(windowClass)) |
{ |
continue; |
} |
|
windows.Add(window); |
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(window => WindowsBufferBlock.SendAsync(window))); |
await Task.WhenAll(windows.Select(modification => WindowsBufferBlock.SendAsync(modification))); |
} |
|
#endregion |
@@ -143,48 +145,43 @@ |
|
#region Private Methods |
|
private void ManipulateWindows(Window window) |
private static void ManipulateWindows(WindowModification modification) |
{ |
foreach (var hWnd in Helpers.FindWindowsWithText(window.Title)) |
if (modification.Handle == IntPtr.Zero) |
{ |
if (hWnd == IntPtr.Zero) |
{ |
continue; |
} |
return; |
} |
|
if (!Natives.GetWindowRect(hWnd, out var rect)) |
{ |
continue; |
} |
if (!Natives.GetWindowRect(modification.Handle, out var rect)) |
{ |
return; |
} |
|
var left = window.Left; |
if (window.IgnoreLeft) |
{ |
left = rect.Left; |
} |
var left = modification.Window.Left; |
if (modification.Window.IgnoreLeft) |
{ |
left = rect.Left; |
} |
|
var top = window.Top; |
if (window.IgnoreTop) |
{ |
top = rect.Top; |
} |
var top = modification.Window.Top; |
if (modification.Window.IgnoreTop) |
{ |
top = rect.Top; |
} |
|
var width = window.Width; |
if (window.IgnoreWidth) |
{ |
width = rect.Left - rect.Right; |
} |
var width = modification.Window.Width; |
if (modification.Window.IgnoreWidth) |
{ |
width = rect.Left - rect.Right; |
} |
|
var height = window.Height; |
if (window.IgnoreHeight) |
{ |
height = rect.Top - rect.Bottom; |
} |
var height = modification.Window.Height; |
if (modification.Window.IgnoreHeight) |
{ |
height = rect.Top - rect.Bottom; |
} |
|
var success = Natives.MoveWindow(hWnd, left, top, width, height, true); |
|
WindowManipulated?.Invoke(this, new WindowManipulatedEventArgs(success, window)); |
} |
Natives.MoveWindow(modification.Handle, left, top, width, height, true); |
} |
|
private async Task ApplyEvery(CancellationToken cancellationToken) |
/trunk/Windows/WindowHash.cs |
@@ -0,0 +1,76 @@ |
using System; |
|
namespace Windows |
{ |
public class WindowHash : IEquatable<WindowHash> |
{ |
#region Public Enums, Properties and Fields |
|
public string Title { get; } |
|
public string Class { get; } |
|
#endregion |
|
#region Constructors, Destructors and Finalizers |
|
public WindowHash(string title, string @class) |
{ |
Title = title; |
Class = @class; |
} |
|
#endregion |
|
#region Interface |
|
public bool Equals(WindowHash other) |
{ |
if (ReferenceEquals(null, other)) |
{ |
return false; |
} |
|
if (ReferenceEquals(this, other)) |
{ |
return true; |
} |
|
return string.Equals(Title, other.Title) && string.Equals(Class, other.Class); |
} |
|
#endregion |
|
#region Public Overrides |
|
public override bool Equals(object obj) |
{ |
if (ReferenceEquals(null, obj)) |
{ |
return false; |
} |
|
if (ReferenceEquals(this, obj)) |
{ |
return true; |
} |
|
if (obj.GetType() != GetType()) |
{ |
return false; |
} |
|
return Equals((WindowHash) obj); |
} |
|
public override int GetHashCode() |
{ |
unchecked |
{ |
return (Title != null ? Title.GetHashCode() : 0) * 397 ^ (Class != null ? Class.GetHashCode() : 0); |
} |
} |
|
#endregion |
} |
} |
/trunk/Windows/Windows.cs |
@@ -34,12 +34,14 @@ |
{ |
_window.Add(window); |
|
if (_windows.ContainsKey(window.Title)) |
var windowHash = new WindowHash(window.Title, window.Class); |
|
if (_windows.ContainsKey(windowHash)) |
{ |
continue; |
} |
|
_windows.Add(window.Title, window); |
_windows.Add(windowHash, window); |
} |
|
_window.CollectionChanged += Window_CollectionChanged; |
@@ -53,7 +55,7 @@ |
|
private readonly ObservableCollection<Window> _window = new ObservableCollection<Window>(); |
|
private readonly Dictionary<string, Window> _windows = new Dictionary<string, Window>(); |
private readonly Dictionary<WindowHash, Window> _windows = new Dictionary<WindowHash, Window>(); |
|
#endregion |
|
@@ -86,9 +88,11 @@ |
{ |
foreach (var window in e.OldItems.OfType<Window>()) |
{ |
if (_windows.ContainsKey(window.Title)) |
var windowHash = new WindowHash(window.Title, window.Class); |
|
if (_windows.ContainsKey(windowHash)) |
{ |
_windows.Remove(window.Title); |
_windows.Remove(windowHash); |
} |
} |
} |
@@ -98,9 +102,11 @@ |
{ |
foreach (var window in e.NewItems.OfType<Window>()) |
{ |
if (!_windows.ContainsKey(window.Title)) |
var windowHash = new WindowHash(window.Title, window.Class); |
|
if (!_windows.ContainsKey(windowHash)) |
{ |
_windows.Add(window.Title, window); |
_windows.Add(windowHash, window); |
} |
} |
} |
@@ -110,9 +116,9 @@ |
|
#region Public Methods |
|
public bool TryGetWindow(string title, out Window window) |
public bool TryGetWindow(WindowHash hash, out Window window) |
{ |
return _windows.TryGetValue(title, out window); |
return _windows.TryGetValue(hash, out window); |
} |
|
#endregion |