سؤال

لقد بدأت مؤخرا في ترقية مشروع 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 في وقت ما الإجراءات لتوفير واجهة واحدة بين الأزرار والقوائم وما إلى ذلك والإرسم رمز؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top