176 lines
4.3 KiB
C++
176 lines
4.3 KiB
C++
#include"Window.h"
|
||
//app单例
|
||
Window* Window::currentWindow = nullptr;
|
||
|
||
Window::Window(Input& p_input):m_input(p_input)
|
||
{
|
||
//ShowCursor(false);
|
||
}
|
||
Window::~Window() {}
|
||
|
||
|
||
//带注册的事件回调(必须是静态函数)
|
||
LRESULT CALLBACK Wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
Window::currentWindow->handleMessage(hWnd, message, wParam, lParam);
|
||
return(DefWindowProc(hWnd, message, wParam, lParam));
|
||
}
|
||
|
||
|
||
bool Window::initWindow(HINSTANCE hInstance, const uint32_t& width, const uint32_t& height) {
|
||
currentWindow = this;
|
||
mWidth = width;
|
||
mHeight = height;
|
||
|
||
//初始化窗体类型,并且注册
|
||
registerWindowClass(hInstance);
|
||
|
||
//生成一个窗体,并且显示
|
||
if (!createWindow(hInstance)) {
|
||
return false;
|
||
}
|
||
|
||
//初始化画布
|
||
/*
|
||
* DC:Device Context 设备上下文描述对象
|
||
* 每个窗口都有自己对应的设备区域映射,即mhDC
|
||
* 这里创建一个与本窗口兼容的DC,mCanvasDC
|
||
* 可以从mCanvasDC向mhDC拷贝绘图数据内容
|
||
*/
|
||
mhDC = GetDC(mHwnd);
|
||
mCanvasDC = CreateCompatibleDC(mhDC);
|
||
|
||
BITMAPINFO bmpInfo{};
|
||
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||
bmpInfo.bmiHeader.biWidth = mWidth;
|
||
bmpInfo.bmiHeader.biHeight = mHeight;
|
||
bmpInfo.bmiHeader.biPlanes = 1;
|
||
bmpInfo.bmiHeader.biBitCount = 32;
|
||
bmpInfo.bmiHeader.biCompression = BI_RGB; //实际上存储方式为bgra
|
||
|
||
//创建与mhMem兼容的位图,其实实在mhMem指代的设备上划拨了一块内存,让mCanvasBuffer指向它
|
||
mhBmp = CreateDIBSection(mCanvasDC, &bmpInfo, DIB_RGB_COLORS, (void**)&mCanvasBuffer, 0, 0);//在这里创建buffer的内存
|
||
|
||
//一个设备可以创建多个位图,本设备使用mhBmp作为激活位图,对mCanvasDC的内存拷出,其实就是拷出了mhBmp的数据
|
||
SelectObject(mCanvasDC, mhBmp);
|
||
|
||
memset(mCanvasBuffer, 0, mWidth * mHeight * 4); //清空buffer为0
|
||
|
||
return true;
|
||
}
|
||
|
||
ATOM Window::registerWindowClass(HINSTANCE hInstance)
|
||
{
|
||
WNDCLASSEXW wndClass;
|
||
|
||
wndClass.cbSize = sizeof(WNDCLASSEX);
|
||
wndClass.style = CS_HREDRAW | CS_VREDRAW; //水平/垂直大小发生变化重绘窗口
|
||
wndClass.lpfnWndProc = Wndproc;
|
||
wndClass.cbClsExtra = 0;
|
||
wndClass.cbWndExtra = 0;
|
||
wndClass.hInstance = hInstance; //应用程序句柄
|
||
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);//应用程序图标,即任务栏的大图标
|
||
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);//鼠标图标
|
||
wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//窗口背景色
|
||
wndClass.lpszMenuName = NULL;
|
||
wndClass.lpszClassName = mWindowClassName;//窗口类名
|
||
wndClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);//窗口标题图标
|
||
|
||
return RegisterClassExW(&wndClass);
|
||
}
|
||
|
||
BOOL Window::createWindow(HINSTANCE hInstance)
|
||
{
|
||
mWindowInst = hInstance;
|
||
|
||
/*
|
||
* WS_POPUP:不需要标题栏,则不需要边框
|
||
* WS_OVERLAPPEDWINDOW:拥有普通程序主窗口的所有特点,必须有标题且有边框
|
||
*
|
||
* WS_CLIPSIBLINGS:被兄弟窗口挡住区域不绘制
|
||
* WS_CLIPCHILDREN:被子窗口遮挡住的区域不绘制
|
||
*/
|
||
|
||
auto dwExStyle = WS_EX_APPWINDOW;
|
||
auto dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||
|
||
//由于存在标题栏等,所以需要计算中间显示区域的大小,比如PopUp的窗体,就没有标题栏,则不会改变
|
||
RECT windowRect;
|
||
windowRect.left = 0L;
|
||
windowRect.top = 0L;
|
||
windowRect.right = (long)mWidth;
|
||
windowRect.bottom = (long)mHeight;
|
||
AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);
|
||
|
||
mHwnd = CreateWindowW(
|
||
mWindowClassName,
|
||
(LPCWSTR)"doom", //窗体标题
|
||
dwStyle,
|
||
400,//x位置,相对左上角
|
||
200,//y位置,相对左上角
|
||
windowRect.right - windowRect.left,
|
||
windowRect.bottom - windowRect.top,
|
||
nullptr,//父窗体
|
||
nullptr,//菜单栏
|
||
hInstance,//程序实例
|
||
nullptr);//额外参数
|
||
|
||
|
||
if (!mHwnd)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
ShowWindow(mHwnd, true);
|
||
UpdateWindow(mHwnd);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void Window::peekMessage() {
|
||
MSG msg;
|
||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||
{
|
||
TranslateMessage(&msg);
|
||
DispatchMessage(&msg);
|
||
}
|
||
}
|
||
|
||
void Window::handleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||
switch (message)
|
||
{
|
||
case WM_CLOSE:
|
||
{
|
||
DestroyWindow(hWnd);//此处销毁窗体,会自动发出WM_DESTROY
|
||
break;
|
||
}
|
||
case WM_PAINT:
|
||
{
|
||
PAINTSTRUCT ps;
|
||
HDC hdc = BeginPaint(hWnd, &ps);
|
||
EndPaint(hWnd, &ps);
|
||
break;
|
||
}
|
||
case WM_DESTROY:
|
||
{
|
||
PostQuitMessage(0);//发出线程终止请求
|
||
mAlive = false;
|
||
break;
|
||
}
|
||
/*case WM_SIZING:
|
||
{
|
||
int newWidth = LOWORD(lParam);
|
||
int newHeight = HIWORD(lParam);
|
||
std::cout<<newWidth<<" "<<newHeight<<std::endl;
|
||
}*/
|
||
default:
|
||
{
|
||
m_input.HandelInput(hWnd, message, wParam, lParam);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Window::swapBuffer() {
|
||
BitBlt(mhDC, 0, 0, mWidth, mHeight, mCanvasDC, 0, 0, SRCCOPY);
|
||
} |