diff options
author | Zufu Liu <unknown> | 2020-05-27 09:07:07 +1000 |
---|---|---|
committer | Zufu Liu <unknown> | 2020-05-27 09:07:07 +1000 |
commit | 24501ccaa7e7e9e66cafbe0d1e2cc27c32af9e73 (patch) | |
tree | f150248c62dd98756e0d84d8b84e5ded1ffcbdf0 | |
parent | 7164b4855d19b72aa3460b851f9989ffa8cf6f91 (diff) | |
download | scintilla-mirror-24501ccaa7e7e9e66cafbe0d1e2cc27c32af9e73.tar.gz |
Bug [#2063]. Add SystemMetricsForDpi and use for ListBox and mouse drag and drop.
Simplify IME font definition.
-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; |