首页 > 解决方案 > 在 embarcadero / RAD 工作室中跨 .dfm 文件使用常量

问题描述

我有一个 Windows Vcl 应用程序,里面有几种形式。我想标准化所有这些表单的布局。所以我想声明一些可以应用于所有 .dfm 布局文件的常量。

例如,这个 main from 是 IDE 中自动生成的表单:

object frm_MainForm: Tfrm_MainForm
  Left = 0
  Top = 0
  Caption = 'Main Form'
  ClientHeight = 300
  ClientWidth = 400    
  Color = clBtnFace
end

我想做的是声明如下内容:

AllFormHeight = 300
AllFormWidth = 400

这样我就可以申请以下所有表格:

object frm_MainForm: Tfrm_MainForm
  Left = 0
  Top = 0
  Caption = 'Main Form'
  ClientHeight = AllFormHeight <--- Like this
  ClientWidth = AllFormWidth <--- And this
  Color = clBtnFace
end

我尝试做一些与 Vcl.Graphics.hpp 中的颜色常数几乎相似的事情,但它不起作用。我正在使用 Embarcadero RAD Studio C++ Builder 10.3。我使用 C++ 进行编程,使用 dfm 文件作为 UI 文件。

标签: c++c++buildervcldfm

解决方案


自定义字符串标识符可以在DFM中用于整数/枚举属性。为此,您需要调用RegisterIntegerConsts()<System.Classes.hpp>注册您自己的自定义函数,这些函数在字符串标识符和它们的序数值之间进行转换。在您的情况下,将"AllFormHeight""AllFormWidth"字符串转换为特定的整数值,反之亦然。

例如,这正是您展示的 DFM 示例允许将clBtnFace标识符用于Color属性的方式。

尝试这个:

#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);

然而,这种方法的缺点是因为ClientHeight/ClientWidth属性被int用作它们的数据类型,您的自定义标识符随后将应用于任何可int流式传输类中的任何属性。 RegisterIntegerConsts()通常仅用于更独特的数据类型,例如TColor,TFontCharset等。

您无法更改ClientHeight/ClientWidth属性本身以使用不同的数据类型,因此您可以将标识符映射到独特的东西。但是,您可以定义自己的属性,这些属性使用您自己的数据类型,然后您可以映射。或者,您可以尝试让您的表单覆盖该DefineProperties()方法以仅为 DFM 流式传输创建“假”属性。无论哪种方式,您都可以选择在 Form 类中重新声明ClientHeight/ClientWidth属性以包含该stored=false属性,这样它们就不会在 DFM 中进行流式传输。让您的自定义属性在内部读取/设置ClientHeight/ClientWidth属性。


推荐阅读