From 1e07bc3d3339a238b32d58f48b34e1581c7ae47a Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Mon, 23 Apr 2018 09:36:10 +0200 Subject: [PATCH] Use the improved DPIAware class from the sktoolslib Based on TortoiseSVN commit 28200 and commit 28204. Signed-off-by: Sven Strickroth --- src/TortoiseMerge/BaseView.cpp | 56 +++++----- src/TortoiseMerge/TortoiseMerge.vcxproj | 2 +- src/TortoiseMerge/TortoiseMerge.vcxproj.filters | 6 +- src/TortoiseUDiff/MainWindow.cpp | 13 +-- src/TortoiseUDiff/TortoiseUDiff.vcxproj | 1 + src/TortoiseUDiff/TortoiseUDiff.vcxproj.filters | 3 + src/Utils/DPIAware.h | 133 ++++++++++++++++++++++++ src/Utils/DpiScale.h | 43 -------- 8 files changed, 175 insertions(+), 82 deletions(-) create mode 100644 src/Utils/DPIAware.h delete mode 100644 src/Utils/DpiScale.h diff --git a/src/TortoiseMerge/BaseView.cpp b/src/TortoiseMerge/BaseView.cpp index d23f1f33b..869c3f30c 100644 --- a/src/TortoiseMerge/BaseView.cpp +++ b/src/TortoiseMerge/BaseView.cpp @@ -29,7 +29,7 @@ #include "GotoLineDlg.h" #include "EncodingDlg.h" #include "EditorConfigWrapper.h" -#include "DpiScale.h" +#include "DPIAware.h" // Note about lines: // We use three different kind of lines here: @@ -1644,7 +1644,6 @@ void CBaseView::DrawLineEnding(CDC *pDC, const CRect &rc, int nLineIndex, const } else { - CDpiScale dpi(pDC->GetSafeHdc()); CPen pen(PS_SOLID, 0, m_WhiteSpaceFg); CPen * oldpen = pDC->SelectObject(&pen); int yMiddle = origin.y + rc.Height()/2; @@ -1656,10 +1655,10 @@ void CBaseView::DrawLineEnding(CDC *pDC, const CRect &rc, int nLineIndex, const { // multiline bMultiline = true; - pDC->MoveTo(origin.x, yMiddle-dpi.ScaleY(2)); - pDC->LineTo(origin.x + GetCharWidth() - dpi.ScaleX(1), yMiddle - dpi.ScaleY(2)); - pDC->LineTo(origin.x + GetCharWidth() - dpi.ScaleX(1), yMiddle + dpi.ScaleY(2)); - pDC->LineTo(origin.x, yMiddle + dpi.ScaleY(2)); + pDC->MoveTo(origin.x, yMiddle - CDPIAware::Instance().ScaleY(2)); + pDC->LineTo(origin.x + GetCharWidth() - CDPIAware::Instance().ScaleX(1), yMiddle - CDPIAware::Instance().ScaleY(2)); + pDC->LineTo(origin.x + GetCharWidth() - CDPIAware::Instance().ScaleX(1), yMiddle + CDPIAware::Instance().ScaleY(2)); + pDC->LineTo(origin.x, yMiddle + CDPIAware::Instance().ScaleY(2)); } else if (GetLineLength(nLineIndex) == 0) bMultiline = true; @@ -1674,32 +1673,32 @@ void CBaseView::DrawLineEnding(CDC *pDC, const CRect &rc, int nLineIndex, const case EOL_AUTOLINE: case EOL_CRLF: // arrow from top to middle+2, then left - pDC->MoveTo(origin.x + GetCharWidth() - dpi.ScaleX(1), rc.top+dpi.ScaleY(1)); - pDC->LineTo(origin.x + GetCharWidth() - dpi.ScaleX(1), yMiddle); + pDC->MoveTo(origin.x + GetCharWidth() - CDPIAware::Instance().ScaleX(1), rc.top + CDPIAware::Instance().ScaleY(1)); + pDC->LineTo(origin.x + GetCharWidth() - CDPIAware::Instance().ScaleX(1), yMiddle); case EOL_CR: // arrow from right to left - pDC->MoveTo(origin.x + GetCharWidth() - dpi.ScaleX(1), yMiddle); + pDC->MoveTo(origin.x + GetCharWidth() - CDPIAware::Instance().ScaleX(1), yMiddle); pDC->LineTo(origin.x, yMiddle); - pDC->LineTo(origin.x + dpi.ScaleX(4), yMiddle + dpi.ScaleY(4)); + pDC->LineTo(origin.x + CDPIAware::Instance().ScaleX(4), yMiddle + CDPIAware::Instance().ScaleY(4)); pDC->MoveTo(origin.x, yMiddle); - pDC->LineTo(origin.x + dpi.ScaleX(4), yMiddle - dpi.ScaleY(4)); + pDC->LineTo(origin.x + CDPIAware::Instance().ScaleX(4), yMiddle - CDPIAware::Instance().ScaleY(4)); break; case EOL_LFCR: // from right-upper to left then down - pDC->MoveTo(origin.x + GetCharWidth() - dpi.ScaleX(1), yMiddle-dpi.ScaleY(2)); - pDC->LineTo(xMiddle, yMiddle - dpi.ScaleY(2)); - pDC->LineTo(xMiddle, rc.bottom - dpi.ScaleY(1)); - pDC->LineTo(xMiddle + dpi.ScaleX(4), rc.bottom - dpi.ScaleY(5)); - pDC->MoveTo(xMiddle, rc.bottom - dpi.ScaleY(1)); - pDC->LineTo(xMiddle - dpi.ScaleX(4), rc.bottom - dpi.ScaleY(5)); + pDC->MoveTo(origin.x + GetCharWidth() - CDPIAware::Instance().ScaleX(1), yMiddle - CDPIAware::Instance().ScaleY(2)); + pDC->LineTo(xMiddle, yMiddle - CDPIAware::Instance().ScaleY(2)); + pDC->LineTo(xMiddle, rc.bottom - CDPIAware::Instance().ScaleY(1)); + pDC->LineTo(xMiddle + CDPIAware::Instance().ScaleX(4), rc.bottom - CDPIAware::Instance().ScaleY(5)); + pDC->MoveTo(xMiddle, rc.bottom - CDPIAware::Instance().ScaleY(1)); + pDC->LineTo(xMiddle - CDPIAware::Instance().ScaleX(4), rc.bottom - CDPIAware::Instance().ScaleY(5)); break; case EOL_LF: // arrow from top to bottom pDC->MoveTo(xMiddle, rc.top); - pDC->LineTo(xMiddle, rc.bottom - dpi.ScaleY(1)); - pDC->LineTo(xMiddle + dpi.ScaleX(4), rc.bottom - dpi.ScaleY(5)); - pDC->MoveTo(xMiddle, rc.bottom - dpi.ScaleY(1)); - pDC->LineTo(xMiddle - dpi.ScaleX(4), rc.bottom - dpi.ScaleY(5)); + pDC->LineTo(xMiddle, rc.bottom - CDPIAware::Instance().ScaleY(1)); + pDC->LineTo(xMiddle + CDPIAware::Instance().ScaleX(4), rc.bottom - CDPIAware::Instance().ScaleY(5)); + pDC->MoveTo(xMiddle, rc.bottom - CDPIAware::Instance().ScaleY(1)); + pDC->LineTo(xMiddle - CDPIAware::Instance().ScaleX(4), rc.bottom - CDPIAware::Instance().ScaleY(5)); break; case EOL_FF: // Form Feed, U+000C case EOL_NEL: // Next Line, U+0085 @@ -2046,7 +2045,6 @@ void CBaseView::DrawSingleLine(CDC *pDC, const CRect &rc, int nLineIndex) int y = rc.top + (rc.bottom-rc.top)/2; xpos -= m_nOffsetChar * GetCharWidth(); - CDpiScale dpi(pDC->GetSafeHdc()); CPen pen(PS_SOLID, 0, m_WhiteSpaceFg); while (*pszChars) { @@ -2064,11 +2062,11 @@ void CBaseView::DrawSingleLine(CDC *pDC, const CRect &rc, int nLineIndex) if ((xposreal > 0) || (nSpaces > 0)) { CPen * oldPen = pDC->SelectObject(&pen); - pDC->MoveTo(xposreal + rc.left + dpi.ScaleX(2), y); - pDC->LineTo((xpos + nSpaces * GetCharWidth()) + rc.left - dpi.ScaleX(2), y); - pDC->LineTo((xpos + nSpaces * GetCharWidth()) + rc.left - dpi.ScaleX(6), y - dpi.ScaleY(4)); - pDC->MoveTo((xpos + nSpaces * GetCharWidth()) + rc.left - dpi.ScaleX(2), y); - pDC->LineTo((xpos + nSpaces * GetCharWidth()) + rc.left - dpi.ScaleX(6), y + dpi.ScaleY(4)); + pDC->MoveTo(xposreal + rc.left + CDPIAware::Instance().ScaleX(2), y); + pDC->LineTo((xpos + nSpaces * GetCharWidth()) + rc.left - CDPIAware::Instance().ScaleX(2), y); + pDC->LineTo((xpos + nSpaces * GetCharWidth()) + rc.left - CDPIAware::Instance().ScaleX(6), y - CDPIAware::Instance().ScaleY(4)); + pDC->MoveTo((xpos + nSpaces * GetCharWidth()) + rc.left - CDPIAware::Instance().ScaleX(2), y); + pDC->LineTo((xpos + nSpaces * GetCharWidth()) + rc.left - CDPIAware::Instance().ScaleX(6), y + CDPIAware::Instance().ScaleY(4)); pDC->SelectObject(oldPen); } } @@ -2082,8 +2080,8 @@ void CBaseView::DrawSingleLine(CDC *pDC, const CRect &rc, int nLineIndex) pLastSpace = pszChars + 1; if (xpos >= 0) { - const int cxWhitespace = dpi.ScaleX(2); - const int cyWhitespace = dpi.ScaleY(2); + const int cxWhitespace = CDPIAware::Instance().ScaleX(2); + const int cyWhitespace = CDPIAware::Instance().ScaleY(2); // draw 2-logical pixel rectangle, like Scintilla editor. pDC->FillSolidRect(xpos + rc.left + GetCharWidth() / 2 - cxWhitespace/2, y, cxWhitespace, cyWhitespace, m_WhiteSpaceFg); } diff --git a/src/TortoiseMerge/TortoiseMerge.vcxproj b/src/TortoiseMerge/TortoiseMerge.vcxproj index 926b4e2ad..fe12d8c88 100644 --- a/src/TortoiseMerge/TortoiseMerge.vcxproj +++ b/src/TortoiseMerge/TortoiseMerge.vcxproj @@ -320,7 +320,7 @@ - + diff --git a/src/TortoiseMerge/TortoiseMerge.vcxproj.filters b/src/TortoiseMerge/TortoiseMerge.vcxproj.filters index e3d54078c..faacdd594 100644 --- a/src/TortoiseMerge/TortoiseMerge.vcxproj.filters +++ b/src/TortoiseMerge/TortoiseMerge.vcxproj.filters @@ -566,12 +566,12 @@ SimpleIni - - Utils - Header Files + + Utils + diff --git a/src/TortoiseUDiff/MainWindow.cpp b/src/TortoiseUDiff/MainWindow.cpp index 8290d0808..e74b1f455 100644 --- a/src/TortoiseUDiff/MainWindow.cpp +++ b/src/TortoiseUDiff/MainWindow.cpp @@ -26,6 +26,7 @@ #include "CreateProcessHelper.h" #include "UDiffColors.h" #include "registry.h" +#include "DPIAware.h" const UINT TaskBarButtonCreated = RegisterWindowMessage(L"TaskbarButtonCreated"); @@ -113,11 +114,11 @@ LRESULT CALLBACK CMainWindow::WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, { ::SetWindowPos(m_hWndEdit, HWND_TOP, rect.left, rect.top, - rect.right-rect.left, rect.bottom-rect.top-30, + rect.right - rect.left, rect.bottom - rect.top - int(30 * CDPIAware::Instance().ScaleFactorY()), SWP_SHOWWINDOW); ::SetWindowPos(m_FindBar, HWND_TOP, - rect.left, rect.bottom-30, - rect.right-rect.left, 30, + rect.left, rect.bottom - int(30 * CDPIAware::Instance().ScaleFactorY()), + rect.right - rect.left, int(30 * CDPIAware::Instance().ScaleFactorY()), SWP_SHOWWINDOW); } else @@ -217,11 +218,11 @@ LRESULT CMainWindow::DoCommand(int id) GetClientRect(*this, &rect); ::SetWindowPos(m_hWndEdit, HWND_TOP, rect.left, rect.top, - rect.right-rect.left, rect.bottom-rect.top-30, + rect.right - rect.left, rect.bottom - rect.top - int(30 * CDPIAware::Instance().ScaleFactorY()), SWP_SHOWWINDOW); ::SetWindowPos(m_FindBar, HWND_TOP, - rect.left, rect.bottom-30, - rect.right-rect.left, 30, + rect.left, rect.bottom - int(30 * CDPIAware::Instance().ScaleFactorY()), + rect.right - rect.left, int(30 * CDPIAware::Instance().ScaleFactorY()), SWP_SHOWWINDOW); ::SetFocus(m_FindBar); SendEditor(SCI_SETSELECTIONSTART, 0); diff --git a/src/TortoiseUDiff/TortoiseUDiff.vcxproj b/src/TortoiseUDiff/TortoiseUDiff.vcxproj index ec5ba4836..132741f7b 100644 --- a/src/TortoiseUDiff/TortoiseUDiff.vcxproj +++ b/src/TortoiseUDiff/TortoiseUDiff.vcxproj @@ -64,6 +64,7 @@ + diff --git a/src/TortoiseUDiff/TortoiseUDiff.vcxproj.filters b/src/TortoiseUDiff/TortoiseUDiff.vcxproj.filters index 74edd2ab2..f43df9555 100644 --- a/src/TortoiseUDiff/TortoiseUDiff.vcxproj.filters +++ b/src/TortoiseUDiff/TortoiseUDiff.vcxproj.filters @@ -107,6 +107,9 @@ Utils + + Utils + diff --git a/src/Utils/DPIAware.h b/src/Utils/DPIAware.h new file mode 100644 index 000000000..3ce434f39 --- /dev/null +++ b/src/Utils/DPIAware.h @@ -0,0 +1,133 @@ +// TortoiseGit - a Windows shell extension for easy version control + +// Copyright (C) 2018 - TortoiseSVN + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +class CDPIAware +{ +private: + CDPIAware() : m_fInitialized(false), m_dpiX(96), m_dpiY(96) {} + ~CDPIAware() {} + +public: + static CDPIAware& Instance() + { + static CDPIAware instance; + return instance; + } + + // Get screen DPI. + int GetDPIX() { _Init(); return m_dpiX; } + int GetDPIY() { _Init(); return m_dpiY; } + + // Convert between raw pixels and relative pixels. + int ScaleX(int x) { _Init(); return MulDiv(x, m_dpiX, 96); } + int ScaleY(int y) { _Init(); return MulDiv(y, m_dpiY, 96); } + float ScaleFactorX() { _Init(); return m_dpiX / 96.0f; } + float ScaleFactorY() { _Init(); return m_dpiY / 96.0f; } + int UnscaleX(int x) { _Init(); return MulDiv(x, 96, m_dpiX); } + int UnscaleY(int y) { _Init(); return MulDiv(y, 96, m_dpiY); } + + // Determine the screen dimensions in relative pixels. + int ScaledScreenWidth() { return _ScaledSystemMetricX(SM_CXSCREEN); } + int ScaledScreenHeight() { return _ScaledSystemMetricY(SM_CYSCREEN); } + + // Scale rectangle from raw pixels to relative pixels. + void ScaleRect(__inout RECT *pRect) + { + pRect->left = ScaleX(pRect->left); + pRect->right = ScaleX(pRect->right); + pRect->top = ScaleY(pRect->top); + pRect->bottom = ScaleY(pRect->bottom); + } + + // Scale Point from raw pixels to relative pixels. + void ScalePoint(__inout POINT *pPoint) + { + pPoint->x = ScaleX(pPoint->x); + pPoint->y = ScaleY(pPoint->y); + } + + // Scale Size from raw pixels to relative pixels. + void ScaleSize(__inout SIZE *pSize) + { + pSize->cx = ScaleX(pSize->cx); + pSize->cy = ScaleY(pSize->cy); + } + + // Determine if screen resolution meets minimum requirements in relative pixels. + bool IsResolutionAtLeast(int cxMin, int cyMin) + { + return (ScaledScreenWidth() >= cxMin) && (ScaledScreenHeight() >= cyMin); + } + + // Convert a point size (1/72 of an inch) to raw pixels. + int PointsToPixels(int pt) { return MulDiv(pt, m_dpiY, 72); } + + // Invalidate any cached metrics. + void Invalidate() { m_fInitialized = false; } + +private: + + // This function initializes the CDPIAware Class + void _Init() + { + if (!m_fInitialized) + { + HDC hdc = GetDC(nullptr); + if (hdc) + { + // Initialize the DPI member variable + // This will correspond to the DPI setting + // With all Windows OS's to date the X and Y DPI will be identical + m_dpiX = GetDeviceCaps(hdc, LOGPIXELSX); + m_dpiY = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(nullptr, hdc); + } + m_fInitialized = true; + } + } + + // This returns a 96-DPI scaled-down equivalent value for nIndex + // For example, the value 120 at 120 DPI setting gets scaled down to 96 + // X and Y versions are provided, though to date all Windows OS releases + // have equal X and Y scale values + int _ScaledSystemMetricX(int nIndex) + { + _Init(); + return MulDiv(GetSystemMetrics(nIndex), 96, m_dpiX); + } + + // This returns a 96-DPI scaled-down equivalent value for nIndex + // For example, the value 120 at 120 DPI setting gets scaled down to 96 + // X and Y versions are provided, though to date all Windows OS releases + // have equal X and Y scale values + int _ScaledSystemMetricY(int nIndex) + { + _Init(); + return MulDiv(GetSystemMetrics(nIndex), 96, m_dpiY); + } + +private: + + // Member variable indicating whether the class has been initialized + bool m_fInitialized; + + // X and Y DPI values are provided, though to date all + // Windows OS releases have equal X and Y scale values + int m_dpiX; + int m_dpiY; +}; diff --git a/src/Utils/DpiScale.h b/src/Utils/DpiScale.h deleted file mode 100644 index 9dd558269..000000000 --- a/src/Utils/DpiScale.h +++ /dev/null @@ -1,43 +0,0 @@ -// TortoiseGit - a Windows shell extension for easy version control - -// Copyright (C) 2017 - TortoiseSVN - -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation, -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -#pragma once - -class CDpiScale -{ -public: - CDpiScale(HDC hdc) - { - m_cxScale = GetDeviceCaps(hdc, LOGPIXELSX); - m_cyScale = GetDeviceCaps(hdc, LOGPIXELSY); - } - - int ScaleX(int x) const - { - return MulDiv(x, m_cxScale, 96); - } - - int ScaleY(int y) const - { - return MulDiv(y, m_cyScale, 96); - } - -private: - int m_cxScale; - int m_cyScale; -}; -- 2.11.4.GIT