116 lines
3.1 KiB
C++
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
|