# 화면 녹화 #6 - DesktopCapture 구현
#pragma once
#include <boost/scope_exit.hpp>
const int PIXELSIZE = 4;
class DesktopCapture {
public:
DesktopCapture()
{
}
void start(int left, int top, int width, int height)
{
left_ = left;
top_ = top;
width_ = width;
height_ = height;
bitmap_size_ = width * height * PIXELSIZE;
bitmap_ = malloc(bitmap_size_);
memset(bitmap_, 0, bitmap_size_);
}
void* getBitmap()
{
do_capture();
return bitmap_;
}
private:
int left_, top_, width_, height_, bitmap_size_;
void* bitmap_;
void do_capture()
{
BITMAPINFO bmpInfo;
HDC hMemDC = NULL;
HDC hScrDC = NULL;
HBITMAP hBit = NULL;
HBITMAP hOldBitmap = NULL;
// 함수를 벗어나면 실행되는 코드 (종료 처리)
BOOST_SCOPE_EXIT(&hMemDC, &hScrDC, &hBit, &hOldBitmap)
{
if (hMemDC != NULL) {
if (hOldBitmap != NULL) SelectObject(hMemDC, hOldBitmap);
DeleteDC(hMemDC);
}
if (hBit != NULL) DeleteObject(hBit);
if (hScrDC != NULL) DeleteDC(hScrDC);
}
BOOST_SCOPE_EXIT_END;
hScrDC = GetDC(0);
if (hScrDC == NULL) {
DebugOutput::trace("GetDC() Error %d", GetLastError());
return;
}
hMemDC = CreateCompatibleDC(hScrDC);
if (hMemDC == NULL) {
DebugOutput::trace("CreateCompatibleDC() Error %d", GetLastError());
return;
}
hBit = CreateCompatibleBitmap(hScrDC, width_, height_);
if (hBit == NULL) {
DebugOutput::trace("CreateCompatibleBitmap() Error %d", GetLastError());
return;
}
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBit);
if (BitBlt(hMemDC, 0, 0, width_, height_, hScrDC, left_, top_, SRCCOPY) == FALSE) {
DebugOutput::trace("BitBlt() Error %d", GetLastError());
return;
}
// 마우스 위치 얻기
POINT curPoint;
GetCursorPos(&curPoint);
curPoint.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
curPoint.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
// hcurosr 얻어서 그리기
{
CURSORINFO cursorInfo;
cursorInfo.cbSize = sizeof(CURSORINFO);
if (GetCursorInfo(&cursorInfo)) {
ICONINFO iconInfo;
if (GetIconInfo(cursorInfo.hCursor, &iconInfo)) {
curPoint.x = curPoint.x - iconInfo.xHotspot;
curPoint.y = curPoint.y - iconInfo.yHotspot;
if (iconInfo.hbmMask != NULL) DeleteObject(iconInfo.hbmMask);
if (iconInfo.hbmColor != NULL) DeleteObject(iconInfo.hbmColor);
}
DrawIconEx(hMemDC, curPoint.x - left_, curPoint.y - top_, cursorInfo.hCursor, 0, 0, 0, NULL, DI_NORMAL);
}
}
bmpInfo.bmiHeader.biBitCount = 0;
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = width_;
bmpInfo.bmiHeader.biHeight = -height_;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = PIXEL_SIZE * 8;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = 0;
bmpInfo.bmiHeader.biXPelsPerMeter = 0;
bmpInfo.bmiHeader.biYPelsPerMeter = 0;
bmpInfo.bmiHeader.biClrUsed = 0;
bmpInfo.bmiHeader.biClrImportant = 0;
GetDIBits(hMemDC, hBit, 0, height_, (PBYTE) bitmap_, &bmpInfo, DIB_RGB_COLORS);
}
};
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
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