c++builder - 如何获取属性的默认值?
问题描述
组件通常有很长的属性列表和可用的默认值:
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
?
解决方案
它可以通过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");
// ...
}
参考:
- C++Builder 2010 中增强的 RTTI,第一部分: Remy Lebeau 的介绍(BCBJ 第 13 卷,第 8 期,2009 年 8 月);
__classid
. 您可以使用它来获取基于 TObject 的类(Delphi 风格的类)的元类;- 德尔福 RTTI 和 C++Builder。Delphi RTTI 不同于标准 C++ RTTI。
推荐阅读
- sql-server - 尝试使用 sql_server_socket 将我的应用程序与 SQL Server 连接起来。在 SqlConnection.dart 中,未正确指定 guinness 包的版本
- azure-devops - Azure YAML Pipelines:如何在 Azure DevOps 的另一个项目中引用一个项目和 repo
- for-loop - FOR循环/向量化数列
- lua - 如何在 ROBLOX 中制作杀手机器人
- python - 在 Python 中录制时检测并分割静音
- mongodb - $ 查找 mongodb 对象数组
- python - Flask、Asyncio、BS4、Requests-html ValueError:信号仅在主解释器的主线程中有效
- android - 使用 replace() 时片段未替换
- blockchain - 使用 web3.js 调用以太坊合约时出现意外错误
- spring - Spring Boot REST API - 字段 ID 的类型不匹配