comparison Chronosv2/source/Interop/Win32Interop.cs @ 10:443821e55f06

Initial cleaned up add from Codeplex files
author stevenh7776 stevenhollidge@hotmail.com
date Tue, 21 Feb 2012 17:25:44 +0700
parents
children 09d18d6e5f40
comparison
equal deleted inserted replaced
9:904a9faadf8b 10:443821e55f06
1 /*
2 The MIT License
3
4 Copyright (c) 2009-2010. Carlos Guzmán Álvarez. http://chronoswpf.codeplex.com/
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 */
24
25 using System;
26 using System.Runtime.InteropServices;
27 using System.Windows;
28
29 namespace Chronos.Interop
30 {
31 /// <summary>
32 /// Win32 Interop Functions
33 /// </summary>
34 /// <remarks>
35 /// http://blogs.msdn.com/llobo/archive/2006/08/01/Maximizing-window-_2800_with-WindowStyle_3D00_None_2900_-considering-Taskbar.aspx
36 /// http://social.msdn.microsoft.com/forums/en-US/wpf/thread/e77c3b58-41f6-4534-8a92-be0f8287b734/
37 /// </remarks>
38 public static class Win32Interop
39 {
40 #region · Consts ·
41
42 /// <summary>
43 /// Sets a new extended window style
44 /// </summary>
45 public static readonly Int32 GWL_EXSTYLE = -20;
46
47 /// <summary>
48 /// Layered Windows
49 /// </summary>
50 public static readonly Int32 WS_EX_LAYERED = 0x00080000;
51
52 /// <summary>
53 /// Transparent window
54 /// </summary>
55 public static readonly Int32 WS_EX_TRANSPARENT = 0x00000020;
56
57 private static readonly Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;
58
59 /// <summary>
60 /// Stop flashing. The system restores the window to its original state.
61 /// </summary>
62 public const UInt32 FLASHW_STOP = 0;
63
64 /// <summary>
65 /// Flash the window caption.
66 /// </summary>
67 public const UInt32 FLASHW_CAPTION = 1;
68
69 /// <summary>
70 /// Flash the taskbar button.
71 /// </summary>
72 public const UInt32 FLASHW_TRAY = 2;
73
74 /// <summary>
75 /// Flash both the window caption and taskbar button.
76 /// This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags.
77 /// </summary>
78 public const UInt32 FLASHW_ALL = 3;
79
80 /// <summary>
81 /// Flash continuously, until the FLASHW_STOP flag is set.
82 /// </summary>
83 public const UInt32 FLASHW_TIMER = 4;
84
85 /// <summary>
86 /// Flash continuously until the window comes to the foreground.
87 /// </summary>
88 public const UInt32 FLASHW_TIMERNOFG = 12;
89
90 #endregion
91
92 #region · Inner Types ·
93
94 [StructLayout(LayoutKind.Sequential)]
95 private struct FLASHWINFO
96 {
97 public UInt32 cbSize;
98 public IntPtr hwnd;
99 public UInt32 dwFlags;
100 public UInt32 uCount;
101 public UInt32 dwTimeout;
102 }
103
104 // Struct we'll need to pass to the function
105 [StructLayout(LayoutKind.Sequential)]
106 private struct LASTINPUTINFO
107 {
108 public UInt32 cbSize;
109 public UInt32 dwTime;
110 }
111
112 /// <summary>
113 /// POINT aka POINTAPI
114 /// </summary>
115 [StructLayout(LayoutKind.Sequential)]
116 public struct POINT
117 {
118 #region · Fields ·
119
120 /// <summary>
121 /// x coordinate of point.
122 /// </summary>
123 public int X;
124 /// <summary>
125 /// y coordinate of point.
126 /// </summary>
127 public int Y;
128
129 #endregion
130
131 #region · Constructors ·
132
133 /// <summary>
134 /// Construct a point of coordinates (x,y).
135 /// </summary>
136 public POINT(int x, int y)
137 {
138 this.X = x;
139 this.Y = y;
140 }
141
142 #endregion
143 }
144
145 /// <summary>
146 /// The MINMAXINFO structure contains information about a window's maximized size and
147 /// position and its minimum and maximum tracking size.
148 /// </summary>
149 [StructLayout(LayoutKind.Sequential)]
150 public struct MINMAXINFO
151 {
152 /// <summary>
153 /// Reserved; do not use.
154 /// </summary>
155 public POINT ptReserved;
156
157 /// <summary>
158 /// Specifies the maximized width (POINT.x) and the maximized height (POINT.y) of the window.
159 /// For top-level windows, this value is based on the width of the primary monitor.
160 /// </summary>
161 public POINT ptMaxSize;
162
163 /// <summary>
164 /// Specifies the position of the left side of the maximized window (POINT.x) and
165 /// the position of the top of the maximized window (POINT.y).
166 /// For top-level windows, this value is based on the position of the primary monitor.
167 /// </summary>
168 public POINT ptMaxPosition;
169
170 /// <summary>
171 /// Specifies the minimum tracking width (POINT.x) and the minimum tracking height (POINT.y) of the window.
172 /// This value can be obtained programmatically from the system metrics SM_CXMINTRACK and SM_CYMINTRACK.
173 /// </summary>
174 public POINT ptMinTrackSize;
175
176 /// <summary>
177 /// Specifies the maximum tracking width (POINT.x) and the maximum tracking height (POINT.y) of the window.
178 /// This value is based on the size of the virtual screen and can be obtained programmatically from the
179 /// system metrics SM_CXMAXTRACK and SM_CYMAXTRACK.
180 /// </summary>
181 public POINT ptMaxTrackSize;
182 };
183
184 /// <summary>
185 /// The MONITORINFO structure contains information about a display monitor.
186 /// </summary>
187 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
188 public class MONITORINFO
189 {
190 /// <summary>
191 /// The size of the structure, in bytes.
192 /// </summary>
193 public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
194
195 /// <summary>
196 /// A RECT structure that specifies the display monitor rectangle, expressed in virtual-screen coordinates.
197 /// Note that if the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.
198 /// </summary>
199 public RECT rcMonitor = new RECT();
200
201 /// <summary>
202 /// A RECT structure that specifies the work area rectangle of the display monitor, expressed in virtual-screen coordinates.
203 /// Note that if the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.
204 /// </summary>
205 public RECT rcWork = new RECT();
206
207 /// <summary>
208 /// A set of flags that represent attributes of the display monitor.
209 /// </summary>
210 public int dwFlags = 0;
211 }
212
213 /// <summary> Win32 </summary>
214 [StructLayout(LayoutKind.Sequential, Pack = 0)]
215 public struct RECT
216 {
217 #region · Operators ·
218
219 /// <summary> Determine if 2 RECT are equal (deep compare)</summary>
220 public static bool operator ==(RECT rect1, RECT rect2)
221 {
222 return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom);
223 }
224
225 /// <summary> Determine if 2 RECT are different(deep compare)</summary>
226 public static bool operator !=(RECT rect1, RECT rect2)
227 {
228 return !(rect1 == rect2);
229 }
230
231 #endregion
232
233 #region · Static Members ·
234
235 /// <summary> Win32 </summary>
236 public static readonly RECT Empty = new RECT();
237
238 #endregion
239
240 #region · Public Fields ·
241
242 /// <summary> Win32 </summary>
243 public int left;
244 /// <summary> Win32 </summary>
245 public int top;
246 /// <summary> Win32 </summary>
247 public int right;
248 /// <summary> Win32 </summary>
249 public int bottom;
250
251 #endregion
252
253 #region · Properties ·
254
255 /// <summary> Win32 </summary>
256 public int Width
257 {
258 get { return Math.Abs(right - left); } // Abs needed for BIDI OS
259 }
260
261 /// <summary> Win32 </summary>
262 public int Height
263 {
264 get { return bottom - top; }
265 }
266
267 /// <summary> Win32 </summary>
268 public bool IsEmpty
269 {
270 get
271 {
272 // BUGBUG : On Bidi OS (hebrew arabic) left > right
273 return left >= right || top >= bottom;
274 }
275 }
276
277 #endregion
278
279 #region · Constructors ·
280
281 /// <summary>
282 /// Win32
283 /// </summary>
284 /// <param name="left">The left.</param>
285 /// <param name="top">The top.</param>
286 /// <param name="right">The right.</param>
287 /// <param name="bottom">The bottom.</param>
288 public RECT(int left, int top, int right, int bottom)
289 {
290 this.left = left;
291 this.top = top;
292 this.right = right;
293 this.bottom = bottom;
294 }
295
296 /// <summary>
297 /// Win32
298 /// </summary>
299 /// <param name="rcSrc">The rc SRC.</param>
300 public RECT(RECT rcSrc)
301 {
302 this.left = rcSrc.left;
303 this.top = rcSrc.top;
304 this.right = rcSrc.right;
305 this.bottom = rcSrc.bottom;
306 }
307
308 #endregion
309
310 #region · Methods ·
311
312 /// <summary>
313 /// Return a user friendly representation of this struct
314 /// </summary>
315 /// <returns>
316 /// A <see cref="System.String"/> that represents this instance.
317 /// </returns>
318 public override string ToString()
319 {
320 if (this == RECT.Empty)
321 {
322 return "RECT {Empty}";
323 }
324 return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + " }";
325 }
326
327 /// <summary>
328 /// Determine if 2 RECT are equal (deep compare)
329 /// </summary>
330 /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
331 /// <returns>
332 /// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
333 /// </returns>
334 public override bool Equals(object obj)
335 {
336 if (!(obj is Rect))
337 {
338 return false;
339 }
340
341 return (this == (RECT)obj);
342 }
343
344 /// <summary>
345 /// Return the HashCode for this struct (not garanteed to be unique)
346 /// </summary>
347 /// <returns>
348 /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
349 /// </returns>
350 public override int GetHashCode()
351 {
352 return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode();
353 }
354
355 #endregion
356 }
357
358 #endregion
359
360 #region · Static Methods ·
361
362 public static void FlashWindow(IntPtr handle)
363 {
364 IntPtr hWnd = handle;
365 FLASHWINFO fInfo = new FLASHWINFO();
366
367 fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo));
368 fInfo.hwnd = hWnd;
369 fInfo.dwFlags = Win32Interop.FLASHW_ALL |
370 Win32Interop.FLASHW_TIMERNOFG |
371 Win32Interop.FLASHW_CAPTION;
372
373 fInfo.uCount = UInt32.MaxValue;
374 fInfo.dwTimeout = 0;
375
376 FlashWindowEx(ref fInfo);
377 }
378
379 /// <summary>
380 /// Gets the application idle time
381 /// </summary>
382 /// <remarks>
383 /// http://www.geekpedia.com/tutorial210_Retrieving-the-Operating-System-Idle-Time-Uptime-and-Last-Input-Time.html
384 /// </remarks>
385 /// <returns></returns>
386 public static int GetIdleTime()
387 {
388 // Get the system uptime
389 int systemUptime = Environment.TickCount;
390 // The tick at which the last input was recorded
391 int lastInputTicks = 0;
392 // The number of ticks that passed since last input
393 int idleTicks = 0;
394
395 // Set the struct
396 LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
397 lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
398 lastInputInfo.dwTime = 0;
399
400 // If we have a value from the function
401 if (GetLastInputInfo(ref lastInputInfo))
402 {
403 // Get the number of ticks at the point when the last activity was seen
404 lastInputTicks = (int)lastInputInfo.dwTime;
405 // Number of idle ticks = system uptime ticks - number of ticks at last input
406 idleTicks = systemUptime - lastInputTicks;
407 }
408
409 return (idleTicks / 1000);
410 }
411
412 /// <summary>
413 /// Window Proc
414 /// </summary>
415 /// <param name="hwnd">The HWND.</param>
416 /// <param name="msg">The MSG.</param>
417 /// <param name="wParam">The w param.</param>
418 /// <param name="lParam">The l param.</param>
419 /// <param name="handled">if set to <c>true</c> [handled].</param>
420 /// <returns></returns>
421 public static System.IntPtr WindowProc(
422 System.IntPtr hwnd,
423 int msg,
424 System.IntPtr wParam,
425 System.IntPtr lParam,
426 ref bool handled)
427 {
428 switch (msg)
429 {
430 case 0x0024:/* WM_GETMINMAXINFO */
431 WmGetMinMaxInfo(hwnd, lParam);
432 handled = true;
433 break;
434 }
435
436 return (System.IntPtr)0;
437 }
438
439 /// <summary>
440 /// Get the min max size of a window
441 /// </summary>
442 /// <param name="hwnd">The HWND.</param>
443 /// <param name="lParam">The l param.</param>
444 public static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)
445 {
446 Win32Interop.MINMAXINFO mmi = (Win32Interop.MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(Win32Interop.MINMAXINFO));
447
448 // Adjust the maximized size and position to fit the work area of the correct monitor
449 System.IntPtr monitor = Win32Interop.MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
450
451 if (monitor != System.IntPtr.Zero)
452 {
453 Win32Interop.MONITORINFO monitorInfo = new Win32Interop.MONITORINFO();
454 Win32Interop.GetMonitorInfo(monitor, monitorInfo);
455 Win32Interop.RECT rcWorkArea = monitorInfo.rcWork;
456 Win32Interop.RECT rcMonitorArea = monitorInfo.rcMonitor;
457
458 mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
459 mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
460 mmi.ptMaxSize.X = Math.Abs(rcWorkArea.right - rcWorkArea.left);
461 mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
462 }
463
464 Marshal.StructureToPtr(mmi, lParam, true);
465 }
466
467 #endregion
468
469 #region · P/Invoke Functions ·
470
471 [DllImport("user32.dll")]
472 static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi);
473
474 [DllImport("user32.dll")]
475 static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
476
477 /// <summary>
478 /// Gets information about a display monitor.
479 /// </summary>
480 /// <param name="hMonitor">The h monitor.</param>
481 /// <param name="lpmi">The lpmi.</param>
482 /// <returns></returns>
483 [DllImport("user32")]
484 internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
485
486 /// <summary>
487 /// Gets a handle to the display monitor that has the largest area of intersection with the bounding rectangle of a specified windo
488 /// </summary>
489 /// <param name="handle">The handle.</param>
490 /// <param name="flags">The flags.</param>
491 /// <returns></returns>
492 [DllImport("User32")]
493 internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
494
495 /// <summary>
496 /// Gets the cursor's position, in screen coordinates.
497 /// </summary>
498 /// <param name="pt"></param>
499 /// <returns></returns>
500 [DllImport("user32.dll", CharSet = CharSet.Auto)]
501 public static extern bool GetCursorPos(out POINT pt);
502
503 /// <summary>
504 /// Gets information about the specified window.
505 /// The function also retrieves the 32-bit (long) value at the specified offset into the extra window memory.
506 /// </summary>
507 /// <param name="hWnd"></param>
508 /// <param name="nIndex"></param>
509 /// <returns></returns>
510 [DllImport("user32.dll", CharSet = CharSet.Auto)]
511 public static extern Int32 GetWindowLong(IntPtr hWnd, Int32 nIndex);
512
513 /// <summary>
514 /// Changes an attribute of the specified window.
515 /// The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
516 /// </summary>
517 /// <param name="hWnd"></param>
518 /// <param name="nIndex"></param>
519 /// <param name="newVal"></param>
520 /// <returns></returns>
521 [DllImport("user32.dll", CharSet = CharSet.Auto)]
522 public static extern Int32 SetWindowLong(IntPtr hWnd, Int32 nIndex, Int32 newVal);
523
524 #endregion
525 }
526 }