From 9f91316be0f0ab01fc5530a5a8f23ec91ec050b1 Mon Sep 17 00:00:00 2001 From: anders_k Date: Thu, 14 Sep 2017 17:10:33 +0000 Subject: [PATCH] Added experimental ManifestDPIAwareness attribute so we can declare PerMonitorV2 awareness git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6899 212acab6-be3b-0410-9dea-997c60f758d6 --- Docs/src/attributes.but | 4 ++++ Source/build.cpp | 2 +- Source/build.h | 1 + Source/exehead/Ui.c | 8 ++++---- Source/exehead/util.c | 4 ++-- Source/manifest.cpp | 21 ++++++++++++++++----- Source/manifest.h | 5 +++-- Source/script.cpp | 11 ++++++++--- Source/tokens.cpp | 1 + Source/tokens.h | 1 + 10 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Docs/src/attributes.but b/Docs/src/attributes.but index 66ac1f97..1c445f69 100644 --- a/Docs/src/attributes.but +++ b/Docs/src/attributes.but @@ -285,6 +285,10 @@ Accepts variables. If variables are used, they must be initialized before the li \c \\notset\\|true|false +\# Note: PerMonitor is not documented because it is not fully supported yet, we need to handle WM_DPICHANGED +\# Example: ManifestDPIAware System ; System DPI on Vista/7/8/8.1/10(<10.1607(AU)) +\# Example: ManifestDPIAwareness "PerMonitorV2,System" ; PMv2 on 10.1703(CU)+, System on 10.1607(AU) + Declare that the installer is DPI-aware. A DPI-aware application is not scaled by the DWM (DPI virtualization) so the text is never blurry. NSIS does not scale the bitmap used by the tree control on the component page and some plugins might have compatibility issues so make sure that you test your installer at different DPI settings if you select \e{true}. See \W{http://msdn.microsoft.com/en-us/library/dd464660}{MSDN} for more information about DPI-aware applications. diff --git a/Source/build.cpp b/Source/build.cpp index 9c26d48f..59ecdf05 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -2384,7 +2384,7 @@ int CEXEBuild::SetManifest() try { init_res_editor(); // This should stay ANSI - string manifest = manifest::generate(manifest_comctl, manifest_exec_level, manifest_dpiaware, manifest_sosl); + string manifest = manifest::generate(manifest_comctl, manifest_exec_level, manifest_dpiaware, manifest_dpiawareness.c_str(), manifest_sosl); if (manifest == "") return PS_OK; diff --git a/Source/build.h b/Source/build.h index f238e554..b706d1bf 100644 --- a/Source/build.h +++ b/Source/build.h @@ -670,6 +670,7 @@ class CEXEBuild { manifest::comctl manifest_comctl; manifest::exec_level manifest_exec_level; manifest::dpiaware manifest_dpiaware; + tstring manifest_dpiawareness; manifest::SupportedOSList manifest_sosl; CResourceEditor *res_editor; diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c index 1fa13c4d..367b9279 100644 --- a/Source/exehead/Ui.c +++ b/Source/exehead/Ui.c @@ -402,20 +402,20 @@ FORCE_INLINE int NSISCALL ui_doinstall(void) #ifdef NSIS_CONFIG_LICENSEPAGE { // load richedit DLL - static const CHAR riched20[]=("RichEd20"); - static const CHAR riched32[]=("RichEd32"); + static const CHAR riched20[]=("RichEd20"); // v2..3 DLL + static const CHAR riched32[]=("RichEd32"); // v1 DLL #ifdef UNICODE static const TCHAR richedit20t[]=_T("RichEdit20W"); #else static const TCHAR richedit20t[]=_T("RichEdit20A"); #endif - static const TCHAR richedit[]=_T("RichEdit"); + static const TCHAR richedit[]=_T("RichEdit"); // v1 class if (!LoadSystemLibrary(riched20)) { LoadSystemLibrary(riched32); // Win95 only ships with v1.0, NT4 has v2.0: web.archive.org/web/20030607222419/http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/aboutricheditcontrols.asp } - // make richedit20a/w point to RICHEDIT + // Register RichEdit20A/W as a RICHEDIT clone (for Win95) if (!GetClassInfo(NULL,richedit20t,&wc)) { GetClassInfo(NULL,richedit,&wc); diff --git a/Source/exehead/util.c b/Source/exehead/util.c index b84e2461..5f13d19a 100644 --- a/Source/exehead/util.c +++ b/Source/exehead/util.c @@ -34,11 +34,11 @@ TCHAR g_log_file[1024]; #endif #endif -// *** DO NOT DECLARE MORE VARIABLES INSIDE THIS PRAGMAS *** +// *** DO NOT DECLARE MORE VARIABLES INSIDE THESE PRAGMAS *** // This will produce a special section called ".ndata" (stands for nsis data) // this way makensis during build time, can search for this section by name // and change the virtual size of this section -// which result in extra memory for extra variables without code to do allocation :) +// which results in extra memory for extra variables without code to do allocation :) // nsis then removes the "DISCARDABLE" style from section (for safe) #ifdef _MSC_VER # pragma bss_seg(NSIS_VARS_SECTION) diff --git a/Source/manifest.cpp b/Source/manifest.cpp index 5bb43438..3f3aa9a4 100644 --- a/Source/manifest.cpp +++ b/Source/manifest.cpp @@ -91,7 +91,7 @@ bool SupportedOSList::append(const TCHAR* osid) } -string generate(comctl comctl_selection, exec_level exec_level_selection, dpiaware dpia, SupportedOSList& sosl) +string generate(comctl comctl_selection, exec_level exec_level_selection, dpiaware dpia, const TCHAR*dpia2, SupportedOSList& sosl) { bool default_or_empty_sosl = sosl.isdefaultlist() || !sosl.getcount(); if (comctl_selection == comctl_old && exec_level_selection == exec_level_none && default_or_empty_sosl && dpiaware_notset == dpia) @@ -149,11 +149,22 @@ string generate(comctl comctl_selection, exec_level exec_level_selection, dpiawa xml += ""; } - if (dpiaware_notset != dpia) + if (dpiaware_notset != dpia || *dpia2) { - xml += ""; - xml += dpiaware_false != dpia ? "true" : "false"; - xml += ""; + xml += ""; + if (dpiaware_notset != dpia) + { + xml += ""; + xml += dpia >= dpiaware_permonitor ? "True/PM" : dpiaware_false != dpia ? "true" : "false"; + xml += ""; + } + if (*dpia2) + { + xml += ""; + xml += TtoCString(dpia2); + xml += ""; + } + xml += ""; } xml += ""; diff --git a/Source/manifest.h b/Source/manifest.h index ebe32a21..d703ee96 100644 --- a/Source/manifest.h +++ b/Source/manifest.h @@ -42,7 +42,8 @@ namespace manifest { dpiaware_notset, dpiaware_false, - dpiaware_true, + dpiaware_true, // System DPI on Vista+ + dpiaware_permonitor // System DPI on Vista/7/8, PerMonitor on 8.1+ }; class SupportedOSList @@ -78,7 +79,7 @@ namespace manifest } }; - std::string generate(comctl, exec_level, dpiaware, SupportedOSList&); + std::string generate(comctl, exec_level, dpiaware, const TCHAR*, SupportedOSList&); }; diff --git a/Source/script.cpp b/Source/script.cpp index aa10a0eb..5944cde9 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -2242,15 +2242,20 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_OK; case TOK_MANIFEST_DPIAWARE: - switch(line.gettoken_enum(1,_T("none\0notset\0true\0false\0"))) + switch(line.gettoken_enum(1,_T("none\0notset\0false\0true\0system\0permonitor\0"))) { case 0: // A lot of attributes use "none" so we support that along with the documented value case 1: manifest_dpiaware = manifest::dpiaware_notset; break; - case 2: manifest_dpiaware = manifest::dpiaware_true; break; - case 3: manifest_dpiaware = manifest::dpiaware_false; break; + case 2: manifest_dpiaware = manifest::dpiaware_false; break; + case 3: // "True" == "System DPI" + case 4: manifest_dpiaware = manifest::dpiaware_true; break; + case 5: manifest_dpiaware = manifest::dpiaware_permonitor; break; default: PRINTHELP(); } return PS_OK; + case TOK_MANIFEST_DPIAWARENESS: + manifest_dpiawareness = line.gettoken_str(1); + return PS_OK; case TOK_MANIFEST_SUPPORTEDOS: { diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 030dc120..32c25b00 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -248,6 +248,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_XPSTYLE,_T("XPStyle"),1,0,_T("(on|off)"),TP_GLOBAL}, {TOK_REQEXECLEVEL,_T("RequestExecutionLevel"),1,0,_T("none|user|highest|admin"),TP_GLOBAL}, {TOK_MANIFEST_DPIAWARE,_T("ManifestDPIAware"),1,0,_T("notset|true|false"),TP_GLOBAL}, +{TOK_MANIFEST_DPIAWARENESS,_T("ManifestDPIAwareness"),1,0,_T("comma_separated_string"),TP_GLOBAL}, {TOK_MANIFEST_SUPPORTEDOS,_T("ManifestSupportedOS"),1,-1,_T("none|all|WinVista|Win7|Win8|Win8.1|Win10|{GUID} [...]"),TP_GLOBAL}, {TOK_P_PACKEXEHEADER,_T("!packhdr"),2,0,_T("temp_file_name command_line_to_compress_that_temp_file"),TP_ALL}, {TOK_P_FINALIZE,_T("!finalize"),1,2,_T("command_with_%1 []"),TP_ALL}, diff --git a/Source/tokens.h b/Source/tokens.h index 6e43c6b5..92b7e457 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -64,6 +64,7 @@ enum TOK_XPSTYLE, TOK_REQEXECLEVEL, TOK_MANIFEST_DPIAWARE, + TOK_MANIFEST_DPIAWARENESS, TOK_MANIFEST_SUPPORTEDOS, TOK_CHANGEUI, TOK_ADDBRANDINGIMAGE,