-
Notifications
You must be signed in to change notification settings - Fork 2
/
GDIHelper.cs
123 lines (102 loc) · 4.36 KB
/
GDIHelper.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
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Zbx1425.DXDynamicTexture {
public class GDIHelper : IDisposable {
[DllImport("gdi32")]
internal static extern IntPtr CreateCompatibleDC([In] IntPtr hdc);
[DllImport("gdi32")]
internal static extern int SelectObject([In] IntPtr hdc, [In] IntPtr hObject);
[DllImport("gdi32")]
internal static extern int DeleteDC([In] IntPtr hdc);
[DllImport("gdi32")]
internal static extern int DeleteObject([In] IntPtr hObject);
[DllImport("gdi32")]
internal static extern int BitBlt([In] IntPtr hDestDC, int x, int y, int nWidth, int nHeight,
[In] IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
internal const int SRCCOPY = 0xCC0020;
[DllImport("gdi32")]
internal static extern int Rectangle([In] IntPtr hdc, int X1, int Y1, int X2, int Y2);
[DllImport("gdi32")]
internal static extern IntPtr CreateSolidBrush(int crColor);
public struct HBitmap {
public Bitmap img;
public IntPtr ptr;
public HBitmap(Bitmap rimg) {
img = rimg;
ptr = img.GetHbitmap();
}
}
private Dictionary<Bitmap, IntPtr> Images = new Dictionary<Bitmap, IntPtr>();
private Dictionary<Color, IntPtr> Brushes = new Dictionary<Color, IntPtr>();
public Graphics Graphics;
public Bitmap Bitmap;
public GDIHelper(Graphics g) {
this.Graphics = g;
}
public GDIHelper(int width, int height) {
this.Bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
this.Graphics = Graphics.FromImage(this.Bitmap);
this.Graphics.Clear(Color.Transparent);
}
private IntPtr hDC;
private IntPtr hMemDC;
public void BeginGDI() {
if (hDC != IntPtr.Zero) return;
hDC = Graphics.GetHdc();
hMemDC = CreateCompatibleDC(hDC);
}
public void EndGDI() {
if (hDC == IntPtr.Zero) return;
DeleteDC(hMemDC);
Graphics.ReleaseHdc();
hDC = IntPtr.Zero;
}
public bool HasAcquiredHDC() {
return hDC != IntPtr.Zero;
}
public void DrawImage(Bitmap img, int x, int y) {
if (hDC == IntPtr.Zero) throw new InvalidOperationException("You must call BeginGDI() first!");
SelectObject(hMemDC, GetHBitmap(img));
BitBlt(hDC, x, y, img.Width, img.Height, hMemDC, 0, 0, SRCCOPY);
}
public void DrawImage(Bitmap img, int x, int y, int sy, int h) {
if (hDC == IntPtr.Zero) throw new InvalidOperationException("You must call BeginGDI() first!");
SelectObject(hMemDC, GetHBitmap(img));
BitBlt(hDC, x, y, img.Width, h, hMemDC, 0, sy, SRCCOPY);
}
public void FillRect12(Color color, int x1, int y1, int x2, int y2) {
if (hDC == IntPtr.Zero) throw new InvalidOperationException("You must call BeginGDI() first!");
SelectObject(hDC, GetSolidBrush(color));
Rectangle(hDC, x1, y1, x2, y2);
}
public void FillRectWH(Color color, int x1, int y1, int w, int h) {
if (hDC == IntPtr.Zero) throw new InvalidOperationException("You must call BeginGDI() first!");
SelectObject(hDC, GetSolidBrush(color));
Rectangle(hDC, x1, y1, x1 + w, y1 + h);
}
private IntPtr GetHBitmap(Bitmap image) {
new DateTime(152).ToShortTimeString();
if (!Images.ContainsKey(image)) Images.Add(image, image.GetHbitmap());
return Images[image];
}
private IntPtr GetSolidBrush(Color color) {
if (!Brushes.ContainsKey(color)) {
Brushes.Add(color, CreateSolidBrush(color.R | color.G << 8 | color.B << 16));
}
return Brushes[color];
}
public void Dispose() {
EndGDI();
if (this.Bitmap != null) this.Bitmap.Dispose();
foreach (var pair in Images) DeleteObject(pair.Value);
Images.Clear();
foreach (var pair in Brushes) DeleteObject(pair.Value);
Brushes.Clear();
}
}
}