文号
t74201
阅读
8787
回复
5
收藏
2
Win32的高DPI支持
2015/11/03
IP:四川
Windows很早就支持高DPI(大概在Windows 95/98),但是大部分应用程序却不是,大部分win32程序都是基于像素编写的,在高DPI环境下表现很糟糕。
为了强行推行高DPI,微软在Windows Vista中搞了个DPI模拟缩放,它可以在高DPI环境下报告低DPI的同时通过DWM对应用程序进行强行缩放。这个想法是好的,但是效果不好,缩放后字体和图标会模糊。因此Windows也给了一种方法关闭DPI缩放,方法是调用SetProcessDPIAware()函数。
FARPROC spdpia = (FARPROC)GetProcAddress(GetModuleHandleA("USER32"), "SetProcessDPIAware");
if (spdpia != NULL) spdpia();

调用之后Windows便不会对新创建的窗口进行DPI模拟缩放,而是像Windows XP一样直接报告高DPI。那么怎么获得DPI的值呢?方法是使用GetDeviceCaps(hdc, LOGPIXELSY)获取。100%的DPI是96,125%的DPI是120,150%的是144,200%的是192,依此类推。任何需要像素大小的地方(如CreateWindowEx)都需要进行缩放(缩放可以用MulDiv(x,dpi,96)和MulDiv(y,dpi,96)等),CreateFont则需要-MulDiv(fontsize,dpi,72)。对话框(DialogBox、CreateDialog)和系统字体(GetStockObject(DEFAULT_GUI_FONT))等一般不需要进行缩放。
---------------
ps.Windows 8.1支持另一种高DPI,称为每显示器的DPI,它过于复杂并且覆盖面较窄,一般的程序支持传统的DPI缩放已经足够。
[ 修改于11年1个月前 - 2015/11/03 14:51:25 ]
5
11年1个月前IP:山东
795455
1楼
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

有人用dwmapi.dll里的接口做的模糊效果
引用
评论
acmilan作者
11年1个月前IP:四川
795459
2楼
引用 张静茹:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

有人用dwmapi.dll里的接口做的模糊效果
这个我做过,参见我以前的帖子。
这里讲的是传统Win32程序关闭Vista/7/8的DPI模拟和适配高DPI的方法。
引用
评论
11年1个月前IP:山东
795468
3楼
引用 acmilan:
这个我做过,参见我以前的帖子。
这里讲的是传统Win32程序关闭Vista/7/8的DPI模拟和适配高DPI的方法。
看到你说dwm我就想起来了
引用
评论
acmilan作者
11年1个月前IP:四川
795473
4楼
未创建任何窗口的情况下,可以使用GetDC(NULL)获取屏幕设备上下文句柄(即屏幕的hdc),这样就可以使用GetDeviceCaps(hdc, LOGPIXELSY)获得DPI了,使用完毕一定要ReleaseDC以免内存泄露。
引用
评论
acmilan作者
11年1个月前IP:四川
796975
5楼
实际上,如果你不想支持Windows XP,完全可以不用GetProcAddress的方法,直接调用这个函数即可:
SetProcessDPIAware();
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的