From d189fbdf4afbf28b42554e8dacd358ca213de4c7 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Fri, 6 Jul 2018 17:57:35 +0200 Subject: [PATCH] Integrate the DPIAware.h changes from TortoiseSVN Inspired on TortoiseSVN rev. 28257. Signed-off-by: Sven Strickroth --- src/TortoiseGitBlame/TortoiseGitBlameView.cpp | 5 +- src/TortoiseIDiff/PicWindow.cpp | 7 +- src/TortoiseMerge/BaseView.cpp | 9 +- src/TortoiseProc/AppUtils.cpp | 5 +- src/TortoiseProc/Commands/SettingsCommand.cpp | 4 +- .../RevisionGraph/RevisionGraphDlgDraw.cpp | 7 +- src/Utils/DPIAware.h | 138 ++++++++++++++------- src/Utils/MiscUI/FilterEdit.cpp | 12 +- src/Utils/MiscUI/MessageBox.cpp | 5 +- 9 files changed, 117 insertions(+), 75 deletions(-) diff --git a/src/TortoiseGitBlame/TortoiseGitBlameView.cpp b/src/TortoiseGitBlame/TortoiseGitBlameView.cpp index ae67ca259..1a6707040 100644 --- a/src/TortoiseGitBlame/TortoiseGitBlameView.cpp +++ b/src/TortoiseGitBlame/TortoiseGitBlameView.cpp @@ -866,8 +866,7 @@ void CTortoiseGitBlameView::CreateFont() return; LOGFONT lf = {0}; lf.lfWeight = 400; - HDC hDC = ::GetDC(wBlame); - lf.lfHeight = -MulDiv((DWORD)CRegStdDWORD(L"Software\\TortoiseGit\\BlameFontSize", 10), GetDeviceCaps(hDC, LOGPIXELSY), 72); + lf.lfHeight = -CDPIAware::Instance().PointsToPixelsY((DWORD)CRegStdDWORD(L"Software\\TortoiseGit\\BlameFontSize", 10)); lf.lfCharSet = DEFAULT_CHARSET; CRegStdString fontname = CRegStdString(L"Software\\TortoiseGit\\BlameFontName", L"Consolas"); wcscpy_s(lf.lfFaceName, 32, ((std::wstring)fontname).c_str()); @@ -875,8 +874,6 @@ void CTortoiseGitBlameView::CreateFont() lf.lfItalic = TRUE; m_italicfont.CreateFontIndirect(&lf); - - ::ReleaseDC(wBlame, hDC); } void CTortoiseGitBlameView::DrawBlame(HDC hDC) diff --git a/src/TortoiseIDiff/PicWindow.cpp b/src/TortoiseIDiff/PicWindow.cpp index 94e21e989..1c2b71b8c 100644 --- a/src/TortoiseIDiff/PicWindow.cpp +++ b/src/TortoiseIDiff/PicWindow.cpp @@ -1,7 +1,7 @@ // TortoiseIDiff - an image diff viewer in TortoiseSVN -// Copyright (C) 2006-2013 - TortoiseSVN -// Copyright (C) 2016 - TortoiseGit +// Copyright (C) 2006-2013, 2018 - TortoiseSVN +// Copyright (C) 2016, 2018 - TortoiseGit // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -23,6 +23,7 @@ #include "PicWindow.h" #include #include +#include "../Utils/DPIAware.h" #pragma comment(lib, "Msimg32.lib") #pragma comment(lib, "shell32.lib") @@ -574,7 +575,7 @@ void CPicWindow::SetPic(const tstring& path, const tstring& title, bool bFirst) void CPicWindow::DrawViewTitle(HDC hDC, RECT * rect) { HFONT hFont = nullptr; - hFont = CreateFont(-MulDiv(pSecondPic ? 8 : 10, GetDeviceCaps(hDC, LOGPIXELSY), 72), 0, 0, 0, FW_DONTCARE, false, false, false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH, L"MS Shell Dlg"); + hFont = CreateFont(-CDPIAware::Instance().PointsToPixelsY(pSecondPic ? 8 : 10), 0, 0, 0, FW_DONTCARE, false, false, false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH, L"MS Shell Dlg"); HFONT hFontOld = (HFONT)SelectObject(hDC, (HGDIOBJ)hFont); RECT textrect; diff --git a/src/TortoiseMerge/BaseView.cpp b/src/TortoiseMerge/BaseView.cpp index 869c3f30c..9335c3a93 100644 --- a/src/TortoiseMerge/BaseView.cpp +++ b/src/TortoiseMerge/BaseView.cpp @@ -1,7 +1,7 @@ // TortoiseGitMerge - a Diff/Patch program // Copyright (C) 2003-2018 - TortoiseSVN -// Copyright (C) 2011-2012, 2017 Sven Strickroth +// Copyright (C) 2011-2012, 2017-2018 Sven Strickroth // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -497,12 +497,7 @@ CFont* CBaseView::GetFont(BOOL bItalic /*= FALSE*/, BOOL bBold /*= FALSE*/) m_lfBaseFont.lfCharSet = DEFAULT_CHARSET; m_lfBaseFont.lfWeight = bBold ? FW_BOLD : FW_NORMAL; m_lfBaseFont.lfItalic = (BYTE) bItalic; - CDC * pDC = GetDC(); - if (pDC) - { - m_lfBaseFont.lfHeight = -MulDiv((DWORD)CRegDWORD(L"Software\\TortoiseGitMerge\\LogFontSize", 10), GetDeviceCaps(pDC->m_hDC, LOGPIXELSY), 72); - ReleaseDC(pDC); - } + m_lfBaseFont.lfHeight = -CDPIAware::Instance().PointsToPixelsY((DWORD)CRegDWORD(L"Software\\TortoiseGitMerge\\LogFontSize", 10)); wcsncpy_s(m_lfBaseFont.lfFaceName, (LPCTSTR)(CString)CRegString(L"Software\\TortoiseGitMerge\\LogFontName", L"Consolas"), _countof(m_lfBaseFont.lfFaceName) - 1); if (!m_apFonts[nIndex]->CreateFontIndirect(&m_lfBaseFont)) { diff --git a/src/TortoiseProc/AppUtils.cpp b/src/TortoiseProc/AppUtils.cpp index a4811467a..3e544f591 100644 --- a/src/TortoiseProc/AppUtils.cpp +++ b/src/TortoiseProc/AppUtils.cpp @@ -67,6 +67,7 @@ #include "SubmoduleResolveConflictDlg.h" #include "GitDiff.h" #include "../TGitCache/CacheInterface.h" +#include "DPIAware.h" static struct last_accepted_cert { BYTE* data; @@ -663,7 +664,7 @@ void CAppUtils::CreateFontForLogs(CFont& fontToCreate) { LOGFONT logFont; HDC hScreenDC = ::GetDC(nullptr); - logFont.lfHeight = -MulDiv(GetLogFontSize(), GetDeviceCaps(hScreenDC, LOGPIXELSY), 72); + logFont.lfHeight = -CDPIAware::Instance().PointsToPixelsY(GetLogFontSize()); ::ReleaseDC(nullptr, hScreenDC); logFont.lfWidth = 0; logFont.lfEscapement = 0; @@ -754,7 +755,7 @@ bool CAppUtils::LaunchRemoteSetting() CTGitPath path(g_Git.m_CurrentDir); CSettings dlg(IDS_PROC_SETTINGS_TITLE, &path); dlg.SetTreeViewMode(TRUE, TRUE, TRUE); - dlg.SetTreeWidth(220); + dlg.SetTreeWidth(220 * CDPIAware::Instance().GetDPIX()); dlg.m_DefaultPage = L"gitremote"; dlg.DoModal(); diff --git a/src/TortoiseProc/Commands/SettingsCommand.cpp b/src/TortoiseProc/Commands/SettingsCommand.cpp index ac887d725..43c6203db 100644 --- a/src/TortoiseProc/Commands/SettingsCommand.cpp +++ b/src/TortoiseProc/Commands/SettingsCommand.cpp @@ -18,8 +18,8 @@ // #include "stdafx.h" #include "SettingsCommand.h" - #include "../Settings/Settings.h" +#include "DPIAware.h" bool SettingsCommand::Execute() { @@ -27,7 +27,7 @@ bool SettingsCommand::Execute() CSettings dlg(IDS_PROC_SETTINGS_TITLE,&orgCmdLinePath); dlg.SetTreeViewMode(TRUE, TRUE, TRUE); - dlg.SetTreeWidth(220); + dlg.SetTreeWidth(220 * CDPIAware::Instance().GetDPIX()); dlg.m_DefaultPage = defaultpage; dlg.DoModal(); diff --git a/src/TortoiseProc/RevisionGraph/RevisionGraphDlgDraw.cpp b/src/TortoiseProc/RevisionGraph/RevisionGraphDlgDraw.cpp index 097326403..32041991b 100644 --- a/src/TortoiseProc/RevisionGraph/RevisionGraphDlgDraw.cpp +++ b/src/TortoiseProc/RevisionGraph/RevisionGraphDlgDraw.cpp @@ -1,7 +1,7 @@ // TortoiseGit - a Windows shell extension for easy version control // Copyright (C) 2003-2011, 2015 - TortoiseSVN -// Copyright (C) 2012-2013, 2015-2017 - TortoiseGit +// Copyright (C) 2012-2013, 2015-2018 - TortoiseGit // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -33,6 +33,7 @@ //#include "ShowTreeStripes.h" #include "registry.h" #include "UnicodeUtils.h" +#include "DPIAware.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -66,9 +67,7 @@ CFont* CRevisionGraphWnd::GetFont(BOOL bItalic /*= FALSE*/, BOOL bBold /*= FALSE m_lfBaseFont.lfWeight = bBold ? FW_BOLD : FW_NORMAL; m_lfBaseFont.lfItalic = (BYTE) bItalic; m_lfBaseFont.lfStrikeOut = (BYTE) FALSE; - CDC * pDC = GetDC(); - m_lfBaseFont.lfHeight = -MulDiv(m_nFontSize, GetDeviceCaps(pDC->m_hDC, LOGPIXELSY), 72); - ReleaseDC(pDC); + m_lfBaseFont.lfHeight = -CDPIAware::Instance().PointsToPixelsY(m_nFontSize); // use the empty font name, so GDI takes the first font which matches // the specs. Maybe this will help render chinese/japanese chars correctly. wcsncpy_s(m_lfBaseFont.lfFaceName, L"MS Shell Dlg 2", _countof(m_lfBaseFont.lfFaceName) - 1); diff --git a/src/Utils/DPIAware.h b/src/Utils/DPIAware.h index 3ce434f39..d0cdfc5d7 100644 --- a/src/Utils/DPIAware.h +++ b/src/Utils/DPIAware.h @@ -16,10 +16,19 @@ // 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 CDPIAware { private: - CDPIAware() : m_fInitialized(false), m_dpiX(96), m_dpiY(96) {} + CDPIAware() + : m_fInitialized(false) + , m_dpi(96) + , pfnGetDpiForWindow(nullptr) + , pfnGetDpiForSystem(nullptr) + , pfnGetSystemMetricsForDpi(nullptr) + , pfnSystemParametersInfoForDpi(nullptr) + {} ~CDPIAware() {} public: @@ -29,43 +38,51 @@ public: return instance; } +private: // Get screen DPI. - int GetDPIX() { _Init(); return m_dpiX; } - int GetDPIY() { _Init(); return m_dpiY; } + int GetDPI() { _Init(); return m_dpi; } // 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); } + int Scale(int x) { _Init(); return MulDiv(x, m_dpi, 96); } + float ScaleFactor() { _Init(); return m_dpi / 96.0f; } + int Unscale(int x) { _Init(); return MulDiv(x, 96, m_dpi); } +public: + inline int GetDPIX() { return GetDPI(); } + inline int GetDPIY() { return GetDPI(); } + inline int ScaleX(int x) { return Scale(x); } + inline int ScaleY(int y) { return Scale(y); } + inline float ScaleFactorX() { return ScaleFactor(); } + inline float ScaleFactorY() { return ScaleFactor(); } + inline int UnscaleX(int x) { return Unscale(x); } + inline int UnscaleY(int y) { return Unscale(y); } + inline int PointsToPixelsX(int pt) { return PointsToPixels(pt); } + inline int PointsToPixelsY(int pt) { return PointsToPixels(pt); } // Determine the screen dimensions in relative pixels. - int ScaledScreenWidth() { return _ScaledSystemMetricX(SM_CXSCREEN); } - int ScaledScreenHeight() { return _ScaledSystemMetricY(SM_CYSCREEN); } + int ScaledScreenWidth() { return _ScaledSystemMetric(SM_CXSCREEN); } + int ScaledScreenHeight() { return _ScaledSystemMetric(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); + pRect->left = Scale(pRect->left); + pRect->right = Scale(pRect->right); + pRect->top = Scale(pRect->top); + pRect->bottom = Scale(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); + pPoint->x = Scale(pPoint->x); + pPoint->y = Scale(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); + pSize->cx = Scale(pSize->cx); + pSize->cy = Scale(pSize->cy); } // Determine if screen resolution meets minimum requirements in relative pixels. @@ -74,8 +91,28 @@ public: return (ScaledScreenWidth() >= cxMin) && (ScaledScreenHeight() >= cyMin); } +private: // Convert a point size (1/72 of an inch) to raw pixels. - int PointsToPixels(int pt) { return MulDiv(pt, m_dpiY, 72); } + int PointsToPixels(int pt) { _Init(); return MulDiv(pt, m_dpi, 72); } + +public: + // returns the system metrics. For Windows 10, it returns the metrics dpi scaled. + UINT GetSystemMetrics(int nIndex) + { + return _ScaledSystemMetric(nIndex); + } + + // returns the system parameters info. If possible adjusted for dpi. + UINT SystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni) + { + _Init(); + UINT ret = 0; + if (pfnSystemParametersInfoForDpi) + ret = pfnSystemParametersInfoForDpi(uiAction, uiParam, pvParam, fWinIni, m_dpi); + if (ret == 0) + ret = ::SystemParametersInfo(uiAction, uiParam, pvParam, fWinIni); + return ret; + } // Invalidate any cached metrics. void Invalidate() { m_fInitialized = false; } @@ -87,15 +124,30 @@ private: { if (!m_fInitialized) { - HDC hdc = GetDC(nullptr); - if (hdc) + auto hUser = ::GetModuleHandle(L"user32.dll"); + if (hUser) + { + pfnGetDpiForWindow = (GetDpiForWindowFN*)GetProcAddress(hUser, "GetDpiForWindow"); + pfnGetDpiForSystem = (GetDpiForSystemFN*)GetProcAddress(hUser, "GetDpiForSystem"); + pfnGetSystemMetricsForDpi = (GetSystemMetricsForDpiFN*)GetProcAddress(hUser, "GetSystemMetricsForDpi"); + pfnSystemParametersInfoForDpi = (SystemParametersInfoForDpiFN*)GetProcAddress(hUser, "SystemParametersInfoForDpi"); + } + + if (pfnGetDpiForSystem) + { + m_dpi = pfnGetDpiForSystem(); + } + else { - // 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); + 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_dpi = GetDeviceCaps(hdc, LOGPIXELSX); + ReleaseDC(nullptr, hdc); + } } m_fInitialized = true; } @@ -105,29 +157,27 @@ private: // 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) + int _ScaledSystemMetric(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); + if (pfnGetSystemMetricsForDpi) + return pfnGetSystemMetricsForDpi(nIndex, m_dpi); + return MulDiv(::GetSystemMetrics(nIndex), 96, m_dpi); } private: + typedef UINT STDAPICALLTYPE GetDpiForWindowFN(HWND hWnd); + typedef UINT STDAPICALLTYPE GetDpiForSystemFN(); + typedef UINT STDAPICALLTYPE GetSystemMetricsForDpiFN(int nIndex, UINT dpi); + typedef UINT STDAPICALLTYPE SystemParametersInfoForDpiFN(UINT uiAction,UINT uiParam, PVOID pvParam, UINT fWinIni, UINT dpi); + + GetDpiForWindowFN* pfnGetDpiForWindow; + GetDpiForSystemFN* pfnGetDpiForSystem; + GetSystemMetricsForDpiFN* pfnGetSystemMetricsForDpi; + SystemParametersInfoForDpiFN* pfnSystemParametersInfoForDpi; // 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; + int m_dpi; }; diff --git a/src/Utils/MiscUI/FilterEdit.cpp b/src/Utils/MiscUI/FilterEdit.cpp index a72bb0e34..0da6f74cf 100644 --- a/src/Utils/MiscUI/FilterEdit.cpp +++ b/src/Utils/MiscUI/FilterEdit.cpp @@ -1,7 +1,7 @@ // TortoiseGit - a Windows shell extension for easy version control -// Copyright (C) 2012, 2014, 2016-2017 - TortoiseGit -// Copyright (C) 2007, 2012-2014, 2017 - TortoiseSVN +// Copyright (C) 2012, 2014, 2016-2018 - TortoiseGit +// Copyright (C) 2007, 2012-2014, 2018 - TortoiseSVN // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -19,7 +19,7 @@ // #include "stdafx.h" #include "FilterEdit.h" - +#include "DPIAware.h" const UINT CFilterEdit::WM_FILTEREDIT_INFOCLICKED = ::RegisterWindowMessage(L"TGITWM_FILTEREDIT_INFOCLICKED"); const UINT CFilterEdit::WM_FILTEREDIT_CANCELCLICKED = ::RegisterWindowMessage(L"TGITWM_FILTEREDIT_CANCELCLICKED"); @@ -395,10 +395,8 @@ void CFilterEdit::DrawDimText() HICON CFilterEdit::LoadDpiScaledIcon(UINT resourceId, int cx96dpi, int cy96dpi) { - CWindowDC dc(this); - - int cx = MulDiv(cx96dpi, dc.GetDeviceCaps(LOGPIXELSX), 96); - int cy = MulDiv(cy96dpi, dc.GetDeviceCaps(LOGPIXELSY), 96); + int cx = CDPIAware::Instance().PointsToPixelsX(cx96dpi); + int cy = CDPIAware::Instance().PointsToPixelsY(cy96dpi); return (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(resourceId), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR); } diff --git a/src/Utils/MiscUI/MessageBox.cpp b/src/Utils/MiscUI/MessageBox.cpp index 533456a3a..41f5d906c 100644 --- a/src/Utils/MiscUI/MessageBox.cpp +++ b/src/Utils/MiscUI/MessageBox.cpp @@ -1,6 +1,6 @@ // TortoiseGit - a Windows shell extension for easy version control -// Copyright (C) 2012-2016 - TortoiseGit +// Copyright (C) 2012-2016, 2018 - TortoiseGit // Copyright (C) 2003-2008,2010 - TortoiseSVN // This program is free software; you can redistribute it and/or @@ -23,6 +23,7 @@ #include "ClipboardHelper.h" #include "SmartHandle.h" #include +#include "DPIAware.h" #define BTN_OFFSET 100 // use an offset in order to not interfere with IDYES and so on... @@ -641,7 +642,7 @@ UINT CMessageBox::GoModal(CWnd * pWnd, const CString& title, const CString& msg, return ::MessageBox(hw, msg, title, m_uType | defButton); } - int pix = -MulDiv(m_LogFont.lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY)); + int pix = -CDPIAware::Instance().PointsToPixelsY(m_LogFont.lfHeight); CDlgTemplate dialogTemplate = CDlgTemplate(title, WS_CAPTION | DS_CENTER, 0, 0, 0, 0, m_LogFont.lfFaceName, pix); dialogTemplate.AddButton(L"Button1", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 1) ? BS_DEFPUSHBUTTON : 0), 0, -- 2.11.4.GIT