diff options
| -rw-r--r-- | win32/PlatWin.cxx | 46 | ||||
| -rw-r--r-- | win32/PlatWin.h | 6 | ||||
| -rw-r--r-- | win32/ScintillaWin.cxx | 13 | 
3 files changed, 46 insertions, 19 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; diff --git a/win32/PlatWin.h b/win32/PlatWin.h index 5ce12b6c0..f8a7ba98a 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -10,6 +10,10 @@  namespace Scintilla { +#ifndef USER_DEFAULT_SCREEN_DPI +#define USER_DEFAULT_SCREEN_DPI		96 +#endif +  extern void Platform_Initialise(void *hInstance);  extern void Platform_Finalise(bool fromDllMain); @@ -54,6 +58,8 @@ T DLLFunction(HMODULE hModule, LPCSTR lpProcName) noexcept {  UINT DpiForWindow(WindowID wid) noexcept; +int SystemMetricsForDpi(int nIndex, UINT dpi) noexcept; +  #if defined(USE_D2D)  extern bool LoadD2D();  extern ID2D1Factory *pD2DFactory; diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 9b1d640f2..cd56105d0 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -286,7 +286,7 @@ class ScintillaWin :  	unsigned int linesPerScroll;	///< Intellimouse support  	int wheelDelta; ///< Wheel delta from roll -	UINT dpi = 72; +	UINT dpi = USER_DEFAULT_SCREEN_DPI;  	HRGN hRgnUpdate; @@ -658,8 +658,8 @@ bool ScintillaWin::DragThreshold(Point ptStart, Point ptNow) {  	const Point ptDifference = ptStart - ptNow;  	const XYPOSITION xMove = std::trunc(std::abs(ptDifference.x));  	const XYPOSITION yMove = std::trunc(std::abs(ptDifference.y)); -	return (xMove > ::GetSystemMetrics(SM_CXDRAG)) || -		(yMove > ::GetSystemMetrics(SM_CYDRAG)); +	return (xMove > SystemMetricsForDpi(SM_CXDRAG, dpi)) || +		(yMove > SystemMetricsForDpi(SM_CYDRAG, dpi));  }  void ScintillaWin::StartDrag() { @@ -2824,13 +2824,8 @@ void ScintillaWin::ImeStartComposition() {  			int sizeZoomed = vs.styles[styleHere].size + vs.zoomLevel * SC_FONT_SIZE_MULTIPLIER;  			if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER)	// Hangs if sizeZoomed <= 1  				sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER; -			AutoSurface surface(this); -			int deviceHeight = sizeZoomed; -			if (surface) { -				deviceHeight = (sizeZoomed * surface->LogPixelsY()) / 72; -			}  			// The negative is to allow for leading -			lf.lfHeight = -(std::abs(deviceHeight / SC_FONT_SIZE_MULTIPLIER)); +			lf.lfHeight = -::MulDiv(sizeZoomed, dpi, 72*SC_FONT_SIZE_MULTIPLIER);  			lf.lfWeight = vs.styles[styleHere].weight;  			lf.lfItalic = vs.styles[styleHere].italic ? 1 : 0;  			lf.lfCharSet = DEFAULT_CHARSET;  | 
