aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/PlatWin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'win32/PlatWin.cxx')
-rw-r--r--win32/PlatWin.cxx59
1 files changed, 38 insertions, 21 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index f09cdfcf1..d4d7b8026 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -243,6 +243,14 @@ void SetWindowPointer(HWND hWnd, void *ptr) noexcept {
namespace {
+using GetDpiForWindowSig = UINT(WINAPI *)(HWND hwnd);
+GetDpiForWindowSig fnGetDpiForWindow = nullptr;
+
+void LoadDpiForWindow() noexcept {
+ HMODULE user32 = ::GetModuleHandleW(L"user32.dll");
+ fnGetDpiForWindow = DLLFunction<GetDpiForWindowSig>(user32, "GetDpiForWindow");
+}
+
HINSTANCE hinstPlatformRes {};
HCURSOR reverseArrowCursor {};
@@ -415,6 +423,16 @@ public:
};
typedef VarBuffer<XYPOSITION, stackBufferLength> TextPositions;
+UINT DpiForWindow(WindowID wid) noexcept {
+ if (fnGetDpiForWindow) {
+ return fnGetDpiForWindow(HwndFromWindowID(wid));
+ }
+ HDC hdcMeasure = ::CreateCompatibleDC({});
+ const UINT scale = ::GetDeviceCaps(hdcMeasure, LOGPIXELSY);
+ ::DeleteDC(hdcMeasure);
+ return scale;
+}
+
class SurfaceGDI : public Surface {
bool unicodeMode=false;
HDC hdc{};
@@ -426,6 +444,9 @@ class SurfaceGDI : public Surface {
HFONT fontOld{};
HBITMAP bitmap{};
HBITMAP bitmapOld{};
+
+ int logPixelsY = 72;
+
int maxWidthMeasure = INT_MAX;
// There appears to be a 16 bit string length limit in GDI on NT.
int maxLenText = 65535;
@@ -537,20 +558,22 @@ bool SurfaceGDI::Initialised() {
return hdc != 0;
}
-void SurfaceGDI::Init(WindowID) {
+void SurfaceGDI::Init(WindowID wid) {
Release();
hdc = ::CreateCompatibleDC({});
hdcOwned = true;
::SetTextAlign(hdc, TA_BASELINE);
+ logPixelsY = DpiForWindow(wid);
}
-void SurfaceGDI::Init(SurfaceID sid, WindowID) {
+void SurfaceGDI::Init(SurfaceID sid, WindowID wid) {
Release();
hdc = static_cast<HDC>(sid);
::SetTextAlign(hdc, TA_BASELINE);
+ logPixelsY = DpiForWindow(wid);
}
-void SurfaceGDI::InitPixMap(int width, int height, Surface *surface_, WindowID) {
+void SurfaceGDI::InitPixMap(int width, int height, Surface *surface_, WindowID wid) {
Release();
SurfaceGDI *psurfOther = dynamic_cast<SurfaceGDI *>(surface_);
// Should only ever be called with a SurfaceGDI, not a SurfaceD2D
@@ -562,6 +585,7 @@ void SurfaceGDI::InitPixMap(int width, int height, Surface *surface_, WindowID)
::SetTextAlign(hdc, TA_BASELINE);
SetUnicodeMode(psurfOther->unicodeMode);
SetDBCSMode(psurfOther->codePage);
+ logPixelsY = DpiForWindow(wid);
}
void SurfaceGDI::PenColour(ColourDesired fore) {
@@ -599,7 +623,7 @@ void SurfaceGDI::SetFont(const Font &font_) noexcept {
}
int SurfaceGDI::LogPixelsY() {
- return ::GetDeviceCaps(hdc, LOGPIXELSY);
+ return logPixelsY;
}
int SurfaceGDI::DeviceHeightFont(int points) {
@@ -992,8 +1016,6 @@ class SurfaceD2D : public Surface {
ID2D1SolidColorBrush *pBrush;
int logPixelsY;
- float dpiScaleX;
- float dpiScaleY;
void Clear() noexcept;
void SetFont(const Font &font_);
@@ -1007,7 +1029,7 @@ public:
SurfaceD2D &operator=(SurfaceD2D &&) = delete;
~SurfaceD2D() override;
- void SetScale();
+ void SetScale(WindowID wid);
void Init(WindowID wid) override;
void Init(SurfaceID sid, WindowID wid) override;
void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override;
@@ -1078,8 +1100,6 @@ SurfaceD2D::SurfaceD2D() noexcept :
pBrush = nullptr;
logPixelsY = 72;
- dpiScaleX = 1.0;
- dpiScaleY = 1.0;
}
SurfaceD2D::~SurfaceD2D() {
@@ -1110,12 +1130,8 @@ void SurfaceD2D::Release() {
Clear();
}
-void SurfaceD2D::SetScale() {
- HDC hdcMeasure = ::CreateCompatibleDC({});
- logPixelsY = ::GetDeviceCaps(hdcMeasure, LOGPIXELSY);
- dpiScaleX = ::GetDeviceCaps(hdcMeasure, LOGPIXELSX) / 96.0f;
- dpiScaleY = logPixelsY / 96.0f;
- ::DeleteDC(hdcMeasure);
+void SurfaceD2D::SetScale(WindowID wid) {
+ logPixelsY = DpiForWindow(wid);
}
bool SurfaceD2D::Initialised() {
@@ -1126,20 +1142,20 @@ HRESULT SurfaceD2D::FlushDrawing() {
return pRenderTarget->Flush();
}
-void SurfaceD2D::Init(WindowID /* wid */) {
+void SurfaceD2D::Init(WindowID wid) {
Release();
- SetScale();
+ SetScale(wid);
}
-void SurfaceD2D::Init(SurfaceID sid, WindowID) {
+void SurfaceD2D::Init(SurfaceID sid, WindowID wid) {
Release();
- SetScale();
+ SetScale(wid);
pRenderTarget = static_cast<ID2D1RenderTarget *>(sid);
}
-void SurfaceD2D::InitPixMap(int width, int height, Surface *surface_, WindowID) {
+void SurfaceD2D::InitPixMap(int width, int height, Surface *surface_, WindowID wid) {
Release();
- SetScale();
+ SetScale(wid);
SurfaceD2D *psurfOther = dynamic_cast<SurfaceD2D *>(surface_);
// Should only ever be called with a SurfaceD2D, not a SurfaceGDI
PLATFORM_ASSERT(psurfOther);
@@ -3312,6 +3328,7 @@ void Platform::Assert(const char *c, const char *file, int line) {
void Platform_Initialise(void *hInstance) {
hinstPlatformRes = static_cast<HINSTANCE>(hInstance);
+ LoadDpiForWindow();
LoadReverseArrowCursor();
ListBoxX_Register();
}