-
Notifications
You must be signed in to change notification settings - Fork 0
/
GraphicalOverlay.cs
136 lines (110 loc) · 4.51 KB
/
GraphicalOverlay.cs
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
namespace Streampanel
{
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
public partial class GraphicalOverlay : Component
{
public event EventHandler<PaintEventArgs> Paint;
private Form form;
public GraphicalOverlay()
{
InitializeComponent();
}
public GraphicalOverlay(IContainer container)
{
container.Add(this);
InitializeComponent();
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Form Owner
{
get { return form; }
set
{
// The owner form cannot be set to null.
if (value == null)
throw new ArgumentNullException();
// The owner form can only be set once.
if (form != null)
throw new InvalidOperationException();
// Save the form for future reference.
form = value;
// Handle the form's Resize event.
form.Resize += new EventHandler(Form_Resize);
// Handle the Paint event for each of the controls in the form's hierarchy.
ConnectPaintEventHandlers(form);
}
}
private void Form_Resize(object sender, EventArgs e)
{
form.Invalidate(true);
}
private void ConnectPaintEventHandlers(Control control)
{
// Connect the paint event handler for this control.
// Remove the existing handler first (if one exists) and replace it.
control.Paint -= new PaintEventHandler(Control_Paint);
control.Paint += new PaintEventHandler(Control_Paint);
control.ControlAdded -= new ControlEventHandler(Control_ControlAdded);
control.ControlAdded += new ControlEventHandler(Control_ControlAdded);
// Recurse the hierarchy.
foreach (Control child in control.Controls)
ConnectPaintEventHandlers(child);
}
private void Control_ControlAdded(object sender, ControlEventArgs e)
{
// Connect the paint event handler for the new control.
ConnectPaintEventHandlers(e.Control);
}
private void Control_Paint(object sender, PaintEventArgs e)
{
// As each control on the form is repainted, this handler is called.
Control control = sender as Control;
Point location;
// Determine the location of the control's client area relative to the form's client area.
if (control == form)
// The form's client area is already form-relative.
location = control.Location;
else
{
// The control may be in a hierarchy, so convert to screen coordinates and then back to form coordinates.
location = form.PointToClient(control.Parent.PointToScreen(control.Location));
// If the control has a border shift the location of the control's client area.
location += new Size((control.Width - control.ClientSize.Width) / 2, (control.Height - control.ClientSize.Height) / 2);
}
// Translate the location so that we can use form-relative coordinates to draw on the control.
if (control != form)
e.Graphics.TranslateTransform(-location.X, -location.Y);
// Fire a paint event.
OnPaint(sender, e);
}
private void OnPaint(object sender, PaintEventArgs e)
{
// Fire a paint event.
// The paint event will be handled in Form1.graphicalOverlay1_Paint().
if (Paint != null)
Paint(sender, e);
}
}
}
namespace System.Windows.Forms
{
using System.Drawing;
public static class Extensions
{
public static Rectangle Coordinates(this Control control)
{
// Extend System.Windows.Forms.Control to have a Coordinates property.
// The Coordinates property contains the control's form-relative location.
Rectangle coordinates;
Form form = (Form)control.TopLevelControl;
if (control == form)
coordinates = form.ClientRectangle;
else
coordinates = form.RectangleToClient(control.Parent.RectangleToScreen(control.Bounds));
return coordinates;
}
}
}