diff options
Diffstat (limited to 'win32/PlatWin.cxx')
| -rw-r--r-- | win32/PlatWin.cxx | 46 | 
1 files changed, 36 insertions, 10 deletions
| diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index b1e08782d..0dd7cc549 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -243,12 +243,29 @@ void SetWindowPointer(HWND hWnd, void *ptr) noexcept {  namespace { +// system DPI, same for all monitor. +UINT uSystemDPI = USER_DEFAULT_SCREEN_DPI; +  using GetDpiForWindowSig = UINT(WINAPI *)(HWND hwnd);  GetDpiForWindowSig fnGetDpiForWindow = nullptr; +using GetSystemMetricsForDpiSig = int(WINAPI *)(int nIndex, UINT dpi); +GetSystemMetricsForDpiSig fnGetSystemMetricsForDpi = nullptr; +  void LoadDpiForWindow() noexcept {  	HMODULE user32 = ::GetModuleHandleW(L"user32.dll");  	fnGetDpiForWindow = DLLFunction<GetDpiForWindowSig>(user32, "GetDpiForWindow"); +	fnGetSystemMetricsForDpi = DLLFunction<GetSystemMetricsForDpiSig>(user32, "GetSystemMetricsForDpi"); + +	using GetDpiForSystemSig = UINT(WINAPI *)(void); +	GetDpiForSystemSig fnGetDpiForSystem = DLLFunction<GetDpiForSystemSig>(user32, "GetDpiForSystem"); +	if (fnGetDpiForSystem) { +		uSystemDPI = fnGetDpiForSystem(); +	} else { +		HDC hdcMeasure = ::CreateCompatibleDC({}); +		uSystemDPI = ::GetDeviceCaps(hdcMeasure, LOGPIXELSY); +		::DeleteDC(hdcMeasure); +	}  }  HINSTANCE hinstPlatformRes {}; @@ -427,10 +444,17 @@ UINT DpiForWindow(WindowID wid) noexcept {  	if (fnGetDpiForWindow) {  		return fnGetDpiForWindow(HwndFromWindowID(wid));  	} -	HDC hdcMeasure = ::CreateCompatibleDC({}); -	const UINT scale = ::GetDeviceCaps(hdcMeasure, LOGPIXELSY); -	::DeleteDC(hdcMeasure); -	return scale; +	return uSystemDPI; +} + +int SystemMetricsForDpi(int nIndex, UINT dpi) noexcept { +	if (fnGetSystemMetricsForDpi) { +		return fnGetSystemMetricsForDpi(nIndex, dpi); +	} + +	int value = ::GetSystemMetrics(nIndex); +	value = (dpi == uSystemDPI) ? value : ::MulDiv(value, dpi, uSystemDPI); +	return value;  }  class SurfaceGDI : public Surface { @@ -445,7 +469,7 @@ class SurfaceGDI : public Surface {  	HBITMAP bitmap{};  	HBITMAP bitmapOld{}; -	int logPixelsY = 72; +	int logPixelsY = USER_DEFAULT_SCREEN_DPI;  	int maxWidthMeasure = INT_MAX;  	// There appears to be a 16 bit string length limit in GDI on NT. @@ -1099,7 +1123,7 @@ SurfaceD2D::SurfaceD2D() noexcept :  	pBrush = nullptr; -	logPixelsY = 72; +	logPixelsY = USER_DEFAULT_SCREEN_DPI;  }  SurfaceD2D::~SurfaceD2D() { @@ -2370,6 +2394,7 @@ class ListBoxX : public ListBox {  	unsigned int aveCharWidth;  	Window *parent;  	int ctrlID; +	UINT dpi;  	IListBoxDelegate *delegate;  	const char *widestItem;  	unsigned int maxCharWidth; @@ -2405,7 +2430,7 @@ class ListBoxX : public ListBox {  public:  	ListBoxX() : lineHeight(10), fontCopy{}, technology(0), lb{}, unicodeMode(false),  		desiredVisibleRows(9), maxItemCharacters(0), aveCharWidth(8), -		parent(nullptr), ctrlID(0), +		parent(nullptr), ctrlID(0), dpi(USER_DEFAULT_SCREEN_DPI),  		delegate(nullptr),  		widestItem(nullptr), maxCharWidth(1), resizeHit(0), wheelDelta(0) {  	} @@ -2462,6 +2487,7 @@ void ListBoxX::Create(Window &parent_, int ctrlID_, Point location_, int lineHei  		hinstanceParent,  		this); +	dpi = DpiForWindow(wid);  	POINT locationw = POINTFromPoint(location);  	::MapWindowPoints(hwndParent, NULL, &locationw, 1);  	location = PointFromPOINT(locationw); @@ -2529,7 +2555,7 @@ PRectangle ListBoxX::GetDesiredRect() {  	rcDesired.right = rcDesired.left + TextOffset() + width + (TextInset.x * 2);  	if (Length() > rows) -		rcDesired.right += ::GetSystemMetrics(SM_CXVSCROLL); +		rcDesired.right += SystemMetricsForDpi(SM_CXVSCROLL, dpi);  	AdjustWindowRect(&rcDesired);  	return rcDesired; @@ -2770,7 +2796,7 @@ POINT ListBoxX::MaxTrackSize() const {  	PRectangle rc = PRectangle::FromInts(0, 0,  		std::max(static_cast<unsigned int>(MinClientWidth()),  		maxCharWidth * maxItemCharacters + static_cast<int>(TextInset.x) * 2 + -		 TextOffset() + ::GetSystemMetrics(SM_CXVSCROLL)), +		 TextOffset() + SystemMetricsForDpi(SM_CXVSCROLL, dpi)),  		ItemHeight() * lti.Count());  	AdjustWindowRect(&rc);  	POINT ret = {static_cast<LONG>(rc.Width()), static_cast<LONG>(rc.Height())}; @@ -2879,7 +2905,7 @@ LRESULT ListBoxX::NcHitTest(WPARAM wParam, LPARAM lParam) const {  	// window caption height + frame, even if one is hovering over the bottom edge of  	// the frame, so workaround that here  	if (hit >= HTTOP && hit <= HTTOPRIGHT) { -		const int minHeight = GetSystemMetrics(SM_CYMINTRACK); +		const int minHeight = SystemMetricsForDpi(SM_CYMINTRACK, dpi);  		const int yPos = GET_Y_LPARAM(lParam);  		if ((rc.Height() < minHeight) && (yPos > ((rc.top + rc.bottom)/2))) {  			hit += HTBOTTOM - HTTOP; | 
