aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorZufu Liu <unknown>2020-05-27 09:07:07 +1000
committerZufu Liu <unknown>2020-05-27 09:07:07 +1000
commit24501ccaa7e7e9e66cafbe0d1e2cc27c32af9e73 (patch)
treef150248c62dd98756e0d84d8b84e5ded1ffcbdf0
parent7164b4855d19b72aa3460b851f9989ffa8cf6f91 (diff)
downloadscintilla-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.cxx46
-rw-r--r--win32/PlatWin.h6
-rw-r--r--win32/ScintillaWin.cxx13
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;