C++ Builder 枚舉控件所有的屬性、事件和方法

C++ Builder 參考手冊 ? 枚舉控件所有的屬性管削、事件和方法


  • 獲取控件的成員
  • 枚舉所有的屬性和事件
  • 枚舉所有的方法
  • 枚舉所有的成員變量
  • 完整的例子

一. 獲取控件的成員

所有從 TObject 繼承的類都可以獲取成員信息糯钙,不僅僅是控件。

1. 獲取 TRttiType

首先使用 TRttiContext 的 GetType 方法獲取 TObject 繼承的類的類型信息 TRttiType:
TRttiType *GetType(System::TClass AClass);
這個函數(shù)的參數(shù)是 System::TClass 類型的电抚。

  • 如果是從 TObject 繼承的類,可以通過 TObject 的 ClassType() 方法獲得 System::TClass竖共,例如 Button1->ClassType()蝙叛;
  • 如果要通過類型來獲取 System::TClass,可以通過 __classid(類型)公给,例如 __classid(TButton)借帘。

獲取 TRttiType * 的完整的寫法:

TRttiContext RttiCtx;
TRttiType *pRttiType = RttiCtx.GetType(Button1->ClassType());

或者

TRttiContext RttiCtx;
TRttiType *pRttiType = RttiCtx.GetType(__classid(TButton));

2. 獲取屬性、事件淌铐、方法和變量表

通過 TRttiType 的 GetProperties 方法獲取屬性和事件表肺然;
通過 TRttiType 的 GetMethods 方法獲取方法 (成員函數(shù)) 表;
通過 TRttiType 的 GetFields 方法獲取成員變量表腿准。

DynamicArray<TRttiProperty *> aProperties = pRttiType->GetProperties();
DynamicArray<TRttiMethod   *> aMethods    = pRttiType->GetMethods();
DynamicArray<TRttiField    *> aFields     = pRttiType->GetFields();

二. 枚舉所有的屬性和事件

通過 TRttiType 的 GetProperties 方法獲取屬性和事件表放在了 DynamicArray<TRttiProperty *> 動態(tài)數(shù)組里面际起,數(shù)組的每一個元素是一個 TRttiProperty *。

  • 通過 TRttiProperty 的 PropertyType 屬性可以獲取屬性的變量類型吐葱;
  • 通過 TRttiProperty 的 Name 屬性可以獲取這個屬性的名字街望;
  • 通過 TRttiProperty 的 TValue GetValue(TObject *pObject) 方法,可以獲取 pObject 對象的這個屬性的屬性值弟跑。

屬性名稱和屬性的類型是類型的屬性它匕,通過類型信息就可以直接獲取到,而屬性的值是類的每個對象的屬性窖认,所以獲取屬性值必須指定具體的對象豫柬。

三. 枚舉所有的方法

通過 TRttiType 的 GetMethods 方法獲取方法 (成員函數(shù)) 表放在了 DynamicArray<TRttiMethod *> 動態(tài)數(shù)組里面,數(shù)組的每一個元素是一個 TRttiMethod *扑浸。

  • 通過 TRttiMethod 的 Name 屬性可以獲取這個方法的函數(shù)名烧给;
  • 通過 TRttiMethod 的 ReturnType 屬性可以獲取這個方法的函數(shù)返回值的類型;
  • 通過 TRttiMethod 的 GetParameters 方法可以獲取這個方法的函數(shù)的每個參數(shù)喝噪,存放在 DynamicArray<TRttiParameter *> 數(shù)組里面础嫡;
  • 通過 TRttiParameter 的 Name 屬性可以獲取函數(shù)的參數(shù)的名稱;
  • 通過 TRttiParameter 的 ParamType 屬性可以獲取函數(shù)的參數(shù)的變量類型酝惧。

四. 枚舉所有的成員變量

