主页C++ Builder 资料C++ Builder 编程技巧界面处理枚举控件的属性、事件、成员函数和变量
C++ Builder 串口控件
C++ Builder 编程技巧
字符串及文字处理
多媒体处理
图片处理
文件处理
界面处理
 • 使用 Action 控件
 • 其他程序文字拖拽到Memo里
 • 把文件拖拽到窗口里面
 • 枚举控件的属性、事件、成员函数和变量
C++ Builder 操作指南
C++ Builder 参考手册
网友留言/技术支持
枚举控件的属性、事件、成员函数和变量

因为从 System::TObject 继承的类都支持枚举类的成员的 RTTI 功能,所以,所有的控件都支持枚举成员,包括属性、事件、成员函数和成员变量。

这些 RTTI 功能的头文件为

#include <System.Rtti.hpp>

需要的模板函数 EnumToStr 是为了以字符串的形式显示枚举值,而不是整数值:

template<class T>
UnicodeString EnumToStr(T t){ return Typinfo::GetEnumName(__delphirtti(T),(int)t); }

枚举属性和事件,参数 lpObject:要枚举的控件 (所有从 TObject 继承的类都支持枚举属性和事件),
枚举到的内容,如果类型是 tkMethod 就是事件,其他类型是属性,因为事件是类型为 __closure 函数指针的属性

void EnumPropertyList(TObject *lpObject) // 枚举属性和事件
{
  TRttiContext context;
  TRttiInstanceType *cls = dynamic_cast<TRttiInstanceType*>(context.GetType(lpObject->ClassType()));
  if(cls)
   {
     System::DynamicArray<TRttiProperty*> PropArray = cls->GetProperties();
     for(int i=0; i<PropArray.Length; i++)
      {
        TRttiProperty *lpProperty = PropArray[i];
        UnicodeString sProp, sName, sKind, sValue;
        sName = lpProperty->Name;
        sKind = EnumToStr(lpProperty->PropertyType->TypeKind);
        sProp = lpProperty->PropertyType->TypeKind == tkMethod ? L"事件" : L"属性";
        try
         {
           TValue vVal = lpProperty->GetValue(lpObject);
           sValue = vVal.ToString();
         }
        catch(Exception &e)
         {
           sValue = e.ClassName() + L": " + e.Message;
         }
        Form1->Memo1->Lines->Add(sProp + L": " + sName + L", 类型: " + sKind + L", 值: " + sValue);
      }
   }
}

枚举成员函数,参数 lpObject:要枚举的控件 (所有从 TObject 继承的类都支持枚举成员函数)

void EnumMethodList(TObject *lpObject) // 枚举成员函数
{
  TRttiContext context;
  TRttiInstanceType *cls = dynamic_cast<TRttiInstanceType*>(context.GetType(lpObject->ClassType()));
  if(cls)
   {
     System::DynamicArray<TRttiMethod*> MethodList = cls->GetMethods();
     for(int i=0; i<MethodList.Length; i++)
      {
        Form1->Memo1->Lines->Add(L"成员函数: " + MethodList[i]->Name);
      }
   }
}

枚举成员变量,参数 lpObject:要枚举的控件 (所有从 TObject 继承的类都支持枚举成员变量)

void EnumFieldList(TObject *lpObject) // 枚举成员变量
{
  TRttiContext context;
  TRttiInstanceType *cls = dynamic_cast<TRttiInstanceType*>(context.GetType(lpObject->ClassType()));
  if(cls)
   {
     System::DynamicArray<TRttiField*> FieldList = cls->GetFields();
     for(int i=0; i<FieldList.Length; i++)
      {
        TRttiField *lpField = FieldList[i];
        UnicodeString sName, sKind, sValue;
        sName = lpField->Name;
        sKind = EnumToStr(lpField->FieldType->TypeKind);
        try
         {
           TValue vVal = lpField->GetValue(lpObject);
           sValue = vVal.ToString();
         }
        catch(Exception &e)
         {
           sValue = e.ClassName() + L": " + e.Message;
         }
        Form1->Memo1->Lines->Add(L"成员变量: " + sName + L", 类型: " + sKind + L", 值: " + sValue);
      }
   }
}

在 Form 上放一个 Memo1 和三个按钮 Button1、Button2、Button3,三个按钮分别枚举 Memo1 的属性事件、成员函数和成员变量

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  EnumPropertyList(Button1); // 枚举控件 Button1 的属性和事件
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  EnumMethodList(Button1); // 枚举控件 Button1 的成员函数
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
  EnumFieldList(Button1); // 枚举控件 Button1 的成员变量
}
//---------------------------------------------------------------------------

点击 Button1 枚举属性和事件的执行结果:

点击 Button2 枚举成员函数的执行结果:

点击 Button3 枚举成员变量的执行结果:

兼容性:

C++ Builder 2010 C++ Builder XE ~ XE8 C++ Builder 10.0 Seattle ~ 10.2.3 Tokyo
不支持 暂未测试 支持
◤上一页:把文件拖拽到窗口里面

C++ 爱好者 -- Victor Chen 的个人网站 www.cppfans.com 辽ICP备11016859号