Files
XCEngine/new_editor/app/Host/WindowMessageDispatcher.cpp

116 lines
3.1 KiB
C++

#include "WindowMessageDispatcher.h"
#include "../Application.h"
namespace XCEngine::UI::Editor::Host {
namespace {
constexpr UINT kDeferredRenderMessage = WM_APP + 1u;
void TryEnableNonClientDpiScaling(HWND hwnd) {
if (hwnd == nullptr) {
return;
}
const HMODULE user32 = GetModuleHandleW(L"user32.dll");
if (user32 == nullptr) {
return;
}
using EnableNonClientDpiScalingFn = BOOL(WINAPI*)(HWND);
const auto enableNonClientDpiScaling =
reinterpret_cast<EnableNonClientDpiScalingFn>(
GetProcAddress(user32, "EnableNonClientDpiScaling"));
if (enableNonClientDpiScaling != nullptr) {
enableNonClientDpiScaling(hwnd);
}
}
} // namespace
Application* WindowMessageDispatcher::GetApplicationFromWindow(HWND hwnd) {
return reinterpret_cast<Application*>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
}
bool WindowMessageDispatcher::TryHandleNonClientCreate(
HWND hwnd,
UINT message,
LPARAM lParam,
LRESULT& outResult) {
if (message != WM_NCCREATE) {
return false;
}
TryEnableNonClientDpiScaling(hwnd);
const auto* createStruct = reinterpret_cast<CREATESTRUCTW*>(lParam);
auto* application = reinterpret_cast<Application*>(createStruct->lpCreateParams);
SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(application));
outResult = TRUE;
return true;
}
bool WindowMessageDispatcher::TryDispatch(
Application& application,
UINT message,
WPARAM wParam,
LPARAM lParam,
LRESULT& outResult) {
switch (message) {
case WM_SETCURSOR:
if (LOWORD(lParam) == HTCLIENT && application.ApplyCurrentCursor()) {
outResult = TRUE;
return true;
}
return false;
case WM_DPICHANGED:
if (lParam == 0) {
return false;
}
application.OnDpiChanged(
static_cast<UINT>(LOWORD(wParam)),
*reinterpret_cast<const RECT*>(lParam));
RequestDeferredRenderFrame(application);
outResult = 0;
return true;
case WM_ENTERSIZEMOVE:
application.OnEnterSizeMove();
outResult = 0;
return true;
case WM_EXITSIZEMOVE:
application.OnExitSizeMove();
RequestDeferredRenderFrame(application);
outResult = 0;
return true;
case WM_SIZE:
if (wParam != SIZE_MINIMIZED) {
application.OnResize();
RequestDeferredRenderFrame(application);
}
outResult = 0;
return true;
case kDeferredRenderMessage:
application.OnDeferredRenderMessage();
outResult = 0;
return true;
case WM_PAINT:
application.OnPaintMessage();
outResult = 0;
return true;
default:
return false;
}
}
void WindowMessageDispatcher::RequestDeferredRenderFrame(Application& application) {
if (application.m_hwnd == nullptr ||
!IsWindow(application.m_hwnd) ||
!application.m_hostRuntime.TryQueueDeferredRender()) {
return;
}
PostMessageW(application.m_hwnd, kDeferredRenderMessage, 0, 0);
}
} // namespace XCEngine::UI::Editor::Host