From 2b7f05d928b33f4c49be1ed2b266650afd1e2714 Mon Sep 17 00:00:00 2001 From: EmsiaetKadosh Date: Tue, 14 Jan 2025 22:33:05 +0800 Subject: [PATCH] Changes --- .clang-format | 2 +- CMakeLists.txt | 11 ++++- Game.cpp | 5 +++ Game.h | 33 +++++++++++++++ Hud.cpp | 7 ++++ Hud.h | 12 ++++++ InteractManager.h | 31 ++++++++++++-- Renderer.cpp | 7 ++++ Renderer.h | 31 ++++++++++++++ Window.cpp | 5 +++ Window.h | 27 ++++++++++++ hbp.h | 7 +--- includes.h | 15 +++++++ main.cpp | 104 +++++++++++++++++++++++++++++++++------------- 14 files changed, 257 insertions(+), 40 deletions(-) create mode 100644 Game.cpp create mode 100644 Game.h create mode 100644 Hud.cpp create mode 100644 Hud.h create mode 100644 Renderer.cpp create mode 100644 Renderer.h create mode 100644 Window.cpp create mode 100644 Window.h create mode 100644 includes.h diff --git a/.clang-format b/.clang-format index 48949df..847c9ec 100644 --- a/.clang-format +++ b/.clang-format @@ -46,7 +46,7 @@ AllowAllArgumentsOnNextLine: true # 如果false,强制把函数参数每个换 AllowAllParametersOfDeclarationOnNextLine: true # 如果false,强制把函数形参每个换行 AllowBreakBeforeNoexceptSpecifier: Always # 是否允许复合noexcept换行 Never|OnlyWithParen AllowShortBlocksOnASingleLine: Always # WIN Always, Empty|Never -AllowShortCaseLabelsOnASingleLine: true # WIN true, false +AllowShortCaseLabelsOnASingleLine: false # WIN true, false AllowShortCompoundRequirementOnASingleLine: true # BTW true, false AllowShortEnumsOnASingleLine: true # WIN true, false AllowShortFunctionsOnASingleLine: All # WIN All, None|InlineOnly|Empty|Inline diff --git a/CMakeLists.txt b/CMakeLists.txt index 10125be..460bcd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,16 @@ enable_testing() add_executable(${PROJECT_NAME} main.cpp def.h InteractManager.cpp - InteractManager.h) + InteractManager.h + Renderer.cpp + Renderer.h + Game.cpp + Game.h + Window.cpp + Window.h + Hud.cpp + Hud.h + includes.h) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack) diff --git a/Game.cpp b/Game.cpp new file mode 100644 index 0000000..d9b697c --- /dev/null +++ b/Game.cpp @@ -0,0 +1,5 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#include "Game.h" diff --git a/Game.h b/Game.h new file mode 100644 index 0000000..85e6790 --- /dev/null +++ b/Game.h @@ -0,0 +1,33 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#pragma once + +#include "Hud.h" +#include "InteractManager.h" +#include "Renderer.h" +#include "Window.h" + +class Game { + Hud hud = Hud(); + Window* window = nullptr; + +public: + explicit Game() = default; + + void render() const noexcept { + if (window) window->render(); + hud.render(); + } + + void setWindow(Window* window) noexcept { + if (this->window == window) return; + if (this->window) this->window->onClose(); + this->window = nullptr; + if (window && window->onOpen()) + this->window = window; + } +}; + +inline static Game game = Game(); diff --git a/Hud.cpp b/Hud.cpp new file mode 100644 index 0000000..7a0a998 --- /dev/null +++ b/Hud.cpp @@ -0,0 +1,7 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#include "Hud.h" + +void Hud::render() const noexcept {} diff --git a/Hud.h b/Hud.h new file mode 100644 index 0000000..f309118 --- /dev/null +++ b/Hud.h @@ -0,0 +1,12 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#pragma once +#include "Renderer.h" + +class Hud : public Renderable { +public: + void render() const noexcept override; +}; + diff --git a/InteractManager.h b/InteractManager.h index 588dd36..b314e1b 100644 --- a/InteractManager.h +++ b/InteractManager.h @@ -5,6 +5,7 @@ #pragma once #include "def.h" +#include "hbp.h" struct KeyStatus { String name; @@ -26,13 +27,22 @@ struct KeyStatus { struct KeyBinding; class InteractManager { + inline static TRACKMOUSEEVENT trackMouseEvent{ + .cbSize = sizeof(TRACKMOUSEEVENT), + .dwFlags = TME_HOVER | TME_LEAVE | TME_NONCLIENT, + .hwndTrack = nullptr, + .dwHoverTime = 0 + }; KeyStatus keyStatus[256]; int mouseX = 0, mouseY = 0; int mouseWheel = 0; int rebindResult = 0; bool rebinding = false; - bool inWindow = false; // 鼠标是否在窗口内部 + bool inWindow = false;// 鼠标是否在窗口内部 + bool hovering = false; + public: + static void initialize() noexcept { trackMouseEvent.hwndTrack = MainWindowHandle; } explicit InteractManager(); void update(const int keyCode, const bool isPressed) noexcept { @@ -51,14 +61,29 @@ public: void updateMouse(const int x, const int y) noexcept { mouseX = x; mouseY = y; - std::wcout << x << " " << y << std::endl; + inWindow = true; + hovering = false; + if (!TrackMouseEvent(&trackMouseEvent)) std::wcout << L"TrackMouseEvent failed. LastError: " << GetLastError() << std::endl; + } + + void mouseHover() noexcept { + hovering = true; + inWindow = true; + std::wcout << L"hover" << std::endl; + } + + void mouseLeave() noexcept { + inWindow = false; + hovering = false; + std::wcout << L"leave" << std::endl; } void updateWheel(const int wheel) noexcept { mouseWheel += wheel; } - [[nodiscard]] int getMouseX() const noexcept { return mouseX; } [[nodiscard]] int getMouseY() const noexcept { return mouseY; } [[nodiscard]] int getMouseWheel() const noexcept { return mouseWheel; } + [[nodiscard]] bool isHovering() const noexcept { return hovering; } + [[nodiscard]] bool isInWindow() const noexcept { return inWindow; } KeyStatus& getKey(const int keyCode) noexcept { return keyStatus[keyCode]; } KeyStatus& getKey(const KeyBinding& binding) noexcept; diff --git a/Renderer.cpp b/Renderer.cpp new file mode 100644 index 0000000..4a63515 --- /dev/null +++ b/Renderer.cpp @@ -0,0 +1,7 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#include "Renderer.h" + +void Renderer::initialize() noexcept { MainDC = GetDC(MainWindowHandle); } diff --git a/Renderer.h b/Renderer.h new file mode 100644 index 0000000..799abd0 --- /dev/null +++ b/Renderer.h @@ -0,0 +1,31 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#pragma once + +#include "def.h" + +interface Renderable { + virtual ~Renderable() = default; + virtual void render() const noexcept = 0; +}; + +class Renderer { + inline static HDC MainDC; + int windowWidth = 0, windowHeight = 0; + +public: + static void initialize() noexcept; + explicit Renderer() = default; + + void resize(const int width, const int height) noexcept(false) { + windowWidth = width; + windowHeight = height; + } + + [[nodiscard]] int getWidth() const noexcept { return windowWidth; } + [[nodiscard]] int getHeight() const noexcept { return windowHeight; } +}; + +inline static Renderer renderer = Renderer(); diff --git a/Window.cpp b/Window.cpp new file mode 100644 index 0000000..8d38040 --- /dev/null +++ b/Window.cpp @@ -0,0 +1,5 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#include "Window.h" diff --git a/Window.h b/Window.h new file mode 100644 index 0000000..64926e2 --- /dev/null +++ b/Window.h @@ -0,0 +1,27 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#pragma once + +#include "Renderer.h" + +class Window : public Renderable { +protected: + Window() = default; + +public: + /** + * 在Game.setWindow()时,本窗口开启时调用。 + * 不应当外部调用。 + * 如果返回false,则拒绝设置窗口。 + * @return 是否允许将显示窗口设为自身 + */ + virtual bool onOpen() = 0; + /** + * 在Game.setWindow()时,本窗口关闭时调用。 + * 不应当外部调用。 + * 注意,关闭未必就是删除。 + */ + virtual void onClose() = 0; +}; diff --git a/hbp.h b/hbp.h index bb4d142..8d21ccb 100644 --- a/hbp.h +++ b/hbp.h @@ -2,7 +2,6 @@ #include "def.h" - inline BOOL NewProcess(const String& cmdline) noexcept { STARTUPINFOW si = { sizeof(si), nullptr, nullptr, nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr @@ -13,7 +12,7 @@ inline BOOL NewProcess(const String& cmdline) noexcept { return CreateProcessW(nullptr, const_cast(cmdline.c_str()), nullptr, nullptr, 0, 0, nullptr, nullptr, &si, &pi); } -inline HRESULT RemoveDefaultCaption(HWND const hWnd, const MARGINS* p) noexcept { return DwmExtendFrameIntoClientArea(hWnd, p); } +inline HRESULT RemoveDefaultCaption(HWND hWnd, const MARGINS* p) noexcept { return DwmExtendFrameIntoClientArea(hWnd, p); } inline void ShowConsoleIO() noexcept { AllocConsole(); @@ -26,7 +25,3 @@ inline void ShowConsoleIO() noexcept { inline const String ApplicationName = L"Hyblud Presher"; inline HINSTANCE MainInstance; inline HWND MainWindowHandle; - -inline void Initialize() {} - -inline void Finalize() {} diff --git a/includes.h b/includes.h new file mode 100644 index 0000000..39ae2b3 --- /dev/null +++ b/includes.h @@ -0,0 +1,15 @@ +// +// Created by EmsiaetKadosh on 25-1-14. +// + +#pragma once + +#include "def.h" +#include "hbp.h" +#include "Renderer.h" +#include "InteractManager.h" + +#include "Hud.h" +#include "Window.h" + +#include "Game.h" diff --git a/main.cpp b/main.cpp index fcefc1d..dda43e7 100644 --- a/main.cpp +++ b/main.cpp @@ -1,47 +1,85 @@ -#include "hbp.h" -#include "InteractManager.h" +#include "includes.h" LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { _LIKELY case WM_PAINT: { PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwnd, &ps);// Paint caption + BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); break; } _LIKELY case WM_NCHITTEST: { + POINT point = { GET_X_LPARAM(lParam), (GET_Y_LPARAM(lParam)) }; + ScreenToClient(hwnd, &point); + const int xPos = point.x; + const int yPos = point.y; + if (xPos < 30) { + if (yPos < 30) return HTTOPLEFT; + if (renderer.getHeight() - yPos < 30) return HTBOTTOMLEFT; + return HTLEFT; + } + if (renderer.getWidth() - xPos < 30) { + if (yPos < 30) return HTTOPRIGHT; + if (renderer.getHeight() - yPos < 30) return HTBOTTOMRIGHT; + return HTBOTTOM; + } + if (yPos < 30) return HTTOP; + if (renderer.getHeight() - yPos < 30) return HTBOTTOM; + if (yPos < 240) return HTCAPTION; LRESULT lr = 0; - BOOL r = DwmDefWindowProc(hwnd, uMsg, wParam, lParam, &lr); + DwmDefWindowProc(hwnd, uMsg, wParam, lParam, &lr); return HTCLIENT; } - case WM_KEYDOWN: interactManager.update(static_cast(wParam), true); + case WM_KEYDOWN: + interactManager.update(static_cast(wParam), true); break; - case WM_KEYUP: interactManager.update(static_cast(wParam), false); + case WM_KEYUP: + interactManager.update(static_cast(wParam), false); break; - case WM_SYSKEYDOWN: interactManager.update(static_cast(wParam), true); + case WM_SYSKEYDOWN: + interactManager.update(static_cast(wParam), true); break; - case WM_SYSKEYUP: interactManager.update(static_cast(wParam), false); + case WM_SYSKEYUP: + interactManager.update(static_cast(wParam), false); break; - case WM_LBUTTONDOWN: interactManager.update(VK_LBUTTON, true); + case WM_LBUTTONDOWN: + interactManager.update(VK_LBUTTON, true); break; - case WM_RBUTTONDOWN: interactManager.update(VK_RBUTTON, true); + case WM_RBUTTONDOWN: + interactManager.update(VK_RBUTTON, true); break; - case WM_LBUTTONUP: interactManager.update(VK_LBUTTON, false); + case WM_LBUTTONUP: + interactManager.update(VK_LBUTTON, false); break; - case WM_RBUTTONUP: interactManager.update(VK_RBUTTON, false); + case WM_RBUTTONUP: + interactManager.update(VK_RBUTTON, false); break; - case WM_MOUSEMOVE: interactManager.updateMouse(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + case WM_MOUSEMOVE: + interactManager.updateMouse(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; - case WM_MBUTTONDOWN: if (wParam & 0x10) interactManager.update(VK_MBUTTON, true); + case WM_MBUTTONDOWN: + if (wParam & 0x10) interactManager.update(VK_MBUTTON, true); break; - case WM_MBUTTONUP: interactManager.update(VK_MBUTTON, false); + case WM_MBUTTONUP: + interactManager.update(VK_MBUTTON, false); break; - case WM_MOUSEWHEEL: interactManager.update(VK_MBUTTON, true); + case WM_MOUSEWHEEL: + interactManager.update(VK_MBUTTON, true); + interactManager.update(VK_MBUTTON, true); break; - case WM_COMMAND: std::wcout << L"WM_COMMAND" << std::endl; + case WM_MOUSEHOVER: + // case WM_NCMOUSEHOVER: + interactManager.mouseHover(); + break; + case WM_MOUSELEAVE: + // case WM_NCMOUSELEAVE: + interactManager.mouseLeave(); + break; + case WM_COMMAND: + std::wcout << L"WM_COMMAND" << std::endl; break; case WM_DWMCOMPOSITIONCHANGED: { MARGINS margins{ @@ -50,10 +88,11 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { .cyTopHeight = 0, .cyBottomHeight = 0 }; - HRESULT hr = RemoveDefaultCaption(hwnd, &margins); + RemoveDefaultCaption(hwnd, &margins); break; } - case WM_NCCALCSIZE: if (wParam == 1) { + case WM_NCCALCSIZE: + if (wParam == 1) { NCCALCSIZE_PARAMS* pncsp = reinterpret_cast(lParam); pncsp->rgrc[0].left = pncsp->rgrc[0].left + 0; pncsp->rgrc[0].top = pncsp->rgrc[0].top + 0; @@ -61,15 +100,19 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { pncsp->rgrc[0].bottom = pncsp->rgrc[0].bottom - 0; return 0; } - case WM_SIZE: switch (wParam) { + case WM_SIZE: { + renderer.resize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + switch (wParam) { case SIZE_RESTORED: case SIZE_MINIMIZED: case SIZE_MAXIMIZED: case SIZE_MAXSHOW: case SIZE_MAXHIDE: - default: break; + default: + break; } break; + } case WM_ACTIVATE: { constexpr MARGINS margins{ .cxLeftWidth = 0, @@ -81,20 +124,22 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { } break; _UNLIKELY - case WM_DESTROY: PostQuitMessage(0); + case WM_DESTROY: + PostQuitMessage(0); return 0; _UNLIKELY - case WM_CREATE: SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);// Force post NCCALCSIZE + case WM_CREATE: + SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);// Force post NCCALCSIZE + break; + default: break; - default: break; } return DefWindowProc(hwnd, uMsg, wParam, lParam); } int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { - AllocConsole(); - freopen("CONOUT$", "w", stdout); - WNDCLASSEX wc = { 0 }; + ShowConsoleIO(); + WNDCLASSEX wc = {}; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; @@ -111,8 +156,9 @@ int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCm MainInstance = hInstance; MainWindowHandle = CreateWindowExW(0, wc.lpszClassName, wc.lpszClassName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr); ShowWindow(MainWindowHandle, nCmdShow); - Initialize(); - HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(109)); + InteractManager::initialize(); + Renderer::initialize(); + HACCEL hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCE(109)); MSG msg = { nullptr }; while (GetMessageW(&msg, nullptr, 0, 0)) { if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) {