Rename GetWindowScalingFactor() to Win_GetW.., support older Win versions

Minimum required Windows version is XP again (instead of Win10).
Win_GetWindowScalingFactor() tries to use two dynamically loaded functions
from newer windows versions (8.1+, Win10 1607+) and has a fallback for
older versions that also seems to work (at least if all displays have
the same DPI).

Moved the function to win_main.cpp so the dynamically loaded functions
can be loaded at startup; so edit_gui_common.cpp could be removed again.
This commit is contained in:
Daniel Gibson 2021-05-10 03:17:26 +02:00
parent e67b77ba5d
commit c3d480afe4
24 changed files with 98 additions and 65 deletions

View file

@ -293,10 +293,11 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
elseif(MSVC)
add_compile_options(/MP) # parallel build (use all cores, or as many as configured in VS)
add_compile_options(/W3)
add_compile_options(/W3) # TODO: was /W4, caused trouble with VS2019 (and/or its integrated CMake? or only HarrieVG's setup?)
add_compile_options(/we4840) # treat as error when passing a class to a vararg-function (probably printf-like)
# treat several kinds of truncating int<->pointer conversions as errors (for more 64bit-safety)
add_compile_options(/we4306 /we4311 /we4312 /we4302)
# ignore the following warnings:
add_compile_options(/wd4100) # unreferenced formal parameter
add_compile_options(/wd4127) # conditional expression is constant
add_compile_options(/wd4244) # possible loss of data
@ -306,7 +307,6 @@ elseif(MSVC)
add_compile_options(/wd4996) # 'function': was declared deprecated
add_compile_options(/wd4068) # unknown pragma
add_compile_options(/wd4458) # declaration of 'variable' hides class member
add_compile_options(/wd4312) # smaller type
add_definitions(-D_ALLOW_KEYWORD_MACROS) # because of the "#define private public" and "#define protected public" in TypeInfo.cpp
set(CMAKE_C_FLAGS_DEBUG "-D_DEBUG /Od /Zi /MDd")
set(CMAKE_C_FLAGS_RELEASE "/Ox /Oy /MD")
@ -324,11 +324,8 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG ${CMAKE_C_FLAGS_MINSIZEREL}")
# mingw and msvc
if(WIN32)
add_definitions(-DWINVER=0x0A00)
add_definitions(-D_WIN32_WINNT=0x0A00)
add_definitions(-DNTDDI_VERSION=0x0A000000)
#add_definitions(-DWINVER=0x0501)
#add_definitions(-D_WIN32_WINNT=0x0501)
add_definitions(-DWINVER=0x0501)
add_definitions(-D_WIN32_WINNT=0x0501)
set(sys_libs ${sys_libs}
winmm
@ -863,7 +860,6 @@ if (TOOLS AND MFC_FOUND AND MSVC)
${src_sound_editor}
"tools/edit_public.h"
"tools/edit_gui_common.h"
"tools/edit_gui_common.cpp"
)
SET(CMAKE_MFC_FLAG 2)
set(TOOLS_DEFINES "ID_ALLOW_TOOLS;_AFXDLL")

View file