通過 TRttiType 的 GetFields 方法獲取成員變量表放在了 DynamicArray<TRttiField *> 動態(tài)數(shù)組里面榴鼎,數(shù)組的每一個元素是一個 TRttiField *。

  • 通過 TRttiField 的 Name 屬性可以獲取這個變量的變量名晚唇;
  • 通過 TRttiField 的 FieldType 屬性可以獲取這個變量的變量類型巫财;
  • 通過 TRttiField 的 TValue GetValue(TObject *pObject) 方法,可以獲取 pObject 對象的這個變量的變量值哩陕。

變量名和變量類型是類型的屬性平项,通過類型信息就可以直接獲取到,而變量的值是類的每個對象的屬性悍及,所以獲取變量值必須指定具體的對象闽瓢。

五. 完整的例子

  • 函數(shù) ShowAllMembers 參數(shù)可以是任意從 TObject 繼承過來的類的對象,包括控件心赶,可以顯示這個對象所有的成員及成員的值扣讼;
  • 模板函數(shù) EnumValName 把枚舉型的值轉成這個值的名字的字符串;
  • 函數(shù) ValueToStr 把 TValue 值轉成字符串缨叫;
  • 函數(shù) ShowProperties 把屬性顯示到 Memo1 里面椭符,把事件顯示到 Memo2 里面;
  • 函數(shù) ShowMethods 把方法顯示到 Memo3 里面弯汰;
  • 函數(shù) ShowFields 把變量顯示到 Memo4 里面艰山。

這個例子顯示 Edit1 編輯框的所有的成員,包括屬性咏闪、事件曙搬、方法、變量鸽嫂,如果要顯示其他控件的成員纵装,只需要 ShowAllMembers 的參數(shù)改成要顯示的控件就可以了。

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    ShowAllMembers(Edit1);
}
//---------------------------------------------------------------------------
template<class T>
UnicodeString EnumValName(T t)
{
    return Typinfo::GetEnumName(__delphirtti(T), (int)t);
}
//---------------------------------------------------------------------------
UnicodeString ValueToStr(TValue &Val)
{
    UnicodeString sValue;
    try
    {
        if(Val.IsEmpty)
        {
            sValue = L"NULL";
        }
        else
        {
            sValue = Val.ToString();
        }
    }
    catch(Exception &e)
    {
        sValue = L"Error (" + e.ClassName() + L"): " + e.Message;
    }
    return sValue;
}
//---------------------------------------------------------------------------
void TForm1::ShowAllMembers(TObject *pObject)
{
    TRttiContext RttiCtx;
    TRttiType *pRttiType = RttiCtx.GetType(pObject->ClassType());
    if(pRttiType)
    {
        DynamicArray<TRttiProperty *> aProperties = pRttiType->GetProperties();
        DynamicArray<TRttiMethod   *> aMethods    = pRttiType->GetMethods();
        DynamicArray<TRttiField    *> aFields     = pRttiType->GetFields();

        ShowProperties(pObject, aProperties);
        ShowMethods(pObject, aMethods);
        ShowFields(pObject, aFields);
    }
}
//---------------------------------------------------------------------------
void TForm1::ShowProperties(TObject *pObject, DynamicArray<TRttiProperty *> &aProperties)
{
    for(int i=0; i<aProperties.Length; i++)
    {
        TRttiProperty *pProperty = aProperties[i];

        TTypeKind TpKind = pProperty->PropertyType->TypeKind; // 屬性的類型
        UnicodeString sName = pProperty->Name; // 屬性的名字
        UnicodeString sValue;

        try
        {
            TValue Val = pProperty->GetValue(pObject);
            sValue = ValueToStr(Val);
        }
        catch(Exception &e)
        {
            sValue = L"Error (" + e.ClassName() + L"): " + e.Message;
        }

        if(TpKind == tkMethod) // 事件
            Memo2->Lines->Add(sName + L" = " + sValue);
        else // 屬性
            Memo1->Lines->Add(sName + L" = " + sValue);
    }
}
//---------------------------------------------------------------------------
void TForm1::ShowMethods(TObject *pObject, DynamicArray<TRttiMethod *> &aMethods)
{
    for(int iMethodIdx=0; iMethodIdx<aMethods.Length; iMethodIdx++)
    {
        TRttiMethod *pMethod = aMethods[iMethodIdx];
        UnicodeString sMethodName = pMethod->Name;
        DynamicArray<TRttiParameter *> aParameters = pMethod->GetParameters();
        UnicodeString sRetType;

        if(pMethod->ReturnType)
        {
            TTypeKind tRetKind = pMethod->ReturnType->TypeKind;
            sRetType = EnumValName(tRetKind);
        }
        else
        {
            sRetType = L"void";
        }

        UnicodeString sMethodStr = sRetType + L" " + sMethodName + L"(";
        for(int iParamIdx=0; iParamIdx<aParameters.Length; iParamIdx++)
        {
            TRttiParameter *pParameter = aParameters[iParamIdx];
            UnicodeString sPmName = pParameter->Name;
            UnicodeString sPmType;

            if(pParameter->ParamType)
            {
                TTypeKind tPmKind = pParameter->ParamType->TypeKind;
                sPmType = EnumValName(tPmKind);
            }
            else
            {
                sPmType = L"void *";
            }

            if(iParamIdx)
                sMethodStr += L", ";
            sMethodStr += sPmType + L" " + sPmName;
        }
        sMethodStr += L");";

        Memo3->Lines->Add(sMethodStr);
    }
}
//---------------------------------------------------------------------------
void TForm1::ShowFields(TObject *pObject, DynamicArray<TRttiField *> &aFields)
{
    for(int i=0; i<aFields.Length; i++)
    {
        TRttiField *pField = aFields[i];

        UnicodeString sName = pField->Name;
        UnicodeString sValue;

        try
        {
            TValue Val = pField->GetValue(pObject);
            sValue = ValueToStr(Val);
        }
        catch(Exception &e)
        {
            sValue = L"Error (" + e.ClassName() + L"): " + e.Message;
        }

        Memo4->Lines->Add(sName + L" = " + sValue);
    }
}
//---------------------------------------------------------------------------

