Add Music fluctuations project and Chinese plan docs
This commit is contained in:
176
MVS/Music fluctuations/source/window/Window.cpp
Normal file
176
MVS/Music fluctuations/source/window/Window.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user