ماذا حدث لسلسلة الميراث TBTBTTN و TButton؟
-
09-09-2019 - |
سؤال
لقد بدأت مؤخرا في ترقية مشروع Rad Studio 2007 الخاص بي إلى Rad Studio 2009. شيء واحد لاحظته هو عندما فشلت الكود البسيط على ما يبدو فجأة في الترجمة.
رمز المثال:
class CButtonPopupMenu
{
// Snip
public:
void Init( TButton* SrcButton )
{
SrcButton->OnClick = OnButtonClick;
}
private:
void __fastcall OnButtonClick( TObject* Sender )
{
// Do some button click stuff
}
};
// Snip
TButton button = new TButton( this );
TBitBtn bitBtn = new TBitBtn( this );
CButtonPopupMenu popupButton = new CButtonPopupMenu( button );
CButtonPopupMenu popupBitBtn = new CButtonPopupMenu( bitBtn );
كل هذا يستخدم لتجميع، ولكن مع 2009 فشل. النظر في سلسلة الميراث لعام 2007 TBitBtn
تستخدم للاستمتاع من TButton
. وبعد لذلك، تم مشاركة الأحداث المتوقعة على أي عنصر تحكم زر (أي OnClick) من قبل TButton
صف دراسي. لذلك، كنت قادرا على علاج بلدي TBitBtn
فئة ك TButton
.
2007 سلسلة الميراث:
- TBTBTN: Tbutton.
2009 سلسلة الميراث:
- TBTBTN: Tcustombutton.
- Tbutton: Tcustombutton.
في عام 2009، كلاهما tbutton. و tbitbutton. يشتق من Tcustombutton., ، والتي ستكون على ما يرام أفترض إذا تم إجراء زر مثل السمات هناك. إذا كان هذا هو الحال، فقد يمكنني فقط تغيير التعليمات البرمجية للتعامل مع Tcustombutton. في حين أن. لسوء الحظ، Tcustombutton. لا يحمل أشياء مثل عند النقر. وبعد لذلك، لم أعد أستطيع التعامل مع tbitbtn. مثل أ tbutton.. وبعد كل من هذه الفصول الدراسية، لديها الآن زر منفصلة خاصة بهم مثل السمات (أي كلاهما لديهما حدث onclick الخاص بهم المعلن). أعني، على الأقل توفير واجهة أو شيء ما، مثل Ibutton. هذان الاثنان tbutton. و tbitbtn. ينفذ.
يبدو أن هذه الأنواع من التغييرات الأبرياء على ما يبدو هي تلك التي يمكن أن تعجب الخراب غير الضروري. يبدو أن هذا غريب وأتساءل عما إذا كان أي شخص يعرف السبب في قيام كادواتي (أو أي مؤلف إطار لهذه المسألة) بهذا النوع من الأشياء؟
والأهم من ذلك، بالنظر إلى هذا الميراث المجزأ، هل هناك و أنيق حل لعلاج tbitbtn. مثل أ tbutton.?
المحلول
لا تزال Tbutton و TBTBTN لا تزال مشاركة حدث OnClick مشترك، حيث يتم تنفيذها طوال الطريق إلى مستوى Tcontrol لتبدأ، وكان دائما. كان Tbutton مجرد تعزيز حدث Tcontrol :: OnClick المحمي للنشر، الذي يرثه TBTBTN بعد ذلك.
في D2009، لا تعزز Tcustombutton، مثل دروس Tcustom الأخرى ...، الأعضاء المحمية من الطبقات الأساسية للنشر. TButton و TBTBTN تعزيز حدث TControl المحمي :: OnClick للنشر بشكل فردي. لكن الحدث نفسه لا يزال موجودا على مستوى Tcontrol.
نظرا لأنه محمي على مستوى Tcontrol، يمكنك استخدام فئة Accessor للوصول إليها، أي:
class TCustomButtonAccess
{
public:
__property OnClick;
};
class CButtonPopupMenu
{
// Snip
public:
void Init( TCustomButton* SrcButton )
{
((TCustomButtonAccess*)SrcButton)->OnClick = OnButtonClick;
}
private:
void __fastcall OnButtonClick( TObject* Sender )
{
// Do some button click stuff
}
};
أو، لأي مؤشر Tcontrol العام:
class TControlAccess
{
public:
__property OnClick;
};
class CControlPopupMenu
{
// Snip
public:
void Init( TControl* SrcControl )
{
((TControlAccess*)SrcControl)->OnClick = OnControlClick;
}
private:
void __fastcall OnControlClick( TObject* Sender )
{
// Do some click stuff
}
};
سيكون الحل الأكثر أناقة استخدام RTTI بدلا من ذلك، مما سيسمح لك أيضا باستخدام أنواع أخرى من الكائنات، مثل TspeedButton، والتي لها حدث OnClick الخاص به، أي:
#include <TypInfo.hpp>
class TControlAccess
{
public:
__property OnClick;
};
class CControlPopupMenu
{
// Snip
public:
void Init( TControl* SrcControl )
{
TMethod m;
m.Code = &OnControlClick;
m.Data = this;
SetMethodProp(SrcControl, "OnClick", m);
}
private:
void __fastcall OnControlClick( TObject* Sender )
{
// Do some click stuff
}
};
او حتى:
#include <TypInfo.hpp>
class CObjectPopupMenu
{
// Snip
public:
void Init( TObject* SrcObject )
{
TMethod m;
m.Code = &OnObjectClick;
m.Data = this;
SetMethodProp(SrcObject, "OnClick", m);
}
private:
void __fastcall OnObjectClick( TObject* Sender )
{
// Do some click stuff
}
};
نصائح أخرى
إذا كان هذا دلفي، أود أن أقترح فئة Tcustombutton مع يكون و كما العاملين:
if (SrcButton is TButton) then
(SrcButton as TButton).OnClick := OnButtonClick
else if (SrcButton is TBitButton)
(SrcButton as TBitButton).OnClick := OnButtonClick;
C ++ ببساطة منذ فترة طويلة
راجع للشغل، لم يشمل VCL في وقت ما الإجراءات لتوفير واجهة واحدة بين الأزرار والقوائم وما إلى ذلك والإرسم رمز؟