-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathRemoteWindow.cs
More file actions
316 lines (283 loc) · 11.3 KB
/
Copy pathRemoteWindow.cs
File metadata and controls
316 lines (283 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
using System;
using System.Collections.Generic;
using System.Linq;
using Process.NET.Native.Types;
using Process.NET.Threads;
using Process.NET.Utilities;
using Process.NET.Windows.Keyboard;
using Process.NET.Windows.Mouse;
namespace Process.NET.Windows
{
/// <summary>
/// Class repesenting a window in the remote process.
/// </summary>
public class RemoteWindow : IEquatable<RemoteWindow>, IWindow
{
protected readonly IProcess ProcessPlus;
/// <summary>
/// Initializes a new instance of the <see cref="RemoteWindow" /> class.
/// </summary>
/// <param name="processPlus">The reference of the <see cref="IProcess" /> object.</param>
/// <param name="handle">The handle of a window.</param>
public RemoteWindow(IProcess processPlus, IntPtr handle)
{
// Save the parameters
ProcessPlus = processPlus;
Handle = handle;
// Create the tools
Keyboard = new MessageKeyboard(this);
Mouse = new SendInputMouse(this);
}
/// <summary>
/// Gets all the child window handles of this window.
/// </summary>
protected IEnumerable<IntPtr> ChildrenHandles => WindowHelper.EnumChildWindows(Handle);
/// <summary>
/// Returns a value indicating whether this instance is equal to a specified object.
/// </summary>
public bool Equals(RemoteWindow other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(ProcessPlus, other.ProcessPlus) && Handle.Equals(other.Handle);
}
/// <summary>
/// Gets all the child windows of this window.
/// </summary>
public IEnumerable<IWindow> Children
{
get { return ChildrenHandles.Select(handle => new RemoteWindow(ProcessPlus, handle)); }
}
/// <summary>
/// Gets the class name of the window.
/// </summary>
public string ClassName => WindowHelper.GetClassName(Handle);
/// <summary>
/// The handle of the window.
/// </summary>
/// <remarks>
/// The type here is not <see cref="SafeMemoryHandle" /> because a window cannot be closed by calling
/// <see cref="NativeMethods.CloseHandle" />.
/// For more information, see:
/// http://stackoverflow.com/questions/8507307/why-cant-i-close-the-window-handle-in-my-code.
/// </remarks>
public IntPtr Handle { get; }
/// <summary>
/// Gets or sets the height of the element.
/// </summary>
public int Height
{
get { return Placement.NormalPosition.Height; }
set
{
var p = Placement;
p.NormalPosition.Height = value;
Placement = p;
}
}
/// <summary>
/// Gets if the window is currently activated.
/// </summary>
public bool IsActivated => WindowHelper.GetForegroundWindow() == Handle;
/// <summary>
/// Gets if this is the main window.
/// </summary>
public bool IsMainWindow => ProcessPlus.Native.MainWindowHandle == Handle;
/// <summary>
/// Tools for managing a virtual keyboard in the window.
/// </summary>
public IKeyboard Keyboard { get; set; }
/// <summary>
/// Tools for managing a virtual mouse in the window.
/// </summary>
public IMouse Mouse { get; set; }
/// <summary>
/// Gets or sets the placement of the window.
/// </summary>
public WindowPlacement Placement
{
get { return WindowHelper.GetWindowPlacement(Handle); }
set { WindowHelper.SetWindowPlacement(Handle, value); }
}
/// <summary>
/// Gets or sets the specified window's show state.
/// </summary>
public WindowStates State
{
get { return Placement.ShowCmd; }
set { WindowHelper.ShowWindow(Handle, value); }
}
/// <summary>
/// Gets or sets the title of the window.
/// </summary>
public string Title
{
get { return WindowHelper.GetWindowText(Handle); }
set { WindowHelper.SetWindowText(Handle, value); }
}
/// <summary>
/// Gets the thread of the window.
/// </summary>
public IRemoteThread Thread => ProcessPlus.ThreadFactory.GetThreadById(WindowHelper.GetWindowThreadId(Handle));
/// <summary>
/// Gets or sets the width of the element.
/// </summary>
public int Width
{
get { return Placement.NormalPosition.Width; }
set
{
var p = Placement;
p.NormalPosition.Width = value;
Placement = p;
}
}
/// <summary>
/// Gets or sets the x-coordinate of the window.
/// </summary>
public int X
{
get { return Placement.NormalPosition.Left; }
set
{
var p = Placement;
p.NormalPosition.Right = value + p.NormalPosition.Width;
p.NormalPosition.Left = value;
Placement = p;
}
}
/// <summary>
/// Gets or sets the y-coordinate of the window.
/// </summary>
public int Y
{
get { return Placement.NormalPosition.Top; }
set
{
var p = Placement;
p.NormalPosition.Bottom = value + p.NormalPosition.Height;
p.NormalPosition.Top = value;
Placement = p;
}
}
/// <summary>
/// Activates the window.
/// </summary>
public void Activate()
{
WindowHelper.SetForegroundWindow(Handle);
}
/// <summary>
/// Closes the window.
/// </summary>
public void Close()
{
PostMessage(WindowsMessages.Close, IntPtr.Zero, IntPtr.Zero);
}
/// <summary>
/// Flashes the window one time. It does not change the active state of the window.
/// </summary>
public void Flash()
{
WindowHelper.FlashWindow(Handle);
}
/// <summary>
/// Flashes the window. It does not change the active state of the window.
/// </summary>
/// <param name="count">The number of times to flash the window.</param>
/// <param name="timeout">The rate at which the window is to be flashed.</param>
/// <param name="flags">The flash status.</param>
public void Flash(int count, TimeSpan timeout, FlashWindowFlags flags = FlashWindowFlags.All)
{
WindowHelper.FlashWindowEx(Handle, flags, count, timeout);
}
public virtual void Dispose()
{
}
/// <summary>
/// Places (posts) a message in the message queue associated with the thread that created the window and returns
/// without waiting for the thread to process the message.
/// </summary>
/// <param name="message">The message to be posted.</param>
/// <param name="wParam">Additional message-specific information.</param>
/// <param name="lParam">Additional message-specific information.</param>
public void PostMessage(WindowsMessages message, IntPtr wParam, IntPtr lParam)
{
WindowHelper.PostMessage(Handle, message, wParam, lParam);
}
/// <summary>
/// Places (posts) a message in the message queue associated with the thread that created the window and returns
/// without waiting for the thread to process the message.
/// </summary>
/// <param name="message">The message to be posted.</param>
/// <param name="wParam">Additional message-specific information.</param>
/// <param name="lParam">Additional message-specific information.</param>
public void PostMessage(int message, IntPtr wParam, IntPtr lParam)
{
WindowHelper.PostMessage(Handle, message, wParam, lParam);
}
/// <summary>
/// Sends the specified message to a window or windows.
/// The SendMessage function calls the window procedure for the specified window and does not return until the window
/// procedure has processed the message.
/// </summary>
/// <param name="message">The message to be sent.</param>
/// <param name="wParam">Additional message-specific information.</param>
/// <param name="lParam">Additional message-specific information.</param>
/// <returns>The return value specifies the result of the message processing; it depends on the message sent.</returns>
public IntPtr SendMessage(WindowsMessages message, IntPtr wParam, IntPtr lParam)
{
return WindowHelper.SendMessage(Handle, message, wParam, lParam);
}
/// <summary>
/// Sends the specified message to a window or windows.
/// The SendMessage function calls the window procedure for the specified window and does not return until the window
/// procedure has processed the message.
/// </summary>
/// <param name="message">The message to be sent.</param>
/// <param name="wParam">Additional message-specific information.</param>
/// <param name="lParam">Additional message-specific information.</param>
/// <returns>The return value specifies the result of the message processing; it depends on the message sent.</returns>
public IntPtr SendMessage(int message, IntPtr wParam, IntPtr lParam)
{
return WindowHelper.SendMessage(Handle, message, wParam, lParam);
}
/// <summary>
/// Serves as a hash function for a particular type.
/// </summary>
public override int GetHashCode()
{
unchecked
{
var hashCode = ProcessPlus?.GetHashCode() ?? 0;
hashCode = (hashCode*397) ^ Handle.GetHashCode();
return hashCode;
}
}
/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
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((RemoteWindow) obj);
}
public static bool operator ==(RemoteWindow left, RemoteWindow right)
{
return Equals(left, right);
}
public static bool operator !=(RemoteWindow left, RemoteWindow right)
{
return !Equals(left, right);
}
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
public override string ToString()
{
return $"Title = {Title} ClassName = {ClassName}";
}
}
}