-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCPictureBox.cs
More file actions
140 lines (121 loc) · 4.69 KB
/
CPictureBox.cs
File metadata and controls
140 lines (121 loc) · 4.69 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
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace GIF_Viewer
{
/// <summary>
/// Represents a custom picture box that is setup to minimize flickering as much as possible when redrawing multiple times a second
/// </summary>
class CPictureBox : PictureBox
{
/// <summary>
/// Image quality
/// </summary>
public int Quality = 3;
/// <summary>
/// Initializes a new instance of the CPictureBox object
/// </summary>
public CPictureBox()
{
// Set some styles to optimize and make things pretty
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
}
/// <summary>
/// Overriden OnPaintBackground method that redraws the image at every call
/// </summary>
/// <param name="pevent">The event message for this paint event</param>
protected override void OnPaintBackground(PaintEventArgs pevent)
{
// Clear the panel:
pevent.Graphics.Clear(BackColor);
pevent.Graphics.CompositingMode = CompositingMode.SourceOver;
pevent.Graphics.CompositingQuality = CompositingQuality.HighSpeed;
// Return if the background image is null or if the paint message is set to be ignored
if (BackgroundImage == null || _Paint == false)
return;
pevent.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
// Switch the drawing quality depending on the current settings:
switch (Quality)
{
// Low:
case 1:
pevent.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
pevent.Graphics.SmoothingMode = SmoothingMode.None;
break;
// Medium:
case 2:
pevent.Graphics.InterpolationMode = InterpolationMode.High;
pevent.Graphics.SmoothingMode = SmoothingMode.None;
break;
// High
case 3:
pevent.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
pevent.Graphics.SmoothingMode = SmoothingMode.None;
break;
}
// Draw it manually:
CalculateRectangle();
pevent.Graphics.DrawImage(BackgroundImage, _rectangle);
}
/// <summary>
/// Calculates a rectangle that fits this object's background image with a Zoom setting
/// which scales but keeps the aspect ratio of the image
/// </summary>
/// <returns></returns>
public void CalculateRectangle()
{
SizeF size2 = BackgroundImage.Size;
Rectangle bounds = ClientRectangle;
_rectangle.X = 0;
_rectangle.Y = 0;
float widthRatio = bounds.Width / size2.Width;
float heightRatio = bounds.Height / size2.Height;
if (widthRatio >= heightRatio)
{
_rectangle.Height = bounds.Height;
_rectangle.Width = (int)((size2.Width * heightRatio) + 0.5f);
if (bounds.X >= 0)
{
_rectangle.X = (bounds.Width - _rectangle.Width) / 2;
}
}
else
{
_rectangle.Width = bounds.Width;
_rectangle.Height = (int)((size2.Height * widthRatio) + 0.5f);
if (bounds.Y >= 0)
{
_rectangle.Y = (bounds.Height - _rectangle.Height) / 2;
}
}
}
/// <summary>
/// The Draw message
/// </summary>
const short WM_PAINT = 0x00F;
/// <summary>
/// Whether the program should respond to the drawm (WM_PAINT [0x00F]) message
/// </summary>
public bool _Paint = true;
/// <summary>
/// Overrided Windows message handler used to reduce the flickering of the control
/// </summary>
/// <param name="m">The message sent to this Control</param>
protected override void WndProc(ref Message m)
{
// Draw message? Not set to draw? Skip with a zero result!
if (m.Msg == WM_PAINT && !_Paint)
{
m.Result = IntPtr.Zero;
}
// If not, Base WndProc it:
else
base.WndProc(ref m);
}
/// <summary>
/// Stored rectangle used on each rectangle calculation
/// </summary>
Rectangle _rectangle;
}
}