以下代码来自Windows 10周年更新SDK。为了在Delphi中使用API,我需要常量句柄,因为从今天起,这些标题不包括在Delphi中。
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
#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)当我在各种DPI场景中使用GetThreadDpiAwarenessContext时,我了解了NativeUInts的值是什么:
DPI_AWARENESS_CONTEXT_UNAWARE = 16;
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 17;
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 18;但我想100%肯定这些值是未来的证明.它们确实在SetThreadDpiAwarenessContext调用中工作,并具有预期的效果,但我不清楚这些值是如何得到的。除了显式整数声明之外,我无法在Delphi中复制生成这些结果的头结构。
发布于 2017-01-18 00:44:02
要在SetThreadDpiAwarenessContext中使用,您应该将它声明为
type
DPI_AWARENESS_CONTEXT = type THandle;
const
DPI_AWARENESS_CONTEXT_UNAWARE = DPI_AWARENESS_CONTEXT(-1);
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = DPI_AWARENESS_CONTEXT(-2);
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE= DPI_AWARENESS_CONTEXT(-3);但是当您从GetThreadDpiAwarenessContext获得响应时,您需要对接收到的值使用GetAwarenessFromDpiAwarenessContext,并将其与AWARENESS枚举进行比较。
您不能直接比较DPI_AWARENESS_CONTEXT,因为它包含多个信息,而且微软将来可能会更改它。
发布于 2017-01-18 00:45:11
Delphi根本不使用C/C++包含文件,所以不管Windows SDK是否随IDE一起提供,它不会在Delphi项目中使用。现在,如果您担心Delphi没有提供C头文件的Pascal翻译,那就另当别论了。
DECLARE_HANDLE()是一个C预处理器宏,它根据输入参数的值以及是否定义了预处理器STRICT条件来声明新的数据类型别名:
#ifdef STRICT
typedef void *HANDLE;
#if 0 && (_MSC_VER > 1000)
#define DECLARE_HANDLE(name) struct name##__; typedef struct name##__ *name
#else
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
#endif
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endifSTRICT为C/C++代码提供了更多的类型安全性。许多Win32句柄类型是用户代码中不透明的类型。使用DECLARE_HANDLE()声明它们允许编译器在定义STRICT时将它们视为不同的数据类型,从而防止将不同的句柄类型错误地混合在一起(例如,传递期望HWND的HBITMAP,等等)。在引入STRICT之前,许多开发人员都犯了这样的错误,因为所有句柄类型实际上都是void*,从而防止了任何编译时验证。
这意味着DECLARE_HANDLE(DPI_AWARENESS_CONTEXT)将像这样声明DPI_AWARENESS_CONTEXT:
STRICT时:
结构DPI_AWARENESS_CONTEXT__{int未使用;};STRICT时:
去胡枝子* DPI_AWARENESS_CONTEXT;因此,DPI_AWARENESS_CONTEXT被声明为指向记录类型的指针或非类型指针,这取决于STRICT。
这种名称解析不能转换为Delphi,因为它不像C/C++那样支持预处理宏。最接近的翻译应该是直接声明DPI_AWARENESS_CONTEXT:
type
{$IFDEF STRICT}
DPI_AWARENESS_CONTEXT__ = record
end;
DPI_AWARENESS_CONTEXT = ^DPI_AWARENESS_CONTEXT__;
{$ELSE}
DPI_AWARENESS_CONTEXT = Pointer;
{$ENDIF}或者干脆忘记德尔菲中存在的STRICT:
type
DPI_AWARENESS_CONTEXT__ = record
end;
DPI_AWARENESS_CONTEXT = ^DPI_AWARENESS_CONTEXT__;无论哪种方式,一旦声明了DPI_AWARENESS_CONTEXT,您就可以声明其常量值:
const
DPI_AWARENESS_CONTEXT_UNAWARE = DPI_AWARENESS_CONTEXT(-1);
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = DPI_AWARENESS_CONTEXT(-2);
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = DPI_AWARENESS_CONTEXT(-3);Update:基于注释,您可以选择使用以下选项:
type
DPI_AWARENESS_CONTEXT = type THandle;
const
DPI_AWARENESS_CONTEXT_UNAWARE = DPI_AWARENESS_CONTEXT(-1);
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = DPI_AWARENESS_CONTEXT(-2);
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = DPI_AWARENESS_CONTEXT(-3);请注意,这些常量仅用于SetThreadDpiAwarenessContext()的输入,而不是用于GetThreadDpiAwarenessContext()的输出。后者返回私有内存结构的不透明句柄。您需要使用GetAwarenessFromDpiAwarenessContext()从该结构中检索实际的DPI_AWARENESS值。
https://stackoverflow.com/questions/41708679
复制相似问题