1

I want to use the library "VCL Style Utils" in Embarcadero C++Builder 10.2 Tokyo.

So I created a new project and added:

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

The build is successful and generates .hpp files for these .pas files.

Then I create another project and include the .hpp files generated.

But when building I get this error:

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

Here are lines 163 and 164 of Vcl.Styles.Utils.Menus.hpp :

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

Why are these declarations incorrect ?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Arnaud
  • 109
  • 3
  • 15

1 Answers1

0

There are likely pre-existing #define statements for MN_SETHMENU and MN_GETHMENU in another C/C++ header file that is in scope, eg:

#define MN_SETHMENU 0x01E0
#define MN_GETHMENU 0x01E1

If so, that would interfere with the declarations generated in Vcl.Styles.Utils.Menus.hpp, making the compiler see them as:

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

Which is clearly wrong, and hence the errors.

In Vcl.Styles.Utils.Menus.pas (and in .pas files in general), the declarations for MN_SETHMENU and MN_GETHMENU (and anything else that is already pre-defined in C/C++ headers) need to be marked with the {$EXTERNALSYM ...} directive so they are not re-declared in the generated .hpp file, eg:

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

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

If necessary, use the {$HPPEMIT '...'} directive to add suitable #include statements to the generated .hpp file so it can pull in other C/C++ header files as needed, eg:

{$HPPEMIT '#include <OtherFile.h>'}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for your quick answer. I'm not sure how to use EXTERNALSYM. I tried `{$EXTERNALSYM MN_SETHMENU}`. Without then with keeping the declaration `'MN_SETHMENU = $01E0;`. And without then with uncommenting these lines : `{$IF CompilerVersion >= 27}` // uncomment these lines if you want to use the VCL Styles Menus Hooks `{$UNDEF UseVCLStyleUtilsMenu}` // included on XE6-XE8 (Embarcadero Version) // `{$IFEND}` – Arnaud May 29 '18 at 08:54
  • I tried this too: adding `{$HPPEMIT #include }` but i'm not sure of the pascal pre-processor syntax and it gives the error `E1030 Invalid compiler directive`. – Arnaud May 29 '18 at 09:12
  • @Arnaud I updated my answer to show how to use `EXTERNALSYM`. And you don't need to use `HPPEMIT` to include other VCL headers, any unit specific in the `uses` clause of the `interface` section is automatically converted into an `#include` statement. – Remy Lebeau May 29 '18 at 14:49
  • Thank you Remy. With the $EXTERNALSYM as you updated it the declaration are not in the `.hpp`. – Arnaud May 30 '18 at 15:36