-
Notifications
You must be signed in to change notification settings - Fork 106
Expand file tree
/
Copy pathNativeWindowWinNT.cs
More file actions
3080 lines (2687 loc) · 99.3 KB
/
Copy pathNativeWindowWinNT.cs
File metadata and controls
3080 lines (2687 loc) · 99.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
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright (c) 2017 Luca Piccioni
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ReSharper disable RedundantUsingDirective
// ReSharper disable UnusedMember.Local
// ReSharper disable InconsistentNaming
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; // Do not delete me! .NET Core include extension methods
using System.Runtime.InteropServices;
namespace OpenGL.CoreUI
{
/// <summary>
/// NativeWindow implementation for WindowsNT platform.
/// </summary>
class NativeWindowWinNT : NativeWindow
{
#region Constructors
/// <summary>
/// Create a NativeWindowWinNT.
/// </summary>
public NativeWindowWinNT()
{
_WindowsWndProc = WindowsWndProc;
#if NETCORE
_HInstance = UnsafeNativeMethods.GetModuleHandle(typeof(Gl).GetTypeInfo().Assembly.Location);
#else
_HInstance = Marshal.GetHINSTANCE(typeof(Gl).Module);
#endif
}
#endregion
#region Platform Resources
private IntPtr WindowsWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch ((WM)msg) {
case WM.CREATE:
return WindowsWndProc_CREATE(hWnd, wParam, lParam);
case WM.DESTROY:
return WindowsWndProc_DESTROY(hWnd, wParam, lParam);
case WM.PAINT:
return WindowsWndProc_PAINT(hWnd, wParam, lParam);
case WM.SIZE:
return WindowsWndProc_SIZE(hWnd, wParam, lParam);
case WM.SYSCOMMAND:
break;
case WM.KEYDOWN:
return WindowsWndProc_KEYDOWN(hWnd, wParam, lParam);
case WM.KEYUP:
return WindowsWndProc_KEYUP(hWnd, wParam, lParam);
case WM.MOUSELEAVE:
return WindowsWndProc_MOUSELEAVE(hWnd, wParam, lParam);
case WM.MOUSEMOVE:
return WindowsWndProc_MOUSEMOVE(hWnd, wParam, lParam);
case WM.LBUTTONDOWN:
case WM.RBUTTONDOWN:
case WM.MBUTTONDOWN:
case WM.XBUTTONDOWN:
return WindowsWndProc_BUTTONDOWN(hWnd, wParam, lParam);
case WM.LBUTTONUP:
case WM.RBUTTONUP:
case WM.MBUTTONUP:
case WM.XBUTTONUP:
return WindowsWndProc_BUTTONUP(hWnd, wParam, lParam);
case WM.LBUTTONDBLCLK:
case WM.RBUTTONDBLCLK:
case WM.MBUTTONDBLCLK:
case WM.XBUTTONDBLCLK:
return WindowsWndProc_BUTTONDOUBLECLICK(hWnd, wParam, lParam);
case WM.MOUSEWHEEL:
return WindowsWndProc_MOUSEWHEEL(hWnd, wParam, lParam);
}
// Callback default window procedure.
return UnsafeNativeMethods.DefWindowProc(hWnd, msg, wParam, lParam);
}
// ReSharper disable UnusedParameter.Local
private IntPtr WindowsWndProc_CREATE(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
// Create device context
CreateDeviceContext(IntPtr.Zero, hWnd);
// Create OpenGL context
CreateDesktopContext();
// The context is made current unconditionally: event handlers allocate resources
MakeCurrentContext();
// Event handling
OnContextCreated();
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_DESTROY(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
DeleteContext();
DestroyDeviceContext();
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_PAINT(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
MakeCurrentContext();
OnRender();
OnContextUpdate();
SwapBuffers();
// Animation
if (Animation) {
if (AnimationTime > 0) {
throw new NotImplementedException();
} else {
// Invalidate continuosly
Invalidate();
}
}
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_SIZE(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
// Notify about client area size changed
// Note:
OnResize();
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_KEYDOWN(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
VirtualKeys virtualKeyDown = (VirtualKeys)wParam.ToInt32();
// bool extendedKeyDown = ((lParam.ToInt64() >> 24) & 1) != 0);
KeyCode key = ToKeyCode(virtualKeyDown);
if (key == KeyCode.None)
return IntPtr.Zero;
OnKeyDown(key);
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_KEYUP(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
VirtualKeys virtualKeyUp = (VirtualKeys)wParam.ToInt32();
// bool extendedKeyUp = ((lParam.ToInt64() >> 24) & 1) != 0);
KeyCode key = ToKeyCode(virtualKeyUp);
if (key == KeyCode.None)
return IntPtr.Zero;
OnKeyUp(key);
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_MOUSELEAVE(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
// Next mouse event can track again mouse leave
_TrackingMouseLeave = false;
OnMouseLeave();
return IntPtr.Zero;
}
/// <summary>
/// Flag indicating whether the system is tracking the mouse leave.
/// </summary>
private bool _TrackingMouseLeave;
private IntPtr WindowsWndProc_MOUSEMOVE(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
Point mouseLocation = WindowsWndProc_GetMouseLocation(lParam);
MouseButton mouseButton = WindowsWndProc_GetMouseButtons(wParam);
if (_TrackingMouseLeave == false) {
// Emulates 'WM_MOUSEENTER'
OnMouseEnter(mouseLocation, mouseButton);
// Keep tracking WM_MOUSELEAVE
TRACKMOUSEEVENT tme = new TRACKMOUSEEVENT(TME.LEAVE, hWnd);
_TrackingMouseLeave = UnsafeNativeMethods.TrackMouseEvent(ref tme);
Debug.Assert(_TrackingMouseLeave, new Win32Exception(Marshal.GetLastWin32Error()).Message);
}
// Note: WM_MOUSEMOVE is execute just after 'WM_MOUSEENTER'
OnMouseMove(mouseLocation, mouseButton);
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_BUTTONDOWN(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
OnMouseDown(WindowsWndProc_GetMouseLocation(lParam), WindowsWndProc_GetMouseButtons(wParam));
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_BUTTONUP(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
OnMouseUp(WindowsWndProc_GetMouseLocation(lParam), WindowsWndProc_GetMouseButtons(wParam));
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_BUTTONDOUBLECLICK(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
OnMouseDoubleClick(WindowsWndProc_GetMouseLocation(lParam), WindowsWndProc_GetMouseButtons(wParam));
return IntPtr.Zero;
}
private IntPtr WindowsWndProc_MOUSEWHEEL(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
short wheelTicks = (short)(((wParam.ToInt64() >> 16) & 0xFFFF) / /* WHEEL_DELTA */ 120);
OnMouseWheel(WindowsWndProc_GetMouseLocation(lParam), WindowsWndProc_GetMouseButtons(wParam), wheelTicks);
return IntPtr.Zero;
}
// ReSharper restore UnusedParameter.Local
private Point WindowsWndProc_GetMouseLocation(IntPtr lParam)
{
int x = lParam.ToInt32() & 0xFFFF;
int y = (lParam.ToInt32() >> 16) & 0xFFFF;
return new Point(x, (int)Height - y - 1);
}
private static MouseButton WindowsWndProc_GetMouseButtons(IntPtr wParam)
{
MouseButton buttons = MouseButton.None;
int wParamValue = wParam.ToInt64() & 0xFFFF;
if ((wParamValue & 0x0001) != 0)
buttons |= MouseButton.Left;
if ((wParamValue & 0x0002) != 0)
buttons |= MouseButton.Right;
if ((wParamValue & 0x0010) != 0)
buttons |= MouseButton.Middle;
if ((wParamValue & 0x0020) != 0)
buttons |= MouseButton.X1;
if ((wParamValue & 0x0040) != 0)
buttons |= MouseButton.X2;
return buttons;
}
/// <summary>
/// Application instance handle.
/// </summary>
private readonly IntPtr _HInstance;
/// <summary>
/// The native window handle.
/// </summary>
private IntPtr _Handle;
/// <summary>
/// The atom associated to the window class.
/// </summary>
private ushort _ClassAtom;
/// <summary>
/// Windows procedure.
/// </summary>
private readonly UnsafeNativeMethods.WndProc _WindowsWndProc;
#endregion
#region P/Invoke
// ReSharper disable FieldCanBeMadeReadOnly.Local
// ReSharper disable PrivateFieldCanBeConvertedToLocalVariable
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct WNDCLASSEX
{
public int cbSize;
public int style;
public IntPtr lpfnWndProc;
private int _ClsExtra;
private int _WndExtra;
public IntPtr hInstance;
private IntPtr _Icon;
private IntPtr _Cursor;
private IntPtr _Background;
[MarshalAs(UnmanagedType.LPTStr)]
private string _MenuName;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpszClassName;
private IntPtr _IconSm;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSG
{
public IntPtr hwnd;
public uint message;
public UIntPtr wParam;
public UIntPtr lParam;
public uint time;
public POINT pt;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
[DebuggerDisplay("RECT: left={left} right={right} top={top} bottom={bottom}")]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public static explicit operator Point(RECT rect)
{
return new Point(rect.left, rect.top);
}
public static explicit operator Size(RECT rect)
{
return new Size(rect.right - rect.left, rect.bottom - rect.top);
}
}
/// <summary>
/// The MONITORINFO structure contains information about a display monitor.
/// The GetMonitorInfo function stores information into a MONITORINFOEX structure or a MONITORINFO structure.
/// The MONITORINFOEX structure is a superset of the MONITORINFO structure. The MONITORINFOEX structure adds a string member to contain a name
/// for the display monitor.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct MONITORINFO
{
/// <summary>
///
/// </summary>
/// <param name="flags"></param>
public MONITORINFO(uint flags)
{
Size = Marshal.SizeOf(typeof(MONITORINFOEX));
Monitor = new RECT();
WorkArea = new RECT();
Flags = flags;
}
/// <summary>
/// The size, in bytes, of the structure. Set this member to sizeof(MONITORINFOEX) (72) before calling the GetMonitorInfo function.
/// Doing so lets the function determine the type of structure you are passing to it.
/// </summary>
public int Size;
/// <summary>
/// A RECT structure that specifies the display monitor rectangle, expressed in virtual-screen coordinates.
/// Note that if the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.
/// </summary>
public RECT Monitor;
/// <summary>
/// A RECT structure that specifies the work area rectangle of the display monitor that can be used by applications,
/// expressed in virtual-screen coordinates. Windows uses this rectangle to maximize an application on the monitor.
/// The rest of the area in rcMonitor contains system windows such as the task bar and side bars.
/// Note that if the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.
/// </summary>
public RECT WorkArea;
/// <summary>
/// The attributes of the display monitor.
///
/// This member can be the following value:
/// 1 : MONITORINFOF_PRIMARY
/// </summary>
public uint Flags;
}
/// <summary>
/// The MONITORINFOEX structure contains information about a display monitor.
/// The GetMonitorInfo function stores information into a MONITORINFOEX structure or a MONITORINFO structure.
/// The MONITORINFOEX structure is a superset of the MONITORINFO structure. The MONITORINFOEX structure adds a string member to contain a name
/// for the display monitor.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct MONITORINFOEX
{
/// <summary>
///
/// </summary>
/// <param name="deviceName"></param>
public MONITORINFOEX(string deviceName)
{
_Size = Marshal.SizeOf(typeof(MONITORINFOEX));
Monitor = new RECT();
WorkArea = new RECT();
_Flags = 0;
_DeviceName = deviceName ?? string.Empty;
}
/// <summary>
/// The size, in bytes, of the structure. Set this member to sizeof(MONITORINFOEX) (72) before calling the GetMonitorInfo function.
/// Doing so lets the function determine the type of structure you are passing to it.
/// </summary>
private int _Size;
/// <summary>
/// A RECT structure that specifies the display monitor rectangle, expressed in virtual-screen coordinates.
/// Note that if the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.
/// </summary>
public RECT Monitor;
/// <summary>
/// A RECT structure that specifies the work area rectangle of the display monitor that can be used by applications,
/// expressed in virtual-screen coordinates. Windows uses this rectangle to maximize an application on the monitor.
/// The rest of the area in rcMonitor contains system windows such as the task bar and side bars.
/// Note that if the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.
/// </summary>
public RECT WorkArea;
/// <summary>
/// The attributes of the display monitor.
///
/// This member can be the following value:
/// 1 : MONITORINFOF_PRIMARY
/// </summary>
private uint _Flags;
// size of a device name string
private const int CCHDEVICENAME = 32;
/// <summary>
/// A string that specifies the device name of the monitor being used. Most applications have no use for a display monitor name,
/// and so can save some bytes by using a MONITORINFO structure.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
private string _DeviceName;
}
// ReSharper restore FieldCanBeMadeReadOnly.Local
// ReSharper restore PrivateFieldCanBeConvertedToLocalVariable
/// <summary>
/// Windows Messages
/// Defined in winuser.h from Windows SDK v6.1
/// Documentation pulled from MSDN.
/// http://www.pinvoke.net/default.aspx/Enums.WindowsMessages
/// </summary>
private enum WM : uint
{
/// <summary>
/// The WM_NULL message performs no operation. An application sends the WM_NULL message if it wants to post a message that the recipient window will ignore.
/// </summary>
NULL = 0x0000,
/// <summary>
/// The WM_CREATE message is sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function. (The message is sent before the function returns.) The window procedure of the new window receives this message after the window is created, but before the window becomes visible.
/// </summary>
CREATE = 0x0001,
/// <summary>
/// The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window procedure of the window being destroyed after the window is removed from the screen.
/// This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed. During the processing of the message, it can be assumed that all child windows still exist.
/// /// </summary>
DESTROY = 0x0002,
/// <summary>
/// The WM_MOVE message is sent after a window has been moved.
/// </summary>
MOVE = 0x0003,
/// <summary>
/// The WM_SIZE message is sent to a window after its size has changed.
/// </summary>
SIZE = 0x0005,
/// <summary>
/// The WM_ACTIVATE message is sent to both the window being activated and the window being deactivated. If the windows use the same input queue, the message is sent synchronously, first to the window procedure of the top-level window being deactivated, then to the window procedure of the top-level window being activated. If the windows use different input queues, the message is sent asynchronously, so the window is activated immediately.
/// </summary>
ACTIVATE = 0x0006,
/// <summary>
/// The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus.
/// </summary>
SETFOCUS = 0x0007,
/// <summary>
/// The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus.
/// </summary>
KILLFOCUS = 0x0008,
/// <summary>
/// The WM_ENABLE message is sent when an application changes the enabled state of a window. It is sent to the window whose enabled state is changing. This message is sent before the EnableWindow function returns, but after the enabled state (WS_DISABLED style bit) of the window has changed.
/// </summary>
ENABLE = 0x000A,
/// <summary>
/// An application sends the WM_SETREDRAW message to a window to allow changes in that window to be redrawn or to prevent changes in that window from being redrawn.
/// </summary>
SETREDRAW = 0x000B,
/// <summary>
/// An application sends a WM_SETTEXT message to set the text of a window.
/// </summary>
SETTEXT = 0x000C,
/// <summary>
/// An application sends a WM_GETTEXT message to copy the text that corresponds to a window into a buffer provided by the caller.
/// </summary>
GETTEXT = 0x000D,
/// <summary>
/// An application sends a WM_GETTEXTLENGTH message to determine the length, in characters, of the text associated with a window.
/// </summary>
GETTEXTLENGTH = 0x000E,
/// <summary>
/// The WM_PAINT message is sent when the system or another application makes a request to paint a portion of an application's window. The message is sent when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage function when the application obtains a WM_PAINT message by using the GetMessage or PeekMessage function.
/// </summary>
PAINT = 0x000F,
/// <summary>
/// The WM_CLOSE message is sent as a signal that a window or an application should terminate.
/// </summary>
CLOSE = 0x0010,
/// <summary>
/// The WM_QUERYENDSESSION message is sent when the user chooses to end the session or when an application calls one of the system shutdown functions. If any application returns zero, the session is not ended. The system stops sending WM_QUERYENDSESSION messages as soon as one application returns zero.
/// After processing this message, the system sends the WM_ENDSESSION message with the wParam parameter set to the results of the WM_QUERYENDSESSION message.
/// </summary>
QUERYENDSESSION = 0x0011,
/// <summary>
/// The WM_QUERYOPEN message is sent to an icon when the user requests that the window be restored to its previous size and position.
/// </summary>
QUERYOPEN = 0x0013,
/// <summary>
/// The WM_ENDSESSION message is sent to an application after the system processes the results of the WM_QUERYENDSESSION message. The WM_ENDSESSION message informs the application whether the session is ending.
/// </summary>
ENDSESSION = 0x0016,
/// <summary>
/// The WM_QUIT message indicates a request to terminate an application and is generated when the application calls the PostQuitMessage function. It causes the GetMessage function to return zero.
/// </summary>
QUIT = 0x0012,
/// <summary>
/// A window receives this message when the user chooses a command from the Window menu, clicks the maximize button, minimize button, restore button, close button, or moves the form. You can stop the form from moving by filtering this out.
/// </summary>
SYSCOMMAND = 0x0112,
/// <summary>
/// The WM_KEYDOWN message is posted to the window with the keyboard focus when a nonsystem key is pressed. A nonsystem key is a key that is pressed when the ALT key is not pressed.
/// </summary>
KEYDOWN = 0x0100,
/// <summary>
/// The WM_KEYUP message is posted to the window with the keyboard focus when a nonsystem key is released. A nonsystem key is a key that is pressed when the ALT key is not pressed, or a keyboard key that is pressed when a window has the keyboard focus.
/// </summary>
KEYUP = 0x0101,
/// <summary>
/// The WM_MOUSEMOVE message is posted to a window when the cursor moves. If the mouse is not captured, the message is posted to the window that contains the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
MOUSEMOVE = 0x0200,
/// <summary>
/// The WM_LBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
LBUTTONDOWN = 0x0201,
/// <summary>
/// The WM_LBUTTONUP message is posted when the user releases the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
LBUTTONUP = 0x0202,
/// <summary>
/// The WM_LBUTTONDBLCLK message is posted when the user double-clicks the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
LBUTTONDBLCLK = 0x0203,
/// <summary>
/// The WM_RBUTTONDOWN message is posted when the user presses the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
RBUTTONDOWN = 0x0204,
/// <summary>
/// The WM_RBUTTONUP message is posted when the user releases the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
RBUTTONUP = 0x0205,
/// <summary>
/// The WM_RBUTTONDBLCLK message is posted when the user double-clicks the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
RBUTTONDBLCLK = 0x0206,
/// <summary>
/// The WM_MBUTTONDOWN message is posted when the user presses the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
MBUTTONDOWN = 0x0207,
/// <summary>
/// The WM_MBUTTONUP message is posted when the user releases the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
MBUTTONUP = 0x0208,
/// <summary>
/// The WM_MBUTTONDBLCLK message is posted when the user double-clicks the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
MBUTTONDBLCLK = 0x0209,
/// <summary>
/// The WM_MOUSEWHEEL message is sent to the focus window when the mouse wheel is rotated. The DefWindowProc function propagates the message to the window's parent. There should be no internal forwarding of the message, since DefWindowProc propagates it up the parent chain until it finds a window that processes it.
/// </summary>
MOUSEWHEEL = 0x020A,
/// <summary>
/// The WM_XBUTTONDOWN message is posted when the user presses the first or second X button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
XBUTTONDOWN = 0x020B,
/// <summary>
/// The WM_XBUTTONUP message is posted when the user releases the first or second X button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
XBUTTONUP = 0x020C,
/// <summary>
/// The WM_XBUTTONDBLCLK message is posted when the user double-clicks the first or second X button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
/// </summary>
XBUTTONDBLCLK = 0x020D,
/// <summary>
/// The WM_MOUSEHWHEEL message is sent to the focus window when the mouse's horizontal scroll wheel is tilted or rotated. The DefWindowProc function propagates the message to the window's parent. There should be no internal forwarding of the message, since DefWindowProc propagates it up the parent chain until it finds a window that processes it.
/// </summary>
MOUSEHWHEEL = 0x020E,
/// <summary>
/// The WM_MOUSEHOVER message is posted to a window when the cursor hovers over the client area of the window for the period of time specified in a prior call to TrackMouseEvent.
/// </summary>
MOUSEHOVER = 0x02A1,
/// <summary>
/// The WM_MOUSELEAVE message is posted to a window when the cursor leaves the client area of the window specified in a prior call to TrackMouseEvent.
/// </summary>
MOUSELEAVE = 0x02A3,
/// <summary>
/// The WM_USER constant is used by applications to help define private messages for use by private window classes, usually of the form WM_USER+X, where X is an integer value.
/// </summary>
USER = 0x0400,
}
/// <summary>
/// Enumeration of the different ways of showing a window using ShowWindow.
/// </summary>
private enum WindowShowStyle
{
/// <summary>Hides the window and activates another window.</summary>
/// <remarks>See SW_HIDE</remarks>
Hide = 0,
/// <summary>Activates and displays a window. If the window is minimized
/// or maximized, the system restores it to its original size and
/// position. An application should specify this flag when displaying
/// the window for the first time.</summary>
/// <remarks>See SW_SHOWNORMAL</remarks>
ShowNormal = 1,
/// <summary>Activates the window and displays it as a minimized window.</summary>
/// <remarks>See SW_SHOWMINIMIZED</remarks>
ShowMinimized = 2,
/// <summary>Activates the window and displays it as a maximized window.</summary>
/// <remarks>See SW_SHOWMAXIMIZED</remarks>
ShowMaximized = 3,
/// <summary>Maximizes the specified window.</summary>
/// <remarks>See SW_MAXIMIZE</remarks>
Maximize = 3,
/// <summary>Displays a window in its most recent size and position.
/// This value is similar to "ShowNormal", except the window is not
/// actived.</summary>
/// <remarks>See SW_SHOWNOACTIVATE</remarks>
ShowNormalNoActivate = 4,
/// <summary>Activates the window and displays it in its current size
/// and position.</summary>
/// <remarks>See SW_SHOW</remarks>
Show = 5,
/// <summary>Minimizes the specified window and activates the next
/// top-level window in the Z order.</summary>
/// <remarks>See SW_MINIMIZE</remarks>
Minimize = 6,
/// <summary>Displays the window as a minimized window. This value is
/// similar to "ShowMinimized", except the window is not activated.</summary>
/// <remarks>See SW_SHOWMINNOACTIVE</remarks>
ShowMinNoActivate = 7,
/// <summary>Displays the window in its current size and position. This
/// value is similar to "Show", except the window is not activated.</summary>
/// <remarks>See SW_SHOWNA</remarks>
ShowNoActivate = 8,
/// <summary>Activates and displays the window. If the window is
/// minimized or maximized, the system restores it to its original size
/// and position. An application should specify this flag when restoring
/// a minimized window.</summary>
/// <remarks>See SW_RESTORE</remarks>
Restore = 9,
/// <summary>Sets the show state based on the SW_ value specified in the
/// STARTUPINFO structure passed to the CreateProcess function by the
/// program that started the application.</summary>
/// <remarks>See SW_SHOWDEFAULT</remarks>
ShowDefault = 10,
/// <summary>Windows 2000/XP: Minimizes a window, even if the thread
/// that owns the window is hung. This flag should only be used when
/// minimizing windows from a different thread.</summary>
/// <remarks>See SW_FORCEMINIMIZE</remarks>
ForceMinimized = 11
}
/// <summary>
/// http://www.pinvoke.net/default.aspx/Enums/RedrawWindowFlags.html
/// </summary>
[Flags()]
private enum RedrawWindowFlags : uint
{
/// <summary>
/// Invalidates the rectangle or region that you specify in lprcUpdate or hrgnUpdate.
/// You can set only one of these parameters to a non-NULL value. If both are NULL, RDW_INVALIDATE invalidates the entire window.
/// </summary>
Invalidate = 0x1,
/// <summary>
/// Causes the OS to post a WM_PAINT message to the window regardless of whether a portion of the window is invalid.
/// </summary>
InternalPaint = 0x2,
/// <summary>
/// Causes the window to receive a WM_ERASEBKGND message when the window is repainted.
/// Specify this value in combination with the RDW_INVALIDATE value; otherwise, RDW_ERASE has no effect.
/// </summary>
Erase = 0x4,
/// <summary>
/// Validates the rectangle or region that you specify in lprcUpdate or hrgnUpdate.
/// You can set only one of these parameters to a non-NULL value. If both are NULL, RDW_VALIDATE validates the entire window.
/// This value does not affect internal WM_PAINT messages.
/// </summary>
Validate = 0x8,
NoInternalPaint = 0x10,
/// <summary>
/// Suppresses any pending WM_ERASEBKGND messages.
/// </summary>
NoErase = 0x20,
/// <summary>
/// Excludes child windows, if any, from the repainting operation.
/// </summary>
NoChildren = 0x40,
/// <summary>
/// Includes child windows, if any, in the repainting operation.
/// </summary>
AllChildren = 0x80,
/// <summary>
/// Causes the affected windows, which you specify by setting the RDW_ALLCHILDREN and RDW_NOCHILDREN values,
/// to receive WM_ERASEBKGND and WM_PAINT messages before the RedrawWindow returns, if necessary.
/// </summary>
UpdateNow = 0x100,
/// <summary>
/// Causes the affected windows, which you specify by setting the RDW_ALLCHILDREN and RDW_NOCHILDREN values,
/// to receive WM_ERASEBKGND messages before RedrawWindow returns, if necessary. The affected windows receive
/// WM_PAINT messages at the ordinary time.
/// </summary>
EraseNow = 0x200,
Frame = 0x400,
NoFrame = 0x800
}
/// <summary>
/// Flags used with the Windows API (User32.dll):GetSystemMetrics(SystemMetric smIndex)
///
/// This Enum and declaration signature was written by Gabriel T. Sharp
/// ai_productions@verizon.net or osirisgothra@hotmail.com
/// Obtained on pinvoke.net, please contribute your code to support the wiki!
/// </summary>
private enum SystemMetric
{
/// <summary>
/// The flags that specify how the system arranged minimized windows. For more information, see the Remarks section in this topic.
/// </summary>
Arrange = 56,
/// <summary>
/// The value that specifies how the system is started:
/// 0 Normal boot
/// 1 Fail-safe boot
/// 2 Fail-safe with network boot
/// A fail-safe boot (also called SafeBoot, Safe Mode, or Clean Boot) bypasses the user startup files.
/// </summary>
CleanBoot = 67,
/// <summary>
/// The number of display monitors on a desktop. For more information, see the Remarks section in this topic.
/// </summary>
CMonitors = 80,
/// <summary>
/// The number of buttons on a mouse, or zero if no mouse is installed.
/// </summary>
CMouseButtons = 43,
/// <summary>
/// The width of a window border, in pixels. This is equivalent to the SM_CXEDGE value for windows with the 3-D look.
/// </summary>
CXBorder = 5,
/// <summary>
/// The width of a cursor, in pixels. The system cannot create cursors of other sizes.
/// </summary>
CXCursor = 13,
/// <summary>
/// This value is the same as SM_CXFIXEDFRAME.
/// </summary>
CXDlgFrame = 7,
/// <summary>
/// The width of the rectangle around the location of a first click in a double-click sequence, in pixels. ,
/// The second click must occur within the rectangle that is defined by SM_CXDOUBLECLK and SM_CYDOUBLECLK for the system
/// to consider the two clicks a double-click. The two clicks must also occur within a specified time.
/// To set the width of the double-click rectangle, call SystemParametersInfo with SPI_SETDOUBLECLKWIDTH.
/// </summary>
CXDoubleClk = 36,
/// <summary>
/// The number of pixels on either side of a mouse-down point that the mouse pointer can move before a drag operation begins.
/// This allows the user to click and release the mouse button easily without unintentionally starting a drag operation.
/// If this value is negative, it is subtracted from the left of the mouse-down point and added to the right of it.
/// </summary>
CxDrag = 68,
/// <summary>
/// The width of a 3-D border, in pixels. This metric is the 3-D counterpart of SM_CXBORDER.
/// </summary>
CXEdge = 45,
/// <summary>
/// The thickness of the frame around the perimeter of a window that has a caption but is not sizable, in pixels.
/// SM_CXFIXEDFRAME is the height of the horizontal border, and SM_CYFIXEDFRAME is the width of the vertical border.
/// This value is the same as SM_CXDLGFRAME.
/// </summary>
CXFixedFrame = 7,
/// <summary>
/// The width of the left and right edges of the focus rectangle that the DrawFocusRectdraws.
/// This value is in pixels.
/// Windows 2000: This value is not supported.
/// </summary>
CXForcusBorder = 83,
/// <summary>
/// This value is the same as SM_CXSIZEFRAME.
/// </summary>
CXFrame = 32,
/// <summary>
/// The width of the client area for a full-screen window on the primary display monitor, in pixels.
/// To get the coordinates of the portion of the screen that is not obscured by the system taskbar or by application desktop toolbars,
/// call the SystemParametersInfofunction with the SPI_GETWORKAREA value.
/// </summary>
CXFullscreen = 16,
/// <summary>
/// The width of the arrow bitmap on a horizontal scroll bar, in pixels.
/// </summary>
CXHscroll = 21,
/// <summary>
/// The width of the thumb box in a horizontal scroll bar, in pixels.
/// </summary>
CXHThunb = 10,
/// <summary>
/// The default width of an icon, in pixels. The LoadIcon function can load only icons with the dimensions
/// that SM_CXICON and SM_CYICON specifies.
/// </summary>
CXIcon = 11,
/// <summary>
/// The width of a grid cell for items in large icon view, in pixels. Each item fits into a rectangle of size
/// SM_CXICONSPACING by SM_CYICONSPACING when arranged. This value is always greater than or equal to SM_CXICON.
/// </summary>
CXIconSpacing = 38,
/// <summary>
/// The default width, in pixels, of a maximized top-level window on the primary display monitor.
/// </summary>
CXMaximized = 61,
/// <summary>
/// The default maximum width of a window that has a caption and sizing borders, in pixels.
/// This metric refers to the entire desktop. The user cannot drag the window frame to a size larger than these dimensions.
/// A window can override this value by processing the WM_GETMINMAXINFO message.
/// </summary>
CXMaxTrack = 59,
/// <summary>
/// The width of the default menu check-mark bitmap, in pixels.
/// </summary>
CXMenuCheck = 71,
/// <summary>
/// The width of menu bar buttons, such as the child window close button that is used in the multiple document interface, in pixels.
/// </summary>
CXMenuSize = 54,
/// <summary>
/// The minimum width of a window, in pixels.
/// </summary>
CXMin = 28,
/// <summary>
/// The width of a minimized window, in pixels.
/// </summary>
CXMinimized = 57,
/// <summary>
/// The width of a grid cell for a minimized window, in pixels. Each minimized window fits into a rectangle this size when arranged.
/// This value is always greater than or equal to SM_CXMINIMIZED.
/// </summary>
CXMinSpacing = 47,
/// <summary>
/// The minimum tracking width of a window, in pixels. The user cannot drag the window frame to a size smaller than these dimensions.
/// A window can override this value by processing the WM_GETMINMAXINFO message.
/// </summary>
CXMinTrack = 34,
/// <summary>
/// The amount of border padding for captioned windows, in pixels. Windows XP/2000: This value is not supported.
/// </summary>
CXPaddedBorder = 92,
/// <summary>
/// The width of the screen of the primary display monitor, in pixels. This is the same value obtained by calling
/// GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, HORZRES).
/// </summary>
CXScreen = 0,
/// <summary>
/// The width of a button in a window caption or title bar, in pixels.
/// </summary>
CXSize = 30,
/// <summary>
/// The thickness of the sizing border around the perimeter of a window that can be resized, in pixels.
/// SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border.
/// This value is the same as SM_CXFRAME.
/// </summary>
CXSizeFrame = 32,
/// <summary>
/// The recommended width of a small icon, in pixels. Small icons typically appear in window captions and in small icon view.
/// </summary>
CXSmallIcon = 49,
/// <summary>
/// The width of small caption buttons, in pixels.
/// </summary>
CXSmallSize = 52,
/// <summary>
/// The width of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors.
/// The SM_XVIRTUALSCREEN metric is the coordinates for the left side of the virtual screen.
/// </summary>
CXVirtualScreen = 78,
/// <summary>
/// The width of a vertical scroll bar, in pixels.
/// </summary>
CXVScroll = 2,
/// <summary>
/// The height of a window border, in pixels. This is equivalent to the SM_CYEDGE value for windows with the 3-D look.
/// </summary>
CYBorder = 6,
/// <summary>
/// The height of a caption area, in pixels.
/// </summary>
CYCaption = 4,
/// <summary>
/// The height of a cursor, in pixels. The system cannot create cursors of other sizes.
/// </summary>