有这样的可能:
某用户的显示器是4K显示器而我们开发的APP的尺寸最大也就1080,那么这时候用户打开这应用就会很小。
这种情况下用户一般是会开启系统的高清分屏的:
一般都会选择缩放125%以上:
这时候我们的程序如果不默认支持高清分屏那么就还是以前(未缩放)之后的大小。
本例就是提供一个操作让指定的exe支持高清分屏模式。
指定某exe支持或停止支持高清分屏:
//* absAppPath : exe的绝对路径
//* enabled : 是否支持
//* return : 是否操作成功
bool RegEnable_DPIUNAWARE( const std::wstring absAppPath, bool enabled )
{
//Win8以上 支持
#if 0
CWinOSVersion os;
if (!os.IsWin8x())
{
return false;
}
#endif
if(absAppPath.empty())
{
//empty path
return false;
}
if(!::PathFileExistsW(absAppPath.c_str()))
{
//not exists
return false;
}
std::wstring appExtension = ::PathFindExtensionW(absAppPath.c_str());
if(appExtension.empty())
{
//no extension
return false;
}
std::wstring appExtension_lower = ::CharLowerW(&appExtension[0]);
if(appExtension_lower.compare(L".exe") != 0)
{
//not exe
return false;
}
//open reg key
HKEY hKey=NULL;
DWORD dwKeyType = 0;
REGSAM regSam = KEY_ALL_ACCESS;
std::wstring subKey_Layers = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers";
LSTATUS sRtn = RegOpenKeyExW(HKEY_CURRENT_USER, subKey_Layers.c_str(), NULL, regSam, &hKey);
if( ERROR_SUCCESS != sRtn )//nokey , create..
{
if(!enabled)
{
return true;
}
sRtn = RegCreateKeyExW(HKEY_CURRENT_USER, subKey_Layers.c_str(), NULL, L"", REG_OPTION_NON_VOLATILE, regSam, NULL, &hKey, &dwKeyType);
if( ERROR_SUCCESS != sRtn )// create failed
{
return false;
}
}
std::wstring wszValue = L"~ DPIUNAWARE";
if(enabled) //set value
{
sRtn = RegSetValueExW(hKey, absAppPath.c_str(), NULL, REG_SZ, (LPBYTE)wszValue.c_str(), (wszValue.length()+1) * sizeof(wchar_t));
if( ERROR_SUCCESS != sRtn )//set failed
{
return false;
}
}
else//delete value
{
sRtn = RegDeleteValueW(hKey, absAppPath.c_str());
return true;
}
return true;
}
查询某exe是否已经兼容高清分屏
//* absAppPath : exe的绝对路径
//* return : 是否已经启用
bool RegQuery_DPIUNAWARE_Enabled( const std::wstring absAppPath )
{
//Win8以上 支持
#if 0
CWinOSVersion os;
if (!os.IsWin8x())
{
return false;
}
#endif
if(absAppPath.empty())
{
//empty path
return false;
}
if(!::PathFileExistsW(absAppPath.c_str()))
{
//not exists
return false;
}
std::wstring appExtension = ::PathFindExtensionW(absAppPath.c_str());
if(appExtension.empty())
{
//no extension
return false;
}
std::wstring appExtension_lower = ::CharLowerW(&appExtension[0]);
if(appExtension_lower.compare(L".exe") != 0)
{
//not exe
return false;
}
//open reg key
HKEY hKey=NULL;
DWORD dwKeyType = 0;
REGSAM regSam = KEY_ALL_ACCESS;
std::wstring subKey_Layers = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers";
std::wstring wszValue = L"~ DPIUNAWARE";
wchar_t wszGetValue[MAX_PATH]={0};
DWORD type = RRF_RT_REG_SZ;
DWORD vSize = MAX_PATH*sizeof(wchar_t);
LSTATUS sRtn = ::RegGetValueW(HKEY_CURRENT_USER, subKey_Layers.c_str(), absAppPath.c_str(), type, 0, (LPBYTE)wszGetValue, &vSize);
if(ERROR_SUCCESS != sRtn) //get value error
{
return false;
}
int n = StrCmpW(wszValue.c_str(),wszGetValue);
return n == 0;
return true;
}
使用方法:
wchar_t appPath[MAX_PATH] = {0};
::GetModuleFileNameW(0,appPath, MAX_PATH);
bool res = RegEnable_DPIUNAWARE(appPath, true);
res = RegQuery_DPIUNAWARE_Enabled(appPath);
运行之后再次打开我们的程序就会根据系统设置的缩放比例进行缩放了。
原理:
修改在注册表启用配置以支持系统的高清分屏模式
————————————————
版权声明:本文为CSDN博主「Eosin_Sky」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/r5014/article/details/112368460
ps:微软用的是DPIUNAWARE,不知道这个文章为啥用的是~ DPIUNAWARE
参考:Windows10显示缩放导致Visual Studio 2017 WinForm窗体设计器在高DPI下设计时界面/布局/大小问题_夏侯依风的博客-CSDN博客