用于GetWindowDpiAwarenessContext的C#Pinvoke [英] c# Pinvoke for GetWindowDpiAwarenessContext

查看:463
本文介绍了用于GetWindowDpiAwarenessContext的C#Pinvoke的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在C#应用程序中实现GetWindowDpiAwarenessContext,但没有成功.

I am trying to implement GetWindowDpiAwarenessContext in a C# application with no success.

relevent头文件是:

The relevent header files are:

windef.h

DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);

typedef enum DPI_AWARENESS {
    DPI_AWARENESS_INVALID           = -1,
    DPI_AWARENESS_UNAWARE           = 0,
    DPI_AWARENESS_SYSTEM_AWARE      = 1,
    DPI_AWARENESS_PER_MONITOR_AWARE = 2
} DPI_AWARENESS;

#define DPI_AWARENESS_CONTEXT_UNAWARE              ((DPI_AWARENESS_CONTEXT)-1)
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE         ((DPI_AWARENESS_CONTEXT)-2)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE    ((DPI_AWARENESS_CONTEXT)-3)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4)

WinUser.h

WINUSERAPI
DPI_AWARENESS_CONTEXT
WINAPI
GetWindowDpiAwarenessContext(
    _In_ HWND hwnd);

我正在使用:

/// <summary>
/// Class for native methods.
/// </summary>
internal static class NativeMethods {

[DllImport("user32.dll")]
internal static extern IntPtr GetWindowDpiAwarenessContext(IntPtr hWnd);

...

            // Dpi awareness context
            IntPtr dpiAwarenessContext = NativeMethods.GetWindowDpiAwarenessContext(process.Handle);
            if (dpiAwarenessContext == (IntPtr)(-1)) {
                sb.AppendLine("  DPI Awareness Context: DPI_AWARENESS_CONTEXT_UNAWARE");
            } else if (dpiAwarenessContext == (IntPtr)(-2)) {
                sb.AppendLine("  DPI Awareness Context: DPI_AWARENESS_CONTEXT_SYSTEM_AWARE");
            } else if (dpiAwarenessContext == (IntPtr)(-3)) {
                sb.AppendLine("  DPI Awareness Context: DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE");
            } else if (dpiAwarenessContext == (IntPtr)(-4)) {
                sb.AppendLine("  DPI Awareness Context: DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2");
            } else {
                sb.AppendLine("  DPI Awareness Context failed: " + dpiAwarenessContext);
            }

它返回以下之一:0、18、34、24592、61457,而不是预期的-1,-2,-3或-4.此外,在随后对同一窗口的调用中,返回值也有所不同. (窗口处于此应用程序以外的其他进程中.)

It returns one of the following: 0, 18, 34, 24592, 61457, not the expected -1, -2, -3, or -4. In addition, in subsequent calls to the same window, the return value varies. (The windows are in other processes than this application.)

问题是定义和调用GetWindowDpiAwarenessContext的正确方法是什么.

The question is what is the proper way to define and call GetWindowDpiAwarenessContext.

提前谢谢.

推荐答案

我尚未找到DPI_AWARENESS_CONTEXT中的确切内容.它被实现为一个句柄,这对于32位和64位系统将有所不同.也许它指向一个结构,或者也许是一个位掩码.如果是这样,则我无法确定其结构.

I have yet to find exactly what is in a DPI_AWARENESS_CONTEXT. It is implemented as a handle, which will be different for 32-bit and 64-bit systems. Perhaps it points to a structure or perhaps it is a bitmask. If so, the structure is not defined that I can tell.

我现在知道您必须使用AreDpiAwarenessContextsEqual(context1,context2)来比较两个DPI_AWARENESS_CONTEXT.您无法比较这些值.这些是我正在使用的相关Pinvoke物品:

I do now know you have to use AreDpiAwarenessContextsEqual(context1, context2) to compare two DPI_AWARENESS_CONTEXT's. You can't compare the values. These are the relevant Pinvoke items I am using:

internal enum PROCESS_DPI_AWARENESS {
    PROCESS_DPI_UNAWARE = 0,
    PROCESS_SYSTEM_DPI_AWARE = 1,
    PROCESS_PER_MONITOR_DPI_AWARE = 2
}

internal enum DPI_AWARENESS {
    DPI_AWARENESS_INVALID = -1,
    DPI_AWARENESS_UNAWARE = 0,
    DPI_AWARENESS_SYSTEM_AWARE = 1,
    DPI_AWARENESS_PER_MONITOR_AWARE = 2
}

[DllImport("SHcore.dll")]
internal static extern int GetProcessDpiAwareness(IntPtr hWnd, out PROCESS_DPI_AWARENESS value);

[DllImport("user32.dll")]
internal static extern int GetDpiForWindow(IntPtr hWnd);

[DllImport("user32.dll")]
internal static extern IntPtr GetWindowDpiAwarenessContext(IntPtr hWnd);

[DllImport("user32.dll")]
internal static extern int GetAwarenessFromDpiAwarenessContext(IntPtr dpiContext);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool AreDpiAwarenessContextsEqual(IntPtr dpiContextA,
    IntPtr dpiContextB);

您可以使用WinDef.h中的这些值进行设置或比较:

You can use these values from WinDef.h to set or compare:

#define DPI_AWARENESS_CONTEXT_UNAWARE              ((DPI_AWARENESS_CONTEXT)-1)
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE         ((DPI_AWARENESS_CONTEXT)-2)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE    ((DPI_AWARENESS_CONTEXT)-3)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4)

但是,如果您使用这些值之一进行Set之后的Get操作,请不要期望将其中一个值取回来.使用AreDpiAwarenessContextsEqual.

But if you do a Get after a Set with one of these values, don't expect to get one of these values back. Use AreDpiAwarenessContextsEqual.

这篇关于用于GetWindowDpiAwarenessContext的C#Pinvoke的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