简体   繁体   English

在 embarcadero / RAD studio 中跨 .dfm 文件使用常量

[英]Using constant across .dfm files in embarcadero / RAD studio

I have a Windows Vcl Application which have several forms inside.我有一个 Windows Vcl 应用程序,里面有几种形式。 I wanted to standardize the layout for all of these forms.我想标准化所有这些表单的布局。 So I wanted to declare some constants which I can apply across all of my .dfm layout file.所以我想声明一些可以应用于我所有 .dfm 布局文件的常量。

For example, this main from is the automatically generated form in the IDE:例如,这个 main from 是 IDE 中自动生成的表单:

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

What I wanted to do is to declare something like:我想做的是声明如下内容:

AllFormHeight = 300
AllFormWidth = 400

So that I can apply to all form like the following:这样我就可以申请所有表格,如下所示:

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

I tried doing something almost similar to the color constant in Vcl.Graphics.hpp but it doesn't work.我尝试做一些几乎类似于 Vcl.Graphics.hpp 中的颜色常量的事情,但它不起作用。 I'm using Embarcadero RAD studio C++ Builder 10.3.我正在使用 Embarcadero RAD studio C++ Builder 10.3。 I used C++ for the programming and dfm file as the UI file.我使用 C++ 进行编程,使用 dfm 文件作为 UI 文件。

Custom string identifiers CAN be used in DFMs for integer/enum properties.自定义字符串标识符可以的DFM整数/枚举性质。 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.为此,您需要调用<System.Classes.hpp> RegisterIntegerConsts()来注册您自己的自定义函数,这些函数在字符串标识符及其序数值之间进行转换。 In your case, converting "AllFormHeight" and "AllFormWidth" strings to specific integer values, and vice versa.在您的情况下,将"AllFormHeight""AllFormWidth"字符串转换为特定的整数值,反之亦然。

For instance, this is exactly how the DFM example you have shown allows the clBtnFace identifier to be used for the Color property.例如,这正是您展示的 DFM 示例允许将clBtnFace标识符用于Color属性的方式。

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.但是,这种方法的缺点是,因为ClientHeight / ClientWidth属性使用int作为它们的数据类型,所以您的自定义标识符将应用于任何可流类中的任何int属性。 RegisterIntegerConsts() is typically only used for more unique data types instead, like TColor , TFontCharset , etc. RegisterIntegerConsts()通常仅用于更独特的数据类型,例如TColorTFontCharset等。

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.您不能更改ClientHeight / ClientWidth属性本身以使用不同的数据类型,因此您可以将标识符映射到唯一的内容。 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.或者,您可以尝试让您的 Form 覆盖DefineProperties()方法来为 DFM 流创建“假”属性。 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.无论哪种方式,您都可以选择在您的 Form 类中重新声明ClientHeight / ClientWidth属性以包含stored=false属性,因此它们根本不会在 DFM 中流式传输。 Have your custom properties read/set the ClientHeight / ClientWidth properties internally.让您的自定义属性在内部读取/设置ClientHeight / ClientWidth属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM