From dd4acb6686920baf1ce1e00442f05569b7cd0386 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Mon, 18 Jul 2022 14:20:42 +0800 Subject: [PATCH] add the dpitester tool, msvc only Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- tools/dpitester/CMakeLists.txt | 46 +++++++ tools/dpitester/app.ico | Bin 0 -> 46227 bytes tools/dpitester/app.manifest | 82 ++++++++++++ tools/dpitester/app.rc | 58 +++++++++ tools/dpitester/main.cpp | 225 +++++++++++++++++++++++++++++++++ 5 files changed, 411 insertions(+) create mode 100644 tools/dpitester/CMakeLists.txt create mode 100644 tools/dpitester/app.ico create mode 100644 tools/dpitester/app.manifest create mode 100644 tools/dpitester/app.rc create mode 100644 tools/dpitester/main.cpp diff --git a/tools/dpitester/CMakeLists.txt b/tools/dpitester/CMakeLists.txt new file mode 100644 index 0000000..46b5e34 --- /dev/null +++ b/tools/dpitester/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.24) + +project(DpiTester LANGUAGES RC CXX) + +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) + +string(REGEX REPLACE "[-|/]GR" "/GR-" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +#string(REGEX REPLACE "[-|/]EHsc" "/EHs-c-" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +string(REGEX REPLACE "[-|/]W[0|1|2|3|4]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +string(REGEX REPLACE "[-|/]Ob[0|1|2|3]" "/Ob3" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) + +add_executable(${PROJECT_NAME}) + +target_sources(${PROJECT_NAME} PRIVATE + app.rc app.manifest main.cpp +) + +set(_WIN32_WINNT_WIN10 0x0A00) +set(NTDDI_WIN10_CO 0x0A00000B) +target_compile_definitions(${PROJECT_NAME} PRIVATE + _CRT_NON_CONFORMING_SWPRINTFS _CRT_SECURE_NO_WARNINGS + _ENABLE_EXTENDED_ALIGNED_STORAGE NOMINMAX UNICODE + _UNICODE WIN32_LEAN_AND_MEAN WINRT_LEAN_AND_MEAN + WINVER=${_WIN32_WINNT_WIN10} _WIN32_WINNT=${_WIN32_WINNT_WIN10} + _WIN32_IE=${_WIN32_WINNT_WIN10} NTDDI_VERSION=${NTDDI_WIN10_CO} +) + +target_compile_options(${PROJECT_NAME} PRIVATE + /await:strict /bigobj /d2FH4 /MP /FS /utf-8 /WX /permissive- /ZH:SHA_256 + /Zc:char8_t,__cplusplus,externC,externConstexpr,hiddenFriend,lambda,preprocessor,referenceBinding,rvalueCast,strictStrings,ternary,throwingNew,trigraphs + $<$:/JMC> + $<$>:/guard:cf /guard:ehcont /GA /GT /Gw /Gy /Oi /Oy /QIntel-jcc-erratum /Qspectre-load /Zc:inline> +) + +target_link_options(${PROJECT_NAME} PRIVATE + /DYNAMICBASE /HIGHENTROPYVA /LARGEADDRESSAWARE /NXCOMPAT /TSAWARE /WX + $<$>:/CETCOMPAT /GUARD:CF /GUARD:EHCONT /OPT:REF /OPT:ICF> +) diff --git a/tools/dpitester/app.ico b/tools/dpitester/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..b3ec03bd617f32e58128fa977fd6ac9605124f4b GIT binary patch literal 46227 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 + + + + + DpiTester + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True/PM + PerMonitorV2, PerMonitor, System + True + True + True + UTF-8 + SegmentHeap + + + diff --git a/tools/dpitester/app.rc b/tools/dpitester/app.rc new file mode 100644 index 0000000..b715feb --- /dev/null +++ b/tools/dpitester/app.rc @@ -0,0 +1,58 @@ +/* + * MIT License + * + * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +IDI_ICON1 ICON "app.ico" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION 1,0,0,0 +PRODUCTVERSION 1,0,0,0 +FILEFLAGSMASK 0x3fL +#ifdef _DEBUG +FILEFLAGS VS_FF_DEBUG +#else +FILEFLAGS 0x0L +#endif +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "wangwenx190" + VALUE "FileDescription", "DpiTester" + VALUE "FileVersion", "1.0.0.0" + VALUE "LegalCopyright", "MIT License" + VALUE "ProductName", "DpiTester" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/tools/dpitester/main.cpp b/tools/dpitester/main.cpp new file mode 100644 index 0000000..9733d6e --- /dev/null +++ b/tools/dpitester/main.cpp @@ -0,0 +1,225 @@ +/* + * MIT License + * + * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#ifndef SM_CYPADDEDBORDER +# define SM_CYPADDEDBORDER SM_CXPADDEDBORDER +#endif + +static const std::map SYSTEM_METRIC_TABLE = { + {L"SM_CXSCREEN", SM_CXSCREEN}, + {L"SM_CYSCREEN", SM_CYSCREEN}, + {L"SM_CXVSCROLL", SM_CXVSCROLL}, + {L"SM_CYHSCROLL", SM_CYHSCROLL}, + {L"SM_CYCAPTION", SM_CYCAPTION}, + {L"SM_CXBORDER", SM_CXBORDER}, + {L"SM_CYBORDER", SM_CYBORDER}, + {L"SM_CXDLGFRAME", SM_CXDLGFRAME}, + {L"SM_CYDLGFRAME", SM_CYDLGFRAME}, + {L"SM_CYVTHUMB", SM_CYVTHUMB}, + {L"SM_CXHTHUMB", SM_CXHTHUMB}, + {L"SM_CXICON", SM_CXICON}, + {L"SM_CYICON", SM_CYICON}, + {L"SM_CXCURSOR", SM_CXCURSOR}, + {L"SM_CYCURSOR", SM_CYCURSOR}, + {L"SM_CYMENU", SM_CYMENU}, + {L"SM_CXFULLSCREEN", SM_CXFULLSCREEN}, + {L"SM_CYFULLSCREEN", SM_CYFULLSCREEN}, + {L"SM_CYKANJIWINDOW", SM_CYKANJIWINDOW}, + {L"SM_MOUSEPRESENT", SM_MOUSEPRESENT}, + {L"SM_CYVSCROLL", SM_CYVSCROLL}, + {L"SM_CXHSCROLL", SM_CXHSCROLL}, + {L"SM_DEBUG", SM_DEBUG}, + {L"SM_SWAPBUTTON", SM_SWAPBUTTON}, + {L"SM_RESERVED1", SM_RESERVED1}, + {L"SM_RESERVED2", SM_RESERVED2}, + {L"SM_RESERVED3", SM_RESERVED3}, + {L"SM_RESERVED4", SM_RESERVED4}, + {L"SM_CXMIN", SM_CXMIN}, + {L"SM_CYMIN", SM_CYMIN}, + {L"SM_CXSIZE", SM_CXSIZE}, + {L"SM_CYSIZE", SM_CYSIZE}, + {L"SM_CXFRAME", SM_CXFRAME}, + {L"SM_CYFRAME", SM_CYFRAME}, + {L"SM_CXMINTRACK", SM_CXMINTRACK}, + {L"SM_CYMINTRACK", SM_CYMINTRACK}, + {L"SM_CXDOUBLECLK", SM_CXDOUBLECLK}, + {L"SM_CYDOUBLECLK", SM_CYDOUBLECLK}, + {L"SM_CXICONSPACING", SM_CXICONSPACING}, + {L"SM_CYICONSPACING", SM_CYICONSPACING}, + {L"SM_MENUDROPALIGNMENT", SM_MENUDROPALIGNMENT}, + {L"SM_PENWINDOWS", SM_PENWINDOWS}, + {L"SM_DBCSENABLED", SM_DBCSENABLED}, + {L"SM_CMOUSEBUTTONS", SM_CMOUSEBUTTONS}, + {L"SM_CXFIXEDFRAME", SM_CXFIXEDFRAME}, + {L"SM_CYFIXEDFRAME", SM_CYFIXEDFRAME}, + {L"SM_CXSIZEFRAME", SM_CXSIZEFRAME}, + {L"SM_CYSIZEFRAME", SM_CYSIZEFRAME}, + {L"SM_SECURE", SM_SECURE}, + {L"SM_CXEDGE", SM_CXEDGE}, + {L"SM_CYEDGE", SM_CYEDGE}, + {L"SM_CXMINSPACING", SM_CXMINSPACING}, + {L"SM_CYMINSPACING", SM_CYMINSPACING}, + {L"SM_CXSMICON", SM_CXSMICON}, + {L"SM_CYSMICON", SM_CYSMICON}, + {L"SM_CYSMCAPTION", SM_CYSMCAPTION}, + {L"SM_CXSMSIZE", SM_CXSMSIZE}, + {L"SM_CYSMSIZE", SM_CYSMSIZE}, + {L"SM_CXMENUSIZE", SM_CXMENUSIZE}, + {L"SM_CYMENUSIZE", SM_CYMENUSIZE}, + {L"SM_ARRANGE", SM_ARRANGE}, + {L"SM_CXMINIMIZED", SM_CXMINIMIZED}, + {L"SM_CYMINIMIZED", SM_CYMINIMIZED}, + {L"SM_CXMAXTRACK", SM_CXMAXTRACK}, + {L"SM_CYMAXTRACK", SM_CYMAXTRACK}, + {L"SM_CXMAXIMIZED", SM_CXMAXIMIZED}, + {L"SM_CYMAXIMIZED", SM_CYMAXIMIZED}, + {L"SM_NETWORK", SM_NETWORK}, + {L"SM_CLEANBOOT", SM_CLEANBOOT}, + {L"SM_CXDRAG", SM_CXDRAG}, + {L"SM_CYDRAG", SM_CYDRAG}, + {L"SM_SHOWSOUNDS", SM_SHOWSOUNDS}, + {L"SM_CXMENUCHECK", SM_CXMENUCHECK}, + {L"SM_CYMENUCHECK", SM_CYMENUCHECK}, + {L"SM_SLOWMACHINE", SM_SLOWMACHINE}, + {L"SM_MIDEASTENABLED", SM_MIDEASTENABLED}, + {L"SM_MOUSEWHEELPRESENT", SM_MOUSEWHEELPRESENT}, + {L"SM_XVIRTUALSCREEN", SM_XVIRTUALSCREEN}, + {L"SM_YVIRTUALSCREEN", SM_YVIRTUALSCREEN}, + {L"SM_CXVIRTUALSCREEN", SM_CXVIRTUALSCREEN}, + {L"SM_CYVIRTUALSCREEN", SM_CYVIRTUALSCREEN}, + {L"SM_CMONITORS", SM_CMONITORS}, + {L"SM_SAMEDISPLAYFORMAT", SM_SAMEDISPLAYFORMAT}, + {L"SM_IMMENABLED", SM_IMMENABLED}, + {L"SM_CXFOCUSBORDER", SM_CXFOCUSBORDER}, + {L"SM_CYFOCUSBORDER", SM_CYFOCUSBORDER}, + {L"SM_TABLETPC", SM_TABLETPC}, + {L"SM_MEDIACENTER", SM_MEDIACENTER}, + {L"SM_STARTER", SM_STARTER}, + {L"SM_SERVERR2", SM_SERVERR2}, + {L"SM_MOUSEHORIZONTALWHEELPRESENT", SM_MOUSEHORIZONTALWHEELPRESENT}, + {L"SM_CXPADDEDBORDER", SM_CXPADDEDBORDER}, + {L"SM_CYPADDEDBORDER", SM_CYPADDEDBORDER}, + {L"SM_DIGITIZER", SM_DIGITIZER}, + {L"SM_MAXIMUMTOUCHES", SM_MAXIMUMTOUCHES}, + {L"SM_CMETRICS", SM_CMETRICS}, + {L"SM_REMOTESESSION", SM_REMOTESESSION}, + {L"SM_SHUTTINGDOWN", SM_SHUTTINGDOWN}, + {L"SM_REMOTECONTROL", SM_REMOTECONTROL}, + {L"SM_CARETBLINKINGENABLED", SM_CARETBLINKINGENABLED}, + {L"SM_CONVERTIBLESLATEMODE", SM_CONVERTIBLESLATEMODE}, + {L"SM_SYSTEMDOCKED", SM_SYSTEMDOCKED} +}; + +static const int DPI_TABLE[] = { + int(std::round(USER_DEFAULT_SCREEN_DPI * 1.0)), // 100% + int(std::round(USER_DEFAULT_SCREEN_DPI * 1.2)), // 120% + int(std::round(USER_DEFAULT_SCREEN_DPI * 1.25)), // 125% + int(std::round(USER_DEFAULT_SCREEN_DPI * 1.4)), // 140% + int(std::round(USER_DEFAULT_SCREEN_DPI * 1.5)), // 150% + int(std::round(USER_DEFAULT_SCREEN_DPI * 1.6)), // 160% + int(std::round(USER_DEFAULT_SCREEN_DPI * 1.75)), // 175% + int(std::round(USER_DEFAULT_SCREEN_DPI * 1.8)), // 180% + int(std::round(USER_DEFAULT_SCREEN_DPI * 2.0)), // 200% + int(std::round(USER_DEFAULT_SCREEN_DPI * 2.25)), // 225% + int(std::round(USER_DEFAULT_SCREEN_DPI * 2.5)), // 250% + int(std::round(USER_DEFAULT_SCREEN_DPI * 3.0)), // 300% + int(std::round(USER_DEFAULT_SCREEN_DPI * 3.5)), // 350% + int(std::round(USER_DEFAULT_SCREEN_DPI * 4.0)), // 400% + int(std::round(USER_DEFAULT_SCREEN_DPI * 4.5)), // 450% + int(std::round(USER_DEFAULT_SCREEN_DPI * 5.0)) // 500% +}; +static const auto DPI_COUNT = int(std::size(DPI_TABLE)); + +EXTERN_C int WINAPI wmain(int argc, wchar_t *argv[]) +{ + std::vector options = {}; + std::vector metrics = {}; + if (argc > 1) { + for (int i = 1; i != argc; ++i) { + std::wstring arg = argv[i]; + if (arg.starts_with(L"SM_CX") || arg.starts_with(L"SM_CY")) { + if (SYSTEM_METRIC_TABLE.contains(arg)) { + if (std::find(std::begin(metrics), std::end(metrics), arg) == std::end(metrics)) { + metrics.push_back(arg); + } + } else { + std::wcerr << L"Unrecognized system metric value: " << arg << std::endl; + } + } else if (arg.starts_with(L"/") || arg.starts_with(L"--")) { + const int len = arg.starts_with(L"/") ? 1 : 2; + arg.erase(0, len); + if (std::find(std::begin(options), std::end(options), arg) == std::end(options)) { + options.push_back(arg); + } + } else { + std::wcerr << L"Unrecognized parameter: " << arg << std::endl; + } + } + } + if (metrics.empty()) { + for (auto &&[key, value] : std::as_const(SYSTEM_METRIC_TABLE)) { + if (key.starts_with(L"SM_CX") || key.starts_with(L"SM_CY")) { + metrics.push_back(key); + } + } + } + const auto metrics_count = int(metrics.size()); + std::wstring text = L"// DPI: "; + for (int i = 0; i != DPI_COUNT; ++i) { + text += std::to_wstring(DPI_TABLE[i]); + if (i == (DPI_COUNT - 1)) { + text += L"\n"; + } else { + text += L", "; + } + } + text += L"static const QHash g_systemMetricsTable = {\n"; + for (int i = 0; i != metrics_count; ++i) { + const std::wstring sm = metrics.at(i); + text += L" {" + sm + L", {"; + for (int j = 0; j != DPI_COUNT; ++j) { + const int index = SYSTEM_METRIC_TABLE.at(sm); + const int value = GetSystemMetricsForDpi(index, DPI_TABLE[j]); + text += std::to_wstring(value); + if (j == (DPI_COUNT - 1)) { + text += L"}}"; + } else { + text += L", "; + } + } + if (i != (metrics_count - 1)) { + text += L","; + } + text += L"\n"; + } + text += L"};"; + std::wcout << text << std::endl; + return 0; +}