Files
XCEngine/MVS/Music fluctuations/source/window/Window.cpp

176 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}
//初始化画布
/*
* DCDevice Context 设备上下文描述对象
* 每个窗口都有自己对应的设备区域映射即mhDC
* 这里创建一个与本窗口兼容的DCmCanvasDC
* 可以从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);
}