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