有人知道 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 那里得到一个“未定义的引用”诊断,因为符号将被不同地“装饰”。