红毛樱木 发表于 2018-1-2 18:59:58

请教如何用pecmd2012获取当前系统的DPI

请教,如题。

slore 发表于 2018-1-3 22:06:22

本帖最后由 slore 于 2018-1-3 23:25 编辑

取了屏幕分辨率,再取显示器分辨率,moniX*96/scrnX就可以。pecmd怎么取我不清楚,C/C++的代码网上一大堆,就5,6行代码。
不知道为啥,啥都要塞到pecmd里面?这种与PE无关的东西,还是找更广泛使用的语言吧,共享信息多,又能自己解决。

freesoft00 发表于 2018-1-2 19:23:27

HKEY_CURRENT_USER\Control Panel\Desktop
LogPixels键值

红毛樱木 发表于 2018-1-2 19:35:34

freesoft00 发表于 2018-1-2 19:23
HKEY_CURRENT_USER\Control Panel\Desktop
LogPixels键值

10没有

ge 发表于 2018-1-3 00:31:30

┃    │命令│'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则获取先前的保存。无文件名则留到下次来取

红毛樱木 发表于 2018-1-3 08:22:08

ge 发表于 2018-1-3 00:31
┃    │命令│'SCRN'                                                                                 ...

scrn怎么获取DPI啊?

ge 发表于 2018-1-3 18:00:08

红毛樱木 发表于 2018-1-3 08:22
scrn怎么获取DPI啊?

不好意思!我看错了!这个不是屏幕分辨率!

527104427 发表于 2018-1-5 00:39:47

本帖最后由 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%%%]

不谢






红毛樱木 发表于 2018-1-5 01:05:09

527104427 发表于 2018-1-5 00:39
CALL $--ret:&hdc user32.dll,GetDC,#0

// 当前系统DPI_X 大小 一般为96


翻译的666,我的学会你这招套用大法。

红毛樱木 发表于 2018-1-5 01:06:17

slore 发表于 2018-1-3 22:06
取了屏幕分辨率,再取显示器分辨率,moniX*96/scrnX就可以。pecmd怎么取我不清楚,C/C++的代码网上一大堆, ...

老大说的在理,可是我不会玩。
只能玩玩pecmd脚本的套用

slore 发表于 2018-1-5 01:36:23

红毛樱木 发表于 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:02:21

本帖最后由 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。

sp_star 发表于 2018-1-5 16:24:04

红毛樱木 发表于 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%

红毛樱木 发表于 2018-1-5 17:47:58

sp_star 发表于 2018-1-5 16:24
试试

可以。

红毛樱木 发表于 2018-1-6 03:48:19

slore 发表于 2018-1-5 02:02
8楼的代码的话,是下面这个样子。




10下一直是96是正常的。这个值不是用在10的默认DPI方式了。

slore 发表于 2018-1-6 10:40:05

红毛樱木 发表于 2018-1-6 03:48
10下一直是96是正常的。这个值不是用在10的默认DPI方式了。

WINDOWS下运行pecmd,交互里面写这个函数,改变DPI能返回变动后的正确DPI,但是VS2015里面一直是96,所以采用分辨率进行运算的。
就是类似获取系统信息的,搜C/C++代码,看用的什么函数,然后MSDN查找是那个DLL,转换吧,我是觉得直接用C方便,代码干净。

红毛樱木 发表于 2018-1-6 11:07:07

slore 发表于 2018-1-6 10:40
WINDOWS下运行pecmd,交互里面写这个函数,改变DPI能返回变动后的正确DPI,但是VS2015里面一直是96,所以 ...

pecmd在win10下也一直是96的值

红毛樱木 发表于 2018-1-6 16:41:55

slore 发表于 2018-1-5 02:02
8楼的代码的话,是下面这个样子。





界面用PECMD2012写完了,不太好用别的语言程序再搞。。。
这个截图是win7 125%DPI的XP模式的情况。读取系统的DPI缩放比,然后再按对应比例缩放字体大小。这样也解决XP里的DPI缩放造成的界面字体混乱的问题。

527104427 发表于 2018-1-6 17:31:45

微软说,要在 manifest 加一段,才能感知DPI:
<asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>Per monitor</dpiAware>
    </asmv3:windowsSettings>
</asmv3:application>

sp_star 发表于 2018-1-6 18:55:44

527104427 发表于 2018-1-6 17:31
微软说,要在 manifest 加一段,才能感知DPI:

   


用API设置也是可以的。
CALL $--ret:&DPI_Aware user32.dll,SetProcessDPIAware//设置DPI-aware

527104427 发表于 2018-1-6 22:56:23

sp_star 发表于 2018-1-6 18:55
用API设置也是可以的。
CALL $--ret:&DPI_Aware user32.dll,SetProcessDPIAware//设置DPI-aware

多谢老大指点,又学了一招{:1_186:}

kteggplant 发表于 2018-6-14 13:22:42

527104427 发表于 2018-1-6 22:56
多谢老大指点,又学了一招

这个api好像win8以上才能用吧

airing 发表于 2019-1-13 17:18:39

527104427 发表于 2018-1-5 00:39
方法一:

// 检索显示设备上下文环境的句柄


受教了。。。 不知道能不能用pecmd或者别的方法来设置DPI呢?
页: [1]
查看完整版本: 请教如何用pecmd2012获取当前系统的DPI