有人知道 windows 中 SetProcessDpiAwarenessContext() 的位置吗?
Anyone know the location of SetProcessDpiAwarenessContext() in windows?
我需要在我的 Win32 应用程序中关闭 DPI 缩放。以编程方式执行此操作的推荐方法是通过调用:
SetProcessDpiAwarenessContext()
我使用的是mingw windows环境。我验证了 mingw headers 没有调用,但是 mingw headers 中缺少几个较新的调用。我敢肯定,更新这些需要做很多工作。
我创建了一个本地定义:
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 3
extern BOOL SetProcessDpiAwarenessContext(int value);
int main()
{
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}
我仍然得到:
C:\projects\petit_ami>gcc -g3 -Iinclude -Ilibc -static tests/widget_test.c -Wl,--whole-archive bin/petit_ami_graph.a -Wl,--no-whole-archive -lwinmm -lgdi32 -lcomdlg32 -lwsock32 -luser32 -o bin/widget_test
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: bin/petit_ami_graph.a(graphics.o): in function `pa_init_graph':
C:\projects\petit_ami/windows/graphics.c:15662: undefined reference to `SetProcessDpiAwarenessContext'
collect2.exe: error: ld returned 1 exit status
我能找到的最好的文档说它在 user32.dll.
这是使用 Windows 10 和最近更新的版本:19042.1052
感谢您的帮助。
斯科特 F运行co
加利福尼亚州圣何塞
快到了。我做到了:
typedef BOOL (WINAPI *PGNSI)(int);
pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("user32.dll")),
"SetProcessDpiAwarenessContext");
if(NULL != pGNSI) {
dbg_printf(dlinfo, "Procedure found\n");
r = pGNSI(2);
dbg_printf(dlinfo, "r: %d\n", r);
if (!r) winerr();
}
得到:
C:\projects\petit_ami>graphics_test
windows/graphics.c:pa_init_graph():15686: Procedure found
windows/graphics.c:pa_init_graph():15688: r: 0
Error: Graph: Windows error: The parameter is incorrect.
参数说明在这里:
https://docs.microsoft.com/en-us/windows/win32/hidpi/dpi-awareness-context
我在别处看到 2 是一个有效值,但显然这可能不正确。西蒙建议获得 Visual studio 环境可能只是为了获得适当的价值。向西蒙道歉,我现在不能接受你的建议。我不想在这里让人们厌烦的原因有很多。
续:
我使用示例代码安装并 运行 visual studio。它有效,现在我想弄清楚 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 是什么,它不是一个简单的整数。
总之,晚了。我争取明天找到最终答案。
续:
工作代码是:
/* function call for direct to dll */
typedef BOOL (WINAPI *PGNSI)(int);
/* select for highest DPI */
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 0xfffffffc
...
/* turn off scaling. The following call gets around the lack of a
declaration in mingw */
pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("user32.dll")),
"SetProcessDpiAwarenessContext");
if (NULL != pGNSI) {
r = pGNSI(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
if (!r) winerr();
}
正如您可能猜到的那样,我将把它与用户选项联系起来。现在我只需要研究这种新模式对小部件和其他 OS 功能有何影响。
感谢大家的帮助。
GetProcAddress
有效,当您无法确定用户的 OS 是否具有该功能时推荐使用此方法。
如果要在 link 时解析符号,需要确保 (1) 导入库有符号,以及 (2) 调用约定和名称修饰和重整正确.
我对 mingw 不是很熟悉,但我相信它带有某些版本的常见 Windows DLL 的导入库。由于这是一个较新的函数,它可能不在导入库中。有一些工具可以扫描现有的 DLL 并创建相应的导入库,因此您可能需要构建一个新的。
Win32 的调用约定是__stdcall
。如果您的编译器默认使用不同的调用约定,您必须在函数的前向声明中明确设置它。此外,如果您在 C++ 模式下编译,则需要将前向声明包装在 extern "C"
中以防止名称混淆。如果其中任何一个错误,您将从 linker 那里得到一个“未定义的引用”诊断,因为符号将被不同地“装饰”。
我需要在我的 Win32 应用程序中关闭 DPI 缩放。以编程方式执行此操作的推荐方法是通过调用:
SetProcessDpiAwarenessContext()
我使用的是mingw windows环境。我验证了 mingw headers 没有调用,但是 mingw headers 中缺少几个较新的调用。我敢肯定,更新这些需要做很多工作。
我创建了一个本地定义:
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 3
extern BOOL SetProcessDpiAwarenessContext(int value);
int main()
{
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}
我仍然得到:
C:\projects\petit_ami>gcc -g3 -Iinclude -Ilibc -static tests/widget_test.c -Wl,--whole-archive bin/petit_ami_graph.a -Wl,--no-whole-archive -lwinmm -lgdi32 -lcomdlg32 -lwsock32 -luser32 -o bin/widget_test
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: bin/petit_ami_graph.a(graphics.o): in function `pa_init_graph':
C:\projects\petit_ami/windows/graphics.c:15662: undefined reference to `SetProcessDpiAwarenessContext'
collect2.exe: error: ld returned 1 exit status
我能找到的最好的文档说它在 user32.dll.
这是使用 Windows 10 和最近更新的版本:19042.1052
感谢您的帮助。 斯科特 F运行co 加利福尼亚州圣何塞
快到了。我做到了:
typedef BOOL (WINAPI *PGNSI)(int);
pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("user32.dll")),
"SetProcessDpiAwarenessContext");
if(NULL != pGNSI) {
dbg_printf(dlinfo, "Procedure found\n");
r = pGNSI(2);
dbg_printf(dlinfo, "r: %d\n", r);
if (!r) winerr();
}
得到:
C:\projects\petit_ami>graphics_test
windows/graphics.c:pa_init_graph():15686: Procedure found
windows/graphics.c:pa_init_graph():15688: r: 0
Error: Graph: Windows error: The parameter is incorrect.
参数说明在这里:
https://docs.microsoft.com/en-us/windows/win32/hidpi/dpi-awareness-context
我在别处看到 2 是一个有效值,但显然这可能不正确。西蒙建议获得 Visual studio 环境可能只是为了获得适当的价值。向西蒙道歉,我现在不能接受你的建议。我不想在这里让人们厌烦的原因有很多。
续:
我使用示例代码安装并 运行 visual studio。它有效,现在我想弄清楚 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 是什么,它不是一个简单的整数。
总之,晚了。我争取明天找到最终答案。
续:
工作代码是:
/* function call for direct to dll */
typedef BOOL (WINAPI *PGNSI)(int);
/* select for highest DPI */
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 0xfffffffc
...
/* turn off scaling. The following call gets around the lack of a
declaration in mingw */
pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("user32.dll")),
"SetProcessDpiAwarenessContext");
if (NULL != pGNSI) {
r = pGNSI(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
if (!r) winerr();
}
正如您可能猜到的那样,我将把它与用户选项联系起来。现在我只需要研究这种新模式对小部件和其他 OS 功能有何影响。
感谢大家的帮助。
GetProcAddress
有效,当您无法确定用户的 OS 是否具有该功能时推荐使用此方法。
如果要在 link 时解析符号,需要确保 (1) 导入库有符号,以及 (2) 调用约定和名称修饰和重整正确.
我对 mingw 不是很熟悉,但我相信它带有某些版本的常见 Windows DLL 的导入库。由于这是一个较新的函数,它可能不在导入库中。有一些工具可以扫描现有的 DLL 并创建相应的导入库,因此您可能需要构建一个新的。
Win32 的调用约定是__stdcall
。如果您的编译器默认使用不同的调用约定,您必须在函数的前向声明中明确设置它。此外,如果您在 C++ 模式下编译,则需要将前向声明包装在 extern "C"
中以防止名称混淆。如果其中任何一个错误,您将从 linker 那里得到一个“未定义的引用”诊断,因为符号将被不同地“装饰”。