Widow – Blame information for rev 14

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  
11 office 28 private Windows.Windows WindowsToManipulate { get; }
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  
11 office 61 public WindowManipulation(MainForm mainForm, Windows.Windows windowsToManipulate) : this(mainForm)
1 office 62 {
11 office 63 WindowsToManipulate = windowsToManipulate;
1 office 64 }
65  
12 office 66 public WindowManipulation(MainForm mainForm, Windows.Windows windowsToManipulate, Settings settings) : this(
67 mainForm,
11 office 68 windowsToManipulate)
9 office 69 {
70 OnWindowCreate = settings.OnWindowCreate;
71 ApplyEveryTimeEnabled = settings.ApplyEveryTimeEnabled;
72 if (int.TryParse(settings.ApplyEveryTime, out var time))
73 {
74 ApplyEveryTime = time;
75 }
76 }
77  
1 office 78 public void Dispose()
79 {
11 office 80 WindowsLink?.Dispose();
81 WindowsLink = null;
82  
1 office 83 Form.WindowCreated -= Form_WindowCreated;
8 office 84 CancellationTokenSource.Cancel();
85 ApplyEveryTask.Wait();
86 CancellationTokenSource.Dispose();
87 CancellationTokenSource = null;
1 office 88 }
89  
90 #endregion
91  
92 #region Event Handlers
93  
11 office 94 private async void Form_WindowCreated(object sender, WindowCreatedEventArgs e)
1 office 95 {
96 if (!OnWindowCreate)
97 {
98 return;
99 }
100  
14 office 101 var @class = Helpers.GetWindowClass(e.Handle);
102 if (!WindowsToManipulate.TryGetWindow(new WindowHash(e.Title, @class), out _))
1 office 103 {
9 office 104 return;
105 }
1 office 106  
11 office 107 await Apply();
1 office 108 }
109  
110 #endregion
7 office 111  
112 #region Public Methods
113  
11 office 114 public async Task Apply()
7 office 115 {
14 office 116 var windows = new List<WindowModification>();
117 foreach (var hWnd in Helpers.FindWindows((wnd, param) => true))
12 office 118 {
14 office 119 var windowTitle = Helpers.GetWindowTitle(hWnd);
12 office 120  
14 office 121 if (string.IsNullOrEmpty(windowTitle))
12 office 122 {
123 continue;
124 }
125  
14 office 126 var windowClass = Helpers.GetWindowClass(hWnd);
127 if (string.IsNullOrEmpty(windowClass))
12 office 128 {
129 continue;
130 }
131  
14 office 132 var windowHash = new WindowHash(windowTitle, windowClass);
133 if (!WindowsToManipulate.TryGetWindow(windowHash, out var window))
134 {
135 continue;
136 }
137  
138 windows.Add(new WindowModification(hWnd, window));
12 office 139 }
140  
14 office 141 await Task.WhenAll(windows.Select(modification => WindowsBufferBlock.SendAsync(modification)));
11 office 142 }
143  
144 #endregion
145  
146 #region Private Methods
147  
14 office 148 private static void ManipulateWindows(WindowModification modification)
11 office 149 {
14 office 150 if (modification.Handle == IntPtr.Zero)
7 office 151 {
14 office 152 return;
153 }
7 office 154  
14 office 155 if (!Natives.GetWindowRect(modification.Handle, out var rect))
156 {
157 return;
158 }
9 office 159  
14 office 160 var left = modification.Window.Left;
161 if (modification.Window.IgnoreLeft)
162 {
163 left = rect.Left;
164 }
9 office 165  
14 office 166 var top = modification.Window.Top;
167 if (modification.Window.IgnoreTop)
168 {
169 top = rect.Top;
170 }
9 office 171  
14 office 172 var width = modification.Window.Width;
173 if (modification.Window.IgnoreWidth)
174 {
175 width = rect.Left - rect.Right;
176 }
9 office 177  
14 office 178 var height = modification.Window.Height;
179 if (modification.Window.IgnoreHeight)
180 {
181 height = rect.Top - rect.Bottom;
182 }
9 office 183  
14 office 184 Natives.MoveWindow(modification.Handle, left, top, width, height, true);
7 office 185 }
186  
8 office 187 private async Task ApplyEvery(CancellationToken cancellationToken)
188 {
189 do
190 {
191 if (!ApplyEveryTimeEnabled)
192 {
193 await Task.Delay(1000, cancellationToken);
194 continue;
195 }
196  
197 await Task.Delay(ApplyEveryTime, cancellationToken);
198  
11 office 199 await Apply();
8 office 200 } while (!cancellationToken.IsCancellationRequested);
201 }
202  
203 #endregion
1 office 204 }
205 }