Add basic DisplayInfo for the DebugInfo

Fix #16519, close #16541
This commit is contained in:
xomx 2025-05-12 13:36:25 +02:00 committed by Don Ho
parent dbce73c8fa
commit b7faa4d70d

View File

@ -15,6 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <format>
#include "AboutDlg.h"
#include "Parameters.h"
#include "localization.h"
@ -30,6 +31,75 @@ using namespace std;
#pragma warning(disable : 4996) // for GetVersion()
#endif
// local DebugInfo helper
void AppendDisplayAdaptersInfo(wstring& strOut, const unsigned int maxAdaptersIn)
{
strOut += L"\n installed Display Class adapters: ";
const wchar_t wszRegDisplayClassWinNT[] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}";
HKEY hkDisplayClass = nullptr;
LSTATUS lStatus = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszRegDisplayClassWinNT, 0,
KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hkDisplayClass);
if ((lStatus != ERROR_SUCCESS) || !hkDisplayClass)
{
strOut += L"\n - error, failed to open the Registry Display Class key!";
return;
}
DWORD dwSubkeysCount = 0;
lStatus = ::RegQueryInfoKeyW(hkDisplayClass, nullptr, nullptr, nullptr, &dwSubkeysCount,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
if ((lStatus == ERROR_SUCCESS) && (dwSubkeysCount > 0))
{
for (DWORD i = 0; i < dwSubkeysCount; ++i)
{
if (i >= maxAdaptersIn)
{
strOut += L"\n - warning, search has been limited to maximum number of adapter records: "
+ std::to_wstring(maxAdaptersIn);
break;
}
wstring strAdapterNo = std::format(L"{:#04d}", i); // 0000, 0001, 0002, etc...
wstring strAdapterSubKey = wszRegDisplayClassWinNT;
strAdapterSubKey += L'\\' + strAdapterNo;
HKEY hkAdapterSubKey = nullptr;
lStatus = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, strAdapterSubKey.c_str(), 0, KEY_READ, &hkAdapterSubKey);
if ((lStatus == ERROR_SUCCESS) && hkAdapterSubKey)
{
strAdapterNo.insert(0, L"\n "); // doubling the output indentation
const unsigned int nKeyValMaxLen = 127;
const DWORD dwKeyValMaxSize = nKeyValMaxLen * sizeof(wchar_t);
wchar_t wszKeyVal[nKeyValMaxLen + 1]{}; // +1 ... to ensure NUL termination
DWORD dwType = REG_SZ;
DWORD dwSize = dwKeyValMaxSize;
if (::RegQueryValueExW(hkAdapterSubKey, L"DriverDesc", nullptr, &dwType, (LPBYTE)wszKeyVal, &dwSize)
== ERROR_SUCCESS)
{
strOut += strAdapterNo + L": Description - ";
strOut += wszKeyVal;
}
// for exact HW identification, query about the "MatchingDeviceId"
dwSize = dwKeyValMaxSize;
if (::RegQueryValueExW(hkAdapterSubKey, L"DriverVersion", nullptr, &dwType, (LPBYTE)wszKeyVal, &dwSize)
== ERROR_SUCCESS)
{
strOut += strAdapterNo + L": DriverVersion - ";
strOut += wszKeyVal;
}
// to obtain also the above driver date, query about the "DriverDate"
::RegCloseKey(hkAdapterSubKey);
hkAdapterSubKey = nullptr;
}
}
}
::RegCloseKey(hkDisplayClass);
hkDisplayClass = nullptr;
}
intptr_t CALLBACK AboutDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
@ -329,6 +399,23 @@ intptr_t CALLBACK DebugInfoDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM
_debugInfoStr += nppGui._darkmode._isEnabled ? L"ON" : L"OFF";
_debugInfoStr += L"\r\n";
// Display Info
_debugInfoStr += L"Display Info : ";
{
HDC hdc = ::GetDC(nullptr); // desktop DC
if (hdc)
{
_debugInfoStr += L"\n primary monitor: " + std::to_wstring(::GetDeviceCaps(hdc, HORZRES));
_debugInfoStr += L"x" + std::to_wstring(::GetDeviceCaps(hdc, VERTRES));
_debugInfoStr += L", scaling " + std::to_wstring(::GetDeviceCaps(hdc, LOGPIXELSX) * 100 / 96);
_debugInfoStr += L"%";
::ReleaseDC(nullptr, hdc);
}
_debugInfoStr += L"\n visible monitors count: " + std::to_wstring(::GetSystemMetrics(SM_CMONITORS));
AppendDisplayAdaptersInfo(_debugInfoStr, 4); // survey up to 4 potential graphics card Registry records
}
_debugInfoStr += L"\r\n";
// OS information
HKEY hKey = nullptr;
DWORD dataSize = 0;