以下代码来自Windows 10 Anniversary Update 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)
Run Code Online (Sandbox Code Playgroud)
当我在各种DPI场景中使用GetThreadDpiAwarenessContext时,我已经了解了NativeUInts的值是什么:
DPI_AWARENESS_CONTEXT_UNAWARE = 16;
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 17;
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 18;
Run Code Online (Sandbox Code Playgroud)
但我想100%肯定这些价值观是面向未来的.它们在SetThreadDpiAwarenessContext调用中工作并具有所需的效果,但我不清楚这些值是如何得出的.除了显式整数声明之外,我无法在Delphi中复制生成这些结果的头部构造.
Eug*_*neK 10
要在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);
Run Code Online (Sandbox Code Playgroud)
但是当您从GetThreadDpiAwarenessContext获得响应时,您需要对收到的值使用GetAwarenessFromDpiAwarenessContext并将其与DPI_AWARENESS枚举进行比较 .
您不能直接比较,DPI_AWARENESS_CONTEXT
因为它包含多条信息,Microsoft可能会在将来更改它.
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
#endif
Run Code Online (Sandbox Code Playgroud)
STRICT
为C/C++代码提供更多类型安全性.许多Win32句柄类型在用户代码中是不透明的类型.声明使用它们DECLARE_HANDLE()
允许将它们视为当不同数据类型进行编译器STRICT
被定义,从而防止不同句柄类型被错误地混合在一起(即,传递一个HBITMAP
其中一个HWND
预计,等等).许多开发人员在STRICT
引入之前就犯了这种错误,因为所有句柄类型都是有效的void*
,因此阻止了任何编译时验证.
这意味着DECLARE_HANDLE(DPI_AWARENESS_CONTEXT)
将声明DPI_AWARENESS_CONTEXT
如下:
什么时候STRICT
定义:
struct DPI_AWARENESS_CONTEXT__{int unused;};
typedef struct DPI_AWARENESS_CONTEXT__ *DPI_AWARENESS_CONTEXT;
Run Code Online (Sandbox Code Playgroud)什么时候STRICT
没有定义:
typedef void* DPI_AWARENESS_CONTEXT;
Run Code Online (Sandbox Code Playgroud)因此,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}
Run Code Online (Sandbox Code Playgroud)
或者STRICT
在Delphi 中完全忘记存在:
type
DPI_AWARENESS_CONTEXT__ = record
end;
DPI_AWARENESS_CONTEXT = ^DPI_AWARENESS_CONTEXT__;
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,一旦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);
Run Code Online (Sandbox Code Playgroud)
更新:根据评论,你可以改为使用它:
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);
Run Code Online (Sandbox Code Playgroud)
请注意,这些常量仅用于输入SetThreadDpiAwarenessContext()
,而不用于输出GetThreadDpiAwarenessContext()
.后者将私有内存结构的不透明句柄返回.您需要使用从该结构中GetAwarenessFromDpiAwarenessContext()
检索实际DPI_AWARENESS
值.