众所周知,Windows 8.1开始系统增加了Per-Monitor DPI Aware级别,从8.1开始只有达到这个级别的才算“真·DPI”缩放支持;System Aware面对可以动态生效DPI的系统或者多显示器,例如Windows10,就会使用DPI虚拟化进行强制缩放,于是就是模糊
我最近在给我的作品加上 Per-Monitor DPI Aware支持;但是还是有部分不完美;例如标题栏、菜单栏和菜单无法正常缩放……如果有解决方案的话希望可以指导我
但是我发现微软的Win32实现的运行对话框的标题栏、菜单栏和菜单却能正常动态缩放;于是我用IDA打开存在运行对话框函数RunFileDlg的Shell32.dll
虽然我没有找到微软是怎么做到的(也许是我不够仔细);但是偶然发现一个API,让我提起了兴趣;然后生成了C伪码,如下
[C++] 纯文本查看 复制代码 char __stdcall IsPerMonitorAwareFileExplorerEnabled()
{
signed int v0; // eax@1
char v1; // bl@1
int v3; // [sp+4h] [bp-Ch]@2
int v4; // [sp+8h] [bp-8h]@2
int v5; // [sp+Ch] [bp-4h]@2
v0 = dword_69DB0A24;
v1 = 1;
if ( !dword_69DB0A24 )
{
v4 &= dword_69DB0A24;
v5 = 4;
if ( !RegGetValueW(
-2147483646,
L"Software\\Microsoft\\Windows\\CurrentVersion\\FlightedFeatures",
L"PerMonitorAwareFileExplorer",
0x10010,
&v4,
&v3,
&v5) )
{
v1 = 1;
if ( v3 == 1 )
{
dword_69DB0A24 = 1;
return v1;
}
dword_69DB0A24 = 2;
goto LABEL_6;
}
v0 = 1;
dword_69DB0A24 = 1;
}
if ( v0 != 1 )
LABEL_6:
v1 = 0;
return v1;
}
粗略看了看,这是内部使用的文件资源管理器是否支持Per-Monitor DPI Aware级别支持的判断API
于是当时猜想如果这个API能返回true,岂不文件资源管理器就能支持Per-Monitor DPI Aware了
PS:文件资源管理器默认只能支持System Aware;Win10一拉DPI调整横杆就模糊,真的是浑身难受
然后粗略看了看实现,于是我尝试在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\FlightedFeatures下建立了一个PerMonitorAwareFileExplorer的DWORD值并设为1
然后重启Explorer,拉DPI调节横杆,结果还是糊;一看文件管理器所属的Explorer进程还是System Aware
突然我想到我可以去掉文件夹选项的“在单独的进程中打开文件夹窗口” 试试,于是文件资源管理器进程是Per-Monitor DPI Aware了;这让我很兴奋
我打开文件资源管理器;把 DPI从100%拉到125%,不注销;文件资源管理器正常缩放,最关键不模糊,完美
我上幅效果图
其他不支持Per-Monitor DPI Aware的程序都是模糊的,你看winver;但是文件管理器正常缩放,而且不模糊!!!
该方法在Windows 10 TH2 Build 10586测试通过,其他系统不保证可以
毛利,于2016/6/14
|