運行結果:

運行結果:Edit1 的屬性
運行結果:Edit1 的事件
運行結果:Edit1 的方法
運行結果:Edit1 的變量

相關:


C++ Builder 參考手冊 ? 枚舉控件所有的屬性据某、事件和方法

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末橡娄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子癣籽,更是在濱河造成了極大的恐慌挽唉,老刑警劉巖滤祖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瓶籽,居然都是意外死亡匠童,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門塑顺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汤求,“玉大人,你說我怎么就攤上這事严拒⊙镄鳎” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵裤唠,是天一觀的道長挤牛。 經常有香客問我,道長巧骚,這世上最難降的妖魔是什么赊颠? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮劈彪,結果婚禮上竣蹦,老公的妹妹穿的比我還像新娘。我一直安慰自己沧奴,他們只是感情好痘括,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著滔吠,像睡著了一般纲菌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疮绷,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天翰舌,我揣著相機與錄音,去河邊找鬼冬骚。 笑死椅贱,一個胖子當著我的面吹牛,可吹牛的內容都是我干的只冻。 我是一名探鬼主播庇麦,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喜德!你這毒婦竟也來了山橄?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤舍悯,失蹤者是張志新(化名)和其女友劉穎航棱,沒想到半個月后睡雇,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡饮醇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年入桂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驳阎。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖馁蒂,靈堂內的尸體忽然破棺而出呵晚,到底是詐尸還是另有隱情,我是刑警寧澤沫屡,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布饵隙,位于F島的核電站,受9級特大地震影響沮脖,放射性物質發(fā)生泄漏金矛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一勺届、第九天 我趴在偏房一處隱蔽的房頂上張望驶俊。 院中可真熱鬧,春花似錦免姿、人聲如沸饼酿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽故俐。三九已至,卻和暖如春紊婉,著一層夾襖步出監(jiān)牢的瞬間药版,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工喻犁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留槽片,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓株汉,卻偏偏與公主長得像筐乳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子乔妈,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內容