Files
msime-windows/ui/tests/src/test_device_resources.cpp
T

84 lines
2.7 KiB
C++

#include "tests/includes/test_framework.h"
#include "msimeui/DeviceResources.h"
#include <cmath>
#include <cstdio>
namespace
{
class HiddenWindow
{
public:
HiddenWindow()
{
REQUIRE(SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)));
hwnd = CreateWindowExW(WS_EX_NOREDIRECTIONBITMAP, L"STATIC", L"DPI resource test", WS_POPUP, 0, 0, 256, 128,
nullptr, nullptr, GetModuleHandleW(nullptr), nullptr);
REQUIRE(hwnd != nullptr);
}
~HiddenWindow()
{
DestroyWindow(hwnd);
CoUninitialize();
}
HWND hwnd = nullptr;
};
void CheckReusedTargetDpi(bool composition)
{
HiddenWindow window;
msimeui::DeviceResources resources;
const auto ensure = [&]() {
return composition ? resources.EnsureForComposition(window.hwnd) : resources.EnsureForWindow(window.hwnd);
};
REQUIRE(ensure());
ID2D1RenderTarget *const target = resources.GetRenderTarget();
REQUIRE(target != nullptr);
const float windowDpi = static_cast<float>(GetDpiForWindow(window.hwnd));
// Reproduce the retained render target from the previous monitor DPI without
// changing the user's display settings. Reuse must refresh DPI, not recreate it.
for (const float previousDpi : {windowDpi / 2.0f, 96.0f, 120.0f, 144.0f, 192.0f, windowDpi * 2.0f})
{
target->SetDpi(previousDpi, previousDpi);
REQUIRE(ensure());
REQUIRE(resources.GetRenderTarget() == target);
float dpiX = 0.0f;
float dpiY = 0.0f;
target->GetDpi(&dpiX, &dpiY);
std::printf("%s retained DPI %.0f -> window %.0f, target %.0f/%.0f\n", composition ? "composition" : "HWND",
previousDpi, windowDpi, dpiX, dpiY);
REQUIRE_NEAR(dpiX, windowDpi);
REQUIRE_NEAR(dpiY, windowDpi);
const D2D1_SIZE_F size = target->GetSize();
const D2D1_SIZE_U pixels = target->GetPixelSize();
REQUIRE_NEAR(size.width, pixels.width * 96.0f / windowDpi);
REQUIRE_NEAR(size.height, pixels.height * 96.0f / windowDpi);
}
// A smaller client area also reuses the larger composition surface.
REQUIRE(SetWindowPos(window.hwnd, nullptr, 0, 0, 128, 64, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE));
target->SetDpi(windowDpi * 1.25f, windowDpi * 1.25f);
REQUIRE(ensure());
REQUIRE(resources.GetRenderTarget() == target);
float dpiX = 0.0f;
float dpiY = 0.0f;
target->GetDpi(&dpiX, &dpiY);
REQUIRE_NEAR(dpiX, windowDpi);
REQUIRE_NEAR(dpiY, windowDpi);
}
} // namespace
TEST_CASE(hwnd_target_refreshes_dpi_when_reused)
{
CheckReusedTargetDpi(false);
}
TEST_CASE(composition_target_refreshes_dpi_when_reused)
{
CheckReusedTargetDpi(true);
}