Custom string identifiers CAN be used in DFMs for integer/enum properties. To do that, you need to call RegisterIntegerConsts()
in <System.Classes.hpp>
to register your own custom functions that convert between string identifiers and their ordinal values. In your case, converting "AllFormHeight"
and "AllFormWidth"
strings to specific integer values, and vice versa.
For instance, this is exactly how the DFM example you have shown allows the clBtnFace
identifier to be used for the Color
property.
Try this:
#include <System.Classes.hpp>
#include <System.TypInfo.hpp>
#include <sysopen.h>
const int AllFormHeight = 300;
const int AllFormWidth = 400;
const TIdentMapEntry MyFormIdents[] = {
{AllFormHeight, "AllFormHeight"},
{AllFormWidth, "AllFormWidth"}
};
bool __fastcall MyFormIdentToInt(const String Ident, int &Int)
{
return IdentToInt(Ident, Int, EXISTINGARRAY(MyFormIdents));
}
bool __fastcall MyIntToFormIdent(int Int, String &Ident)
{
return IntToIdent(Int, Ident, EXISTINGARRAY(MyFormIdents));
}
// See http://bcbjournal.org/articles/vol3/9908/Registering_AnsiString_property_editors.htm
// for why this function is needed...
TTypeInfo* IntTypeInfo()
{
TTypeInfo* typeInfo = new TTypeInfo;
typeInfo->Name = "int";
typeInfo->Kind = tkInteger;
return typeInfo;
/* alternatively:
TPropInfo* PropInfo = GetPropInfo(__typeinfo(TForm), "ClientHeight");
return *PropInfo->PropType;
*/
}
RegisterIntegerConsts(IntTypeInfo(), &MyFormIdentToInt, &MyIntToFormIdent);
However, the downside to this approach is that because the ClientHeight
/ClientWidth
properties are using int
as their data type, your custom identifiers will then be applied to ANY int
property in ANY streamable class. RegisterIntegerConsts()
is typically only used for more unique data types instead, like TColor
, TFontCharset
, etc.
You can't change the ClientHeight
/ClientWidth
properties themselves to use a different data type so you have something unique to map your identifiers to. But, you can define your own properties that use your own data type that you can then map. Or, you can try having your Form override the DefineProperties()
method to create "fake" properties just for DFM streaming. Either way, you could then optionally redeclare the ClientHeight
/ClientWidth
properties in your Form class to include the stored=false
attribute so they are not streamed in the DFM at all. Have your custom properties read/set the ClientHeight
/ClientWidth
properties internally.