为在 Embarcadero C++ Builder 中生成的 VCL Style Utils 包含 .hpp 文件时出错

Error when including .hpp files for VCL Style Utils generated in Embarcadero C++ Builder

我想在 Embarcadero C++Builder 10.2 Tokyo 中使用库 "VCL Style Utils"。

所以我创建了一个新项目并添加了:

Vcl.Styles.Utils.Graphics.pas
Vcl.Styles.Utils.Menus.pas
Vcl.Styles.Utils.SysControls.pas
Vcl.Styles.Utils.SysStyleHook.pas

构建成功并为这些 .pas 个文件生成 .hpp 个文件。

然后我创建另一个项目并包含生成的 .hpp 个文件。

但是在构建时出现此错误:

[bcc32 Error] Vcl.Styles.Utils.Menus.hpp(164): E2040 Declaration terminated incorrectly.

这是 Vcl.Styles.Utils.Menus.hpp 的第 163 和 164 行:

static const System::Word MN_SETHMENU = System::Word(0x1e0);
static const System::Word MN_GETHMENU = System::Word(0x1e1);

为什么这些声明不正确?

在范围内的另一个 C/C++ 头文件中可能预先存在 MN_SETHMENUMN_GETHMENU#define 语句,例如:

#define MN_SETHMENU 0x01E0
#define MN_GETHMENU 0x01E1

如果是这样,那会干扰 Vcl.Styles.Utils.Menus.hpp 中生成的声明,使编译器将它们视为:

static const System::Word 0x01E0 = System::Word(0x1e0);
static const System::Word 0x01E1 = System::Word(0x1e1);

这显然是错误的,因此是错误的。

Vcl.Styles.Utils.Menus.pas(通常在 .pas 文件中),MN_SETHMENUMN_GETHMENU 的声明(以及已经在 C/C++ headers) 需要用 {$EXTERNALSYM ...} 指令标记,这样它们就不会在生成的 .hpp 文件中重新声明,例如:

{$EXTERNALSYM MN_SETHMENU} // <-- add this
MN_SETHMENU = E0;

{$EXTERNALSYM MN_GETHMENU} // <-- add this
MN_GETHMENU = E1;

如有必要,使用 {$HPPEMIT '...'} 指令将合适的 #include 语句添加到生成的 .hpp 文件中,以便它可以将其他 C/C++ 头文件作为需要,例如:

{$HPPEMIT '#include <OtherFile.h>'}