-
Notifications
You must be signed in to change notification settings - Fork 9
/
Screen.cpp
127 lines (104 loc) · 2.87 KB
/
Screen.cpp
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
#include "Screen.h"
#include <windows.h>
#include <tchar.h>
int ScreenKeys[512]; // 记录键盘状态
int ScreenUpKeys[512]; // 记录键盘是否被放开
int Exit = 0;
static LRESULT WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_CLOSE:Exit = 1; break;
case WM_KEYDOWN:ScreenKeys[wParam & 511] = 1; break;
case WM_KEYUP:ScreenKeys[wParam & 511] = 0; ScreenUpKeys[wParam & 511] = 1; break;
default:return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int Screen::init(int width, int height, LPCTSTR title)
{
WNDCLASS wc = { CS_BYTEALIGNCLIENT, (WNDPROC)WndProc, 0, 0, 0, NULL, NULL, NULL, NULL, _T("SCREEN") };
// -height 表示 top-down
BITMAPINFO bi = { {sizeof(BITMAPINFOHEADER), width, -height, 1, 32, BI_RGB, width * height * 4, 0, 0, 0, 0} };
RECT rect = { 0, 0, width, height };
this->close();
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hInstance = GetModuleHandle(NULL);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
if (!RegisterClass(&wc)) return -1;
wndHandle = CreateWindow(_T("SCREEN"), title, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 0, 0, 0, 0, NULL, NULL, wc.hInstance, NULL);
if (wndHandle == NULL) return -2;
HDC hDC = GetDC(wndHandle);
wndDc = CreateCompatibleDC(hDC);
ReleaseDC(wndHandle, hDC);
wndHb = CreateDIBSection(wndDc, &bi, DIB_RGB_COLORS, &wndFramebuffer, 0, 0);
if (wndHb == NULL) return -3;
wndOb = (HBITMAP)SelectObject(wndDc, wndHb);
this->width = width;
this->height = height;
AdjustWindowRect(&rect, GetWindowLong(wndHandle, GWL_STYLE), 0);
int wx = rect.right - rect.left;
int wy = rect.bottom - rect.top;
int sx = (GetSystemMetrics(SM_CXSCREEN) - wx) / 2;
int sy = (GetSystemMetrics(SM_CYSCREEN) - wy) / 2;
if (sy < 0) sy = 0;
SetWindowPos(wndHandle, NULL, sx, sy, wx, wy, (SWP_NOCOPYBITS | SWP_NOZORDER | SWP_SHOWWINDOW));
SetForegroundWindow(wndHandle);
ShowWindow(wndHandle, SW_NORMAL);
dispatch();
memset(wndFramebuffer, 0, width * height * 4);
memset(ScreenKeys, 0, sizeof(int) * 512);
return 0;
}
void Screen::update()
{
HDC hDC = GetDC(wndHandle);
BitBlt(hDC, 0, 0, width, height, wndDc, 0, 0, SRCCOPY);
ReleaseDC(wndHandle, hDC);
dispatch();
}
void Screen::dispatch()
{
MSG msg;
while (1) {
if (!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) break;
if (!GetMessage(&msg, NULL, 0, 0)) break;
DispatchMessage(&msg);
}
}
void Screen::close()
{
if (wndDc) {
if (wndOb) {
SelectObject(wndDc, wndOb);
wndOb = NULL;
}
DeleteDC(wndDc);
wndDc = NULL;
}
if (wndHb) {
DeleteObject(wndHb);
wndHb = NULL;
}
if (wndHandle) {
CloseWindow(wndHandle);
wndHandle = NULL;
}
}
int Screen::isKeyPressed(int key)
{
return ScreenKeys[key & 511];
}
int Screen::getKeyUpEvent(int key)
{
int r = ScreenUpKeys[key];
ScreenUpKeys[key] = 0;
return r;
}
int Screen::isExit()
{
return Exit;
}
LPVOID Screen::getFrameBuffer()
{
return wndFramebuffer;
}