首页 > 解决方案 > 如何获取属性的默认值?

问题描述

组件通常有很长的属性列表和可用的默认值:

class PACKAGE TMySpecialComboBox : public TCustomComboBox
{
public:
  __fastcall TMySpecialComboBox(TComponent *Owner);
  // ...

private:
  // ...
  bool fetch_all_;
  bool rename_;
  TColor background1_, background2_, background3_;
  // ...

__published:
  // ...
  __property bool FetchAll = {read = fetch_all_, write = fetch_all_,
                              default = false};
  __property bool Rename = {read = rename_, write = rename_,
                            default = false};
  __property TColor Background1 = {read = background1_, write = background1_,
                                   default = clWindow};
  __property TColor Background2 = {read = background2_, write = background2_,
                                   default = clWindow};
  __property TColor Background3 = {read = background3_, write = background3_,
                                   default = clWindow};
  // ...
};

将所有这些信息存储在表单文件中会浪费空间并且将其读回需要时间,这是不可取的,因为在大多数情况下,很少有默认值更改。

为了尽量减少表单文件中的数据量,您可以为每个属性指定一个默认值(写入表单文件时,表单编辑器会跳过任何值未更改的属性)。

请注意,这样做不会设置默认值:

注意:属性值不会自动初始化为默认值。也就是说,默认指令仅控制何时将属性值保存到表单文件,而不控制新创建的实例上的属性初始值。

构造函数负责这样做:

__fastcall TMySpecialComboBox::TMySpecialComboBox(TComponent* Owner)
  : TCustomComboBox(Owner), // ...
{
  FetchAll = false;       // how to get the default value ?
  Rename = false;         // how to get the default value ?
  Background1 = clWindow  // how to get the default value ?
  // ...
}

但是以这种方式编写初始化非常容易出错。

如何获得 a 的默认值__property

标签: c++buildervclrttidfm

解决方案


它可以通过TRttiContext结构来完成。

#include <Rtti.hpp>

int get_property_default(const String &name)
{
  TRttiContext ctx;

  auto *p(ctx.GetType(__classid(TMySpecialComboBox))->GetProperty(name));
  assert(dynamic_cast<TRttiInstanceProperty *>(p));

  return static_cast<TRttiInstanceProperty *>(p)->Default;
}

__fastcall TMySpecialComboBox::TMySpecialComboBox(TComponent* Owner)
  : TCustomComboBox(Owner), // ...
{
  FetchAll = get_property_default("FetchAll");
  // ...
}

参考:


推荐阅读