请教如何用pecmd2012获取当前系统的DPI
请教,如题。本帖最后由 slore 于 2018-1-3 23:25 编辑
取了屏幕分辨率,再取显示器分辨率,moniX*96/scrnX就可以。pecmd怎么取我不清楚,C/C++的代码网上一大堆,就5,6行代码。
不知道为啥,啥都要塞到pecmd里面?这种与PE无关的东西,还是找更广泛使用的语言吧,共享信息多,又能自己解决。 HKEY_CURRENT_USER\Control Panel\Desktop
LogPixels键值 freesoft00 发表于 2018-1-2 19:23
HKEY_CURRENT_USER\Control Panel\Desktop
LogPixels键值
10没有 ┃ │命令│'SCRN' ┃
┃ ├──┼──────────────────────────────────────────────┨
┃ │格式│SCRN [-win][,H变量名][,x变量名][,y变量名][,任务栏位置名] ┃
┃ │ │SCRN -cap [:格式:][文件名],[#窗口ID|<x:y:R:B>] //屏幕捕捉 格式如:image/png ┃
┃ ├──┼──────────────────────────────────────────────┨
┃ │功能│返回屏幕当前的宽和高。-win则为最大窗口大小。 ┃
┃ ├──┼──────────────────────────────────────────────┨
┃SCRN│参数│■变量名: 用于保存屏幕当前宽和高的变量名; ┃
┃ ├──┼──────────────────────────────────────────────┨
┃ │示例│SCRN ScrW,ScrH或SCRN -capa.bmp,0 或 SCRN -capwin.bmp,#1181336 ┃
┃ ├──┼──────────────────────────────────────────────┨
┃ │备注│※变量名不能和已存在的变量名相同,当命令出错时两变量的返回结果均为空值或数值0 ┃
┃ │ │※屏幕捕捉:位置参数>=1则捕捉。无位置参数和窗口ID则获取先前的保存。无文件名则留到下次来取 ge 发表于 2018-1-3 00:31
┃ │命令│'SCRN' ...
scrn怎么获取DPI啊? 红毛樱木 发表于 2018-1-3 08:22
scrn怎么获取DPI啊?
不好意思!我看错了!这个不是屏幕分辨率! 本帖最后由 527104427 于 2018-1-8 00:54 编辑
方法一:
// 检索显示设备上下文环境的句柄
CALL $--ret:&hdc user32.dll,GetDC,#0
// 当前系统DPI_X 大小 一般为96
CALL $--ret:&LOGPIXELSX Gdi32.dll,GetDeviceCaps,#%hdc%,#88
// 当前系统DPI_Y 大小 一般为96
CALL $--ret:&LOGPIXELSY Gdi32.dll,GetDeviceCaps,#%hdc%,#90
// 获取屏幕分辨率当前物理大小
CALL $--ret:&HORZRES Gdi32.dll,GetDeviceCaps,#%hdc%,#8 //宽
CALL $--ret:&VERTRES Gdi32.dll,GetDeviceCaps,#%hdc%,#10//高
// 获取真实设置的桌面分辨率大小
CALL $--ret:&DESKTOPHORZRES Gdi32.dll,GetDeviceCaps,#%hdc%,#118 //宽
CALL $--ret:&DESKTOPVERTRES Gdi32.dll,GetDeviceCaps,#%hdc%,#117 //高
// 获取宽度缩放百分比
IFEX $%&LOGPIXELSX%=96, CALC &ScaleX=round(%&DESKTOPHORZRES%/%&HORZRES%*100)! CALC &ScaleX=round(%&LOGPIXELSX%/96*100)
// 获取高度缩放百分比
IFEX $%&LOGPIXELSY%=96, CALC &ScaleY=round(%&DESKTOPVERTRES%/%&VERTRES%*100)! CALC &ScaleY=round(%&LOGPIXELSY%/96*100)
//如果DPI为96,且缩放百分比不是100%,则重新计算DPI
IFEX $[ %&LOGPIXELSX%=96 & %&ScaleX%<>100 ], CALC &LOGPIXELSX=round(%&DESKTOPHORZRES%/%&HORZRES%*96)
IFEX $[ %&LOGPIXELSY%=96 & %&ScaleY%<>100 ], CALC &LOGPIXELSY=round(%&DESKTOPVERTRES%/%&VERTRES%*96)
MESS 水平方向DPI:[%&LOGPIXELSX%] 缩放百分比:[%&ScaleX%%%] 垂直方向DPI:[%&LOGPIXELSY%] 缩放百分比:[%&ScaleY%%%]
方法二:
CALL $--ret:&DPI_Aware user32.dll,SetProcessDPIAware // 设置DPI-aware,用于感知 DPI
CALL $--ret:&hdc user32.dll,GetDC,#0
CALL $--ret:&LOGPIXELSX Gdi32.dll,GetDeviceCaps,#%hdc%,#88
CALC &ScaleX=round(%&LOGPIXELSX%/96*100)
MESS DPI:[%&LOGPIXELSX%] 缩放百分比:[%&ScaleX%%%]
不谢
527104427 发表于 2018-1-5 00:39
CALL $--ret:&hdc user32.dll,GetDC,#0
// 当前系统DPI_X 大小 一般为96
翻译的666,我的学会你这招套用大法。 slore 发表于 2018-1-3 22:06
取了屏幕分辨率,再取显示器分辨率,moniX*96/scrnX就可以。pecmd怎么取我不清楚,C/C++的代码网上一大堆, ...
老大说的在理,可是我不会玩。
只能玩玩pecmd脚本的套用 红毛樱木 发表于 2018-1-5 01:06
老大说的在理,可是我不会玩。
只能玩玩pecmd脚本的套用
GetDPI.c
#include <Windows.h>
int main() {
int dpi = 0;
DEVMODE DeviceMode;
int screenX = GetSystemMetrics(SM_CXSCREEN);
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DeviceMode);
dpi = DeviceMode.dmPelsWidth * 96 / screenX;
printf("%d", dpi);
return dpi;
}
pecmd脚本不会,你看能调用API的话,参照吧。
E:\Test>GetDPI1.exe
96
E:\Test>echo %errorlevel%
96
附件是把代码的96改成100,得到 系统设定的百分比,100%(96 DPI), 125%(120 DPI), 150%(144 DPI), 175%(168 DPI)。
你清楚你要百分比,还是要具体的DPI值,自己根据情况改下吧。
E:\Test>GetDPI2.exe
100
E:\Test>echo %errorlevel%
100 本帖最后由 slore 于 2018-1-5 02:03 编辑
8楼的代码的话,是下面这个样子。
int main() {
HDC hdc = GetDC(NULL);
int x = GetDeviceCaps(hdc, LOGPIXELSX);/* <-这个在我WIN10上没用,一直是96,控制台程序的问题?或者DPI相关的函数没设置 */
int y = GetDeviceCaps(hdc, LOGPIXELSY);/* <-这个在我WIN10上没用,一直是96,控制台程序的问题?或者DPI相关的函数没设置 */
int h = GetDeviceCaps(hdc, HORZRES);
int v = GetDeviceCaps(hdc, VERTRES);
int dh = GetDeviceCaps(hdc, DESKTOPHORZRES);
int dv = GetDeviceCaps(hdc, DESKTOPVERTRES);
int dpiX_percent = dh * 100 / h;
int dpiY_percent = dv * 100 / v;
ReleaseDC(NULL, hdc);
return dpiX_percent;
}
不是很理解能用PECMD,不能用C。 红毛樱木 发表于 2018-1-5 01:06
老大说的在理,可是我不会玩。
只能玩玩pecmd脚本的套用
试试CALL $--ret:&CX user32.dll,GetSystemMetrics,#0 //获取X方向分辨率
CALL $--ret:&CY user32.dll,GetSystemMetrics,#1 //获取Y方向分辨率
//MESS %CX%–%CY%
CALL $--ret:&hdc user32.dll,GetDC,#0
FIND |%hdc%=0, EXIT//返回0,不成功
CALL $--ret:&HORZSIZE Gdi32.dll,GetDeviceCaps,#%hdc%,#4
CALL $--ret:&VERTSIZE Gdi32.dll,GetDeviceCaps,#%hdc%,#6
CALL $--ret:&HORZRES Gdi32.dll,GetDeviceCaps,#%hdc%,#8
CALL $--ret:&VERTRES Gdi32.dll,GetDeviceCaps,#%hdc%,#10
CALL $--ret:&LOGPIXELSX Gdi32.dll,GetDeviceCaps,#%hdc%,#88
CALL $--ret:&LOGPIXELSY Gdi32.dll,GetDeviceCaps,#%hdc%,#90
CALL $--ret:&BITSPIXEL Gdi32.dll,GetDeviceCaps,#%hdc%,#12
CALL $--ret:&VREFRESH Gdi32.dll,GetDeviceCaps,#%hdc%,#116
ENVI msg1=颜色深度: %BITSPIXEL%位\n刷新率: %VREFRESH%赫兹\n水平分辨率: %HORZRES%像素\n垂直分辨率: %VERTRES%像素
ENVI msg2=每英寸水平逻辑像数: %LOGPIXELSX%\n每英寸垂直逻辑像数: %LOGPIXELSY%\n水平毫米数: %HORZSIZE%\n垂直毫米数: %VERTSIZE%
mess %msg1%\n%msg2%
sp_star 发表于 2018-1-5 16:24
试试
可以。 slore 发表于 2018-1-5 02:02
8楼的代码的话,是下面这个样子。
10下一直是96是正常的。这个值不是用在10的默认DPI方式了。 红毛樱木 发表于 2018-1-6 03:48
10下一直是96是正常的。这个值不是用在10的默认DPI方式了。
WINDOWS下运行pecmd,交互里面写这个函数,改变DPI能返回变动后的正确DPI,但是VS2015里面一直是96,所以采用分辨率进行运算的。
就是类似获取系统信息的,搜C/C++代码,看用的什么函数,然后MSDN查找是那个DLL,转换吧,我是觉得直接用C方便,代码干净。 slore 发表于 2018-1-6 10:40
WINDOWS下运行pecmd,交互里面写这个函数,改变DPI能返回变动后的正确DPI,但是VS2015里面一直是96,所以 ...
pecmd在win10下也一直是96的值 slore 发表于 2018-1-5 02:02
8楼的代码的话,是下面这个样子。
界面用PECMD2012写完了,不太好用别的语言程序再搞。。。
这个截图是win7 125%DPI的XP模式的情况。读取系统的DPI缩放比,然后再按对应比例缩放字体大小。这样也解决XP里的DPI缩放造成的界面字体混乱的问题。 微软说,要在 manifest 加一段,才能感知DPI:
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>Per monitor</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
527104427 发表于 2018-1-6 17:31
微软说,要在 manifest 加一段,才能感知DPI:
用API设置也是可以的。
CALL $--ret:&DPI_Aware user32.dll,SetProcessDPIAware//设置DPI-aware sp_star 发表于 2018-1-6 18:55
用API设置也是可以的。
CALL $--ret:&DPI_Aware user32.dll,SetProcessDPIAware//设置DPI-aware
多谢老大指点,又学了一招{:1_186:} 527104427 发表于 2018-1-6 22:56
多谢老大指点,又学了一招
这个api好像win8以上才能用吧 527104427 发表于 2018-1-5 00:39
方法一:
// 检索显示设备上下文环境的句柄
受教了。。。 不知道能不能用pecmd或者别的方法来设置DPI呢?
页:
[1]