Widow – Blame information for rev 18

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
12 office 2 using System.Collections.Generic;
11 office 3 using System.Linq;
8 office 4 using System.Threading;
5 using System.Threading.Tasks;
11 office 6 using System.Threading.Tasks.Dataflow;
7 using Windows;
9 office 8 using Widow.Properties;
1 office 9  
10 namespace Widow
11 {
9 office 12 public class WindowManipulation : IDisposable
1 office 13 {
14 #region Public Enums, Properties and Fields
15  
16 public bool OnWindowCreate { get; set; }
17  
8 office 18 public int ApplyEveryTime { get; set; }
1 office 19  
8 office 20 public bool ApplyEveryTimeEnabled { get; set; }
21  
1 office 22 #endregion
23  
24 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
25  
8 office 26 private MainForm Form { get; }
27  
18 office 28 private Windows.Windows WindowsToManipulate { get; set; }
1 office 29  
8 office 30 private CancellationTokenSource CancellationTokenSource { get; set; }
31  
32 private Task ApplyEveryTask { get; }
33  
14 office 34 private BufferBlock<WindowModification> WindowsBufferBlock { get; }
11 office 35  
14 office 36 private ActionBlock<WindowModification> WindowsActionBlock { get; }
11 office 37  
38 private IDisposable WindowsLink { get; set; }
39  
1 office 40 #endregion
41  
42 #region Constructors, Destructors and Finalizers
43  
9 office 44 public WindowManipulation()
1 office 45 {
8 office 46 CancellationTokenSource = new CancellationTokenSource();
14 office 47 WindowsBufferBlock = new BufferBlock<WindowModification>();
48 WindowsActionBlock = new ActionBlock<WindowModification>(ManipulateWindows);
11 office 49 WindowsLink = WindowsBufferBlock.LinkTo(WindowsActionBlock);
50  
8 office 51 ApplyEveryTask = ApplyEvery(CancellationTokenSource.Token);
1 office 52 }
53  
9 office 54 public WindowManipulation(MainForm mainForm) : this()
1 office 55 {
6 office 56 Form = mainForm;
1 office 57  
58 Form.WindowCreated += Form_WindowCreated;
59 }
60  
18 office 61 public WindowManipulation(Settings settings, MainForm mainForm) : this(mainForm)
1 office 62 {
9 office 63 OnWindowCreate = settings.OnWindowCreate;
64 ApplyEveryTimeEnabled = settings.ApplyEveryTimeEnabled;
65 if (int.TryParse(settings.ApplyEveryTime, out var time))
66 {
67 ApplyEveryTime = time;
68 }
69 }
70  
1 office 71 public void Dispose()
72 {
11 office 73 WindowsLink?.Dispose();
74 WindowsLink = null;
75  
1 office 76 Form.WindowCreated -= Form_WindowCreated;
8 office 77 CancellationTokenSource.Cancel();
78 ApplyEveryTask.Wait();
79 CancellationTokenSource.Dispose();
80 CancellationTokenSource = null;
1 office 81 }
82  
83 #endregion
84  
85 #region Event Handlers
86  
11 office 87 private async void Form_WindowCreated(object sender, WindowCreatedEventArgs e)
1 office 88 {
89 if (!OnWindowCreate)
90 {
91 return;
92 }
93  
18 office 94 if (WindowsToManipulate == null)
95 {
96 return;
97 }
98  
14 office 99 var @class = Helpers.GetWindowClass(e.Handle);
100 if (!WindowsToManipulate.TryGetWindow(new WindowHash(e.Title, @class), out _))
1 office 101 {
9 office 102 return;
103 }
1 office 104  
11 office 105 await Apply();
1 office 106 }
107  
108 #endregion
7 office 109  
110 #region Public Methods
111  
18 office 112 public void AddWindows(Windows.Windows windows)
113 {
114 WindowsToManipulate = windows;
115 }
116  
11 office 117 public async Task Apply()
7 office 118 {
18 office 119 if (WindowsToManipulate == null)
120 {
121 return;
122 }
123  
14 office 124 var windows = new List<WindowModification>();
125 foreach (var hWnd in Helpers.FindWindows((wnd, param) => true))
12 office 126 {
14 office 127 var windowTitle = Helpers.GetWindowTitle(hWnd);
12 office 128  
14 office 129 if (string.IsNullOrEmpty(windowTitle))
12 office 130 {
131 continue;
132 }
133  
14 office 134 var windowClass = Helpers.GetWindowClass(hWnd);
135 if (string.IsNullOrEmpty(windowClass))
12 office 136 {
137 continue;
138 }
139  
14 office 140 var windowHash = new WindowHash(windowTitle, windowClass);
141 if (!WindowsToManipulate.TryGetWindow(windowHash, out var window))
142 {
143 continue;
144 }
145  
146 windows.Add(new WindowModification(hWnd, window));
12 office 147 }
148  
14 office 149 await Task.WhenAll(windows.Select(modification => WindowsBufferBlock.SendAsync(modification)));
11 office 150 }
151  
152 #endregion
153  
154 #region Private Methods
155  
14 office 156 private static void ManipulateWindows(WindowModification modification)
11 office 157 {
14 office 158 if (modification.Handle == IntPtr.Zero)
7 office 159 {
14 office 160 return;
161 }
7 office 162  
14 office 163 if (!Natives.GetWindowRect(modification.Handle, out var rect))
164 {
165 return;
166 }
9 office 167  
14 office 168 var left = modification.Window.Left;
169 if (modification.Window.IgnoreLeft)
170 {
171 left = rect.Left;
172 }
9 office 173  
14 office 174 var top = modification.Window.Top;
175 if (modification.Window.IgnoreTop)
176 {
177 top = rect.Top;
178 }
9 office 179  
14 office 180 var width = modification.Window.Width;
181 if (modification.Window.IgnoreWidth)
182 {
183 width = rect.Left - rect.Right;
184 }
9 office 185  
14 office 186 var height = modification.Window.Height;
187 if (modification.Window.IgnoreHeight)
188 {
189 height = rect.Top - rect.Bottom;
190 }
9 office 191  
14 office 192 Natives.MoveWindow(modification.Handle, left, top, width, height, true);
7 office 193 }
194  
8 office 195 private async Task ApplyEvery(CancellationToken cancellationToken)
196 {
197 do
198 {
199 if (!ApplyEveryTimeEnabled)
200 {
201 await Task.Delay(1000, cancellationToken);
202 continue;
203 }
204  
205 await Task.Delay(ApplyEveryTime, cancellationToken);
206  
11 office 207 await Apply();
8 office 208 } while (!cancellationToken.IsCancellationRequested);
209 }
210  
211 #endregion
1 office 212 }
213 }