Add Music fluctuations project and Chinese plan docs

This commit is contained in:
2026-03-21 15:55:54 +08:00
parent 629455df07
commit a172d75e36
462 changed files with 382904 additions and 0 deletions

View 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;
}
//初始化画布
/*
* 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);
}