@ -761,6 +761,57 @@ void Win_Frame( void ) {
}
}
// the MFC tools use Win_GetWindowScalingFactor() for High-DPI support
#ifdef ID_ALLOW_TOOLS
typedef enum D3_MONITOR_DPI_TYPE {
D3_MDT_EFFECTIVE_DPI = 0,
D3_MDT_ANGULAR_DPI = 1,
D3_MDT_RAW_DPI = 2,
D3_MDT_DEFAULT = D3_MDT_EFFECTIVE_DPI
} D3_MONITOR_DPI_TYPE;
// https://docs.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-getdpiformonitor
// GetDpiForMonitor() - Win8.1+, shellscalingapi.h, Shcore.dll
static HRESULT (STDAPICALLTYPE *D3_GetDpiForMonitor)(HMONITOR hmonitor, D3_MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY) = NULL;
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforwindow
// GetDpiForWindow() - Win10 1607+, winuser.h/Windows.h, User32.dll
static UINT(WINAPI *D3_GetDpiForWindow)(HWND hwnd) = NULL;
float Win_GetWindowScalingFactor(HWND window)
{
// the best way - supported by Win10 1607 and newer
if ( D3_GetDpiForWindow != NULL ) {
UINT dpi = D3_GetDpiForWindow(window);
return static_cast<float>(dpi) / 96.0f;
}
// probably second best, supported by Win8.1 and newer
if ( D3_GetDpiForMonitor != NULL ) {
HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
UINT dpiX = 96, dpiY;
D3_GetDpiForMonitor(monitor, D3_MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
return static_cast<float>(dpiX) / 96.0f;
}
// on older versions of windows, DPI was system-wide (not per monitor)
// and changing DPI required logging out and in again (AFAIK), so we only need to get it once
static float scaling_factor = -1.0f;
if ( scaling_factor == -1.0f ) {
HDC hdc = GetDC(window);
if (hdc == NULL) {
return 1.0f;
}
// "Number of pixels per logical inch along the screen width. In a system with multiple display monitors, this value is the same for all monitors."
int ppi = GetDeviceCaps(hdc, LOGPIXELSX);
scaling_factor = static_cast<float>(ppi) / 96.0f;
}
return scaling_factor;
}
#endif // ID_ALLOW_TOOLS
// code that tells windows we're High DPI aware so it doesn't scale our windows
// taken from Yamagi Quake II
@ -768,7 +819,7 @@ typedef enum D3_PROCESS_DPI_AWARENESS {
D3_PROCESS_DPI_UNAWARE = 0,
D3_PROCESS_SYSTEM_DPI_AWARE = 1,
D3_PROCESS_PER_MONITOR_DPI_AWARE = 2
} YQ2_PROCESS_DPI_AWARENESS;
} D3_PROCESS_DPI_AWARENESS;
static void setHighDPIMode(void)
{
@ -778,7 +829,6 @@ static void setHighDPIMode(void)
/* Win8.1 and later */
HRESULT(WINAPI *SetProcessDpiAwareness)(D3_PROCESS_DPI_AWARENESS dpiAwareness) = NULL;
HINSTANCE userDLL = LoadLibrary("USER32.DLL");
if (userDLL)
@ -786,22 +836,30 @@ static void setHighDPIMode(void)
SetProcessDPIAware = (BOOL(WINAPI *)(void)) GetProcAddress(userDLL, "SetProcessDPIAware");
}
HINSTANCE shcoreDLL = LoadLibrary("SHCORE.DLL");
if (shcoreDLL)
{
SetProcessDpiAwareness = (HRESULT(WINAPI *)(YQ2_PROCESS_DPI_AWARENESS))
SetProcessDpiAwareness = (HRESULT(WINAPI *)(D3_PROCESS_DPI_AWARENESS))
GetProcAddress(shcoreDLL, "SetProcessDpiAwareness");
}
if (SetProcessDpiAwareness) {
SetProcessDpiAwareness(D3_PROCESS_PER_MONITOR_DPI_AWARE);
}
else if (SetProcessDPIAware) {
SetProcessDPIAware();
}
#ifdef ID_ALLOW_TOOLS // also init function pointers for Win_GetWindowScalingFactor() here
if (userDLL) {
D3_GetDpiForWindow = (UINT(WINAPI *)(HWND))GetProcAddress(userDLL, "GetDpiForWindow");
}
if (shcoreDLL) {
D3_GetDpiForMonitor = (HRESULT (STDAPICALLTYPE *)(HMONITOR, D3_MONITOR_DPI_TYPE, UINT *, UINT *))
GetProcAddress(shcoreDLL, "GetDpiForMonitor");
}
#endif // ID_ALLOW_TOOLS
}
#ifdef ID_ALLOW_TOOLS

View file

@ -191,7 +191,7 @@ void CPropTree::OnSize(UINT nType, int cx, int cy)
void CPropTree::ResizeChildWindows(int cx, int cy)
{
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int sh = int(m_nInfoHeight * scaling_factor);
if (m_bShowInfo)
@ -212,7 +212,7 @@ void CPropTree::ResizeChildWindows(int cx, int cy)
void CPropTree::InitGlobalResources()
{
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
NONCLIENTMETRICS info;

View file

@ -262,7 +262,7 @@ LONG CPropTreeItem::GetHeight()
{
if (m_pProp)
{
float scaling_factor = GetWindowScalingFactor(m_pProp->GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(m_pProp->GetSafeHwnd());
return PROPTREEITEM_DEFHEIGHT * scaling_factor;
}
return PROPTREEITEM_DEFHEIGHT;
@ -401,7 +401,7 @@ LONG CPropTreeItem::DrawItem(CDC* pDC, const RECT& rc, LONG x, LONG y)
ASSERT(m_pProp!=NULL);
float scaling_factor = GetWindowScalingFactor(m_pProp->GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(m_pProp->GetSafeHwnd());
int PNINDENT_s = int(PNINDENT * scaling_factor);
int PROPTREEITEM_SPACE_s = int(PROPTREEITEM_SPACE * scaling_factor);
int PROPTREEITEM_CHECKBOX_s = int(PROPTREEITEM_CHECKBOX * scaling_factor);

View file

@ -54,7 +54,7 @@ LONG CPropTreeItemButton::DrawItem( CDC* pDC, const RECT& rc, LONG x, LONG y )
nTotal = CPropTreeItem::DrawItem( pDC, rc, x, y );
textSize = pDC->GetOutputTextExtent( buttonText );
float scaling_factor = GetWindowScalingFactor(m_pProp->GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(m_pProp->GetSafeHwnd());
int s2 = int(2 * scaling_factor);
int s4 = int(4 * scaling_factor);
int s12 = int(12 * scaling_factor);

View file

@ -65,7 +65,7 @@ void CPropTreeItemCheck::DrawAttribute(CDC* pDC, const RECT& rc)
return;
}
float scaling_factor = GetWindowScalingFactor(m_pProp->GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(m_pProp->GetSafeHwnd());
int CHECK_BOX_SIZE_s = int(CHECK_BOX_SIZE * scaling_factor);
checkRect.left = m_rc.left;

View file

@ -221,7 +221,7 @@ void CPropTreeItemColor::OnActivate(int activateType, CPoint point)
m_cPrevColor = m_cColor;
float scaling_factor = GetWindowScalingFactor(m_pProp->GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(m_pProp->GetSafeHwnd());
r = m_rc;
r.right = r.left + 150 * scaling_factor;
@ -260,7 +260,7 @@ void CPropTreeItemColor::OnPaint()
{
CPaintDC dc(this);
CPoint pt;
float scaling_factor = GetWindowScalingFactor(m_pProp->GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(m_pProp->GetSafeHwnd());
int s3 = int(3 * scaling_factor);
int s7 = int(7 * scaling_factor);
int s13 = int(13 * scaling_factor);

View file

@ -129,7 +129,7 @@ void CPropTreeList::UpdateResize()
LONG nHeight;
CRect rc;
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
ASSERT(m_pProp!=NULL);
@ -168,7 +168,7 @@ void CPropTreeList::OnPaint()
CRect rc;
GetClientRect(rc);
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
rc.InflateRect(scaling_factor, scaling_factor);
// draw control background
@ -571,7 +571,7 @@ void CPropTreeList::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*)
LONG nHeight;
SetFocus();
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
GetClientRect(rc);
nHeight = rc.Height();

View file

@ -103,7 +103,7 @@ void CPropTreeView::OnPaint()
}
void CPropTreeView::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s20 = int(20 * scaling_factor);
// #HvGNote : This should be the right way to do it, but hardcoded is fine too.

View file

@ -587,7 +587,7 @@ bool rvPropertyGrid::ReflectMessage ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM
case WM_MEASUREITEM:
{
float scaling_factor = GetWindowScalingFactor(hWnd);
float scaling_factor = Win_GetWindowScalingFactor(hWnd);
MEASUREITEMSTRUCT* mis = (MEASUREITEMSTRUCT*) lParam;
mis->itemHeight = 18 * scaling_factor;

View file

@ -659,7 +659,7 @@ void DialogDeclBrowser::OnSize( UINT nType, int cx, int cy ) {
GetClientRect( clientRect );
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
float scaled_toolbar_height = (TOOLBAR_HEIGHT * scaling_factor);
float scaled_button_space = (BUTTON_SPACE * scaling_factor);
float scaled_border_size = (BORDER_SIZE * scaling_factor);

View file

@ -235,7 +235,7 @@ void DialogDeclEditor::LoadDecl( idDecl *decl ) {
SetWindowText( va( "Declaration Editor (%s, line %d)", decl->GetFileName(), decl->GetLineNum() ) );
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
rect.left = initialRect.left;
rect.right = rect.left + (maxCharsPerLine * FONT_WIDTH + 32) *scaling_factor;
@ -385,7 +385,7 @@ void DialogDeclEditor::OnSize( UINT nType, int cx, int cy ) {
CDialog::OnSize( nType, cx, cy );
GetClientRect( clientRect );
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
float scaled_toolbar_height = (TOOLBAR_HEIGHT * scaling_factor);
float scaled_button_space = (BUTTON_SPACE * scaling_factor);

View file

@ -1,22 +0,0 @@
#include "edit_gui_common.h"
//https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt
float GetWindowScalingFactor(HWND window)
{
float scaling_factor = 1.0f;
#if (WINVER == 0x0A00) // Windows 10
UINT dpi = GetDpiForWindow(window);
scaling_factor = static_cast<float>(dpi) / 96.0f;
#else
HDC hdc = GetDC(window);
int LogicalScreenHeight = GetDeviceCaps(hdc, VERTRES);
int PhysicalScreenHeight = GetDeviceCaps(hdc, DESKTOPVERTRES);
scaling_factor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
#endif
return scaling_factor;// 1.25 = 125%
}

View file

@ -179,5 +179,6 @@
// Compilers for map, model, video etc. processing.
#include "tools/compilers/compiler_public.h"
float GetWindowScalingFactor(HWND window);
// scaling factor based on DPI (dpi/96.0f, so 1.0 by default); implemented in win_main.cpp
float Win_GetWindowScalingFactor(HWND window);
#endif // TOOLS_EDIT_GUI_COMMON_H

View file

@ -334,7 +334,7 @@ void MEMainFrame::OnSize(UINT nType, int cx, int cy)
CFrameWnd::OnSize(nType, cx, cy);
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s5 = int(5 * scaling_factor);
CRect statusRect;

View file

@ -241,7 +241,7 @@ void MaterialEditView::OnSize(UINT nType, int cx, int cy) {
m_tabs.GetItemRect(0, tabRect);
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s2 = int(2 * scaling_factor);
int s8 = int(8 * scaling_factor);
int s4 = int(4 * scaling_factor);

View file

@ -160,7 +160,7 @@ void ToggleListView::OnSize(UINT nType, int cx, int cy) {
* Returns the size of each item in the toggle list.
*/
void ToggleListView::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
lpMeasureItemStruct->itemHeight = TOGGLELIST_ITEMHEIGHT * scaling_factor;
}

View file

@ -938,7 +938,7 @@ void CDialogTextures::OnSize(UINT nType, int cx, int cy)
return;
}
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s8 = int(8 * scaling_factor);
int s4 = int(4 * scaling_factor);
int s12 = int(12 * scaling_factor);

View file

@ -74,7 +74,7 @@ void CEditViewDlg::OnSize(UINT nType, int cx, int cy) {
return;
}
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s2 = int(2 * scaling_factor);
int s8 = int(8 * scaling_factor);
int s4 = int(4 * scaling_factor);

View file

@ -164,7 +164,7 @@ void CEntityDlg::OnSize(UINT nType, int cx, int cy)
CDialog::OnSize(nType, cx, cy);
CRect rect, crect, crect2;
GetClientRect(rect);
float scaling_factor = GetWindowScalingFactor(staticTitle.GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(staticTitle.GetSafeHwnd());
int s2 = int( 2 * scaling_factor);
int s8 = int( 8 * scaling_factor);

View file

@ -131,7 +131,7 @@ void CInspectorDialog::OnSize(UINT nType, int cx, int cy)
POSITION pos;
WORD wID;
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s5 = int(5 * scaling_factor);
int s4 = int(4 * scaling_factor);

View file

@ -1797,7 +1797,7 @@ void CMainFrame::OnSize(UINT nType, int cx, int cy) {
CRect rctParent;
GetClientRect(rctParent);
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
UINT nID;
UINT nStyle;

View file

@ -108,7 +108,7 @@ BOOL CMediaPreviewDlg::OnInitDialog()
void CMediaPreviewDlg::OnSize(UINT nType, int cx, int cy)
{
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s8 = int(8 * scaling_factor);
int s4 = int(4 * scaling_factor);

View file

@ -88,7 +88,7 @@ BOOL CPropertyList::PreCreateWindow(CREATESTRUCT& cs) {
}
void CPropertyList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s20 = int(20 * scaling_factor);
if (measureItem && !measureItem->m_curValue.IsEmpty()) {
@ -110,7 +110,7 @@ void CPropertyList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
void CPropertyList::DrawItem(LPDRAWITEMSTRUCT lpDIS) {
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s3 = 3;// int(3 * scaling_factor);
CDC dc;
@ -194,7 +194,7 @@ void CPropertyList::OnSelchange() {
static int recurse = 0;
//m_curSel = GetCurSel();
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s3 = int(3 * scaling_factor);
GetItemRect(m_curSel,rect);
@ -277,7 +277,7 @@ void CPropertyList::DisplayButton(CRect region) {
//displays a button if the property is a file/color/font chooser
m_nLastBox = 2;
m_prevSel = m_curSel;
float scaling_factor = GetWindowScalingFactor(GetSafeHwnd());
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
int s3 = int(3 * scaling_factor);
if (region.Width() > 25) {