通知一个控件另一个控件有状态更改

发布于 2025-01-15 04:11:32 字数 383 浏览 3 评论 0原文

我正在使用 C++Builder Enterprise 并且需要一些想法。

我有一个表单,上面有一堆 TButtonTSpeedButton 控件。我想要发生的是,当按下给定按钮时,我想禁用它和其他几个按钮,同时启用其他几个按钮,即状态更改。

问题是我在很多地方复制启用/禁用代码。我考虑过以某种方式使用 TNotifyEvent 委托来提醒按钮状态更改,但我认为委托技术在这种情况下不起作用。我想避免创建一堆 TButton/TSpeedButton 的子类。

我还想尝试使用 VCL 中提供的技术,因为每个组件都带有一个观察者列表,并且想知道我是否可以以某种方式利用它。

I am using C++Builder Enterprise and need some ideas.

I have a Form with a bunch of TButton and TSpeedButton controls on it. What I want to have happen is that, when a given button is pressed, I want to disable it and several others, while enabling several other buttons, i.e. state changes.

The issue is that I am duplicating the enable/disable code in a bunch of places. I've thought about somehow using the TNotifyEvent delegation to alert the buttons of a state change, but I don't think that delegation technique will work in this situation. I want to avoid creating a bunch of sub-classes of TButton/TSpeedButton.

I also would like to try to use techniques that are available from the VCL, as in each component carries an observer list and wonder if I could leverage that somehow.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

奢华的一滴泪 2025-01-22 04:11:32

我的 2 美分价值..

我已经为你的问题做了一个概念验证,需要做更多的工作,但我认为这是可行的,并且应该做你想要的。

如果有兴趣,我会做更多的工作并发布。

要查找窗体上某个类类型的所有控件

--- TControlAgent->FindTControl(this, "TButton");

我在表单上添加了4个按钮,向button1单击事件添加了以下代码,

TControlAgent->SetControlProperty("Enabled", "TButton", false, true, "Button3");

在这种情况下,想要类名为 TButton、state = true 或 false 的具有 Enabled 属性的控件,执行该操作,但排除名为 TButton3 的控件,

结果是表单上除按钮 3 之外的所有 TButton 都设置为禁用

(注意:排除选项将是要从任何操作中排除的控件的查找列表,或者能够设置不是该状态的状态,例如 Enabled = !true 或 !false )

在 button3 的单击事件中,我放置了以下代码;

TControlAgent->SetControlProperty("启用", "TButton", true, true, "");

这样做的结果是重新启用所有控件,这只是一个想法,但通过额外的工作,可以对表单集合中任何表单的单个父表单的任何控件执行任何操作。

我还认为有可能触发事件,只是一个疯狂的想法...

使用 berlin 10.1


    //---------------------------------------------------------------------------

#ifndef TControlAgentH
#define TControlAgentH
//---------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <System.TypInfo.hpp>
#include <vector>
#include <algorithm>

//---------------------------------------------------------------------------
class PACKAGE TControlAgent : public TComponent
{
private:
    std::vector<TControl*> FControls;
protected:
public:
  std::vector<UnicodeString> excludeControlNames;
    __fastcall TControlAgent(TComponent* Owner);
    TControl * __fastcall GetControl(TControl* ctrl, UnicodeString property);
    void __fastcall FindTControl(TForm *f, UnicodeString className);
  TControl* __fastcall SetControlProperty(UnicodeString property, UnicodeString className, bool state, bool exec, UnicodeString excludeControlName   );
__published:
};
//---------------------------------------------------------------------------
#endif


.cpp 文件的 .h 文件


    //---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "TControlAgent.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
//---------------------------------------------------------------------------
// component to act as agent for other components derived from TControl
//
//  Components have properties and events, is it possible to get all TControls into a vector
//  then be able to get a property of a component then fire an event or carry out an action
//  on the component!!!!
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TControlAgent *)
{
    new TControlAgent(NULL);
}
//---------------------------------------------------------------------------
__fastcall TControlAgent::TControlAgent(TComponent* Owner)
    : TComponent(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TForm *f, UnicodeString className)
    {
    FControls.clear();

    for(int i = 0; i < f->ControlCount; i++)
        {
        if(f->Controls[i]->ClassName() == className)  //control classes that to set as a group
            FControls.push_back(f->Controls[i]);
        }
    //note:  could have a function that appends other class names
    }
//---------------------------------------------------------------------------
TControl* __fastcall TControlAgent::SetControlProperty(UnicodeString property, UnicodeString className, bool state, bool exec, UnicodeString excludeControlName  )
    {
    PPropInfo propinfo;
    for(int i = 0; i < FControls.size(); i++)
        {
        if(FControls[i]->ClassName() == className)
            {
            propinfo = GetPropInfo(FControls[i], property);
            if (!propinfo)
                continue;
            if(exec && FControls[i]->Name != excludeControlName )
                {
                if(property == "Enabled")
                    FControls[i]->Enabled = state;
                }
            }

        }

    }
//---------------------------------------------------------------------------
namespace Tcontrolagent
{
    void __fastcall PACKAGE Register()
    {
        TComponentClass classes[1] = {__classid(TControlAgent)};
        RegisterComponents(L"SQLite", classes, 0);
    }
}
//---------------------------------------------------------------------------

My 2 cents worth..

I have done a proof of concept for your problem, would need a lot more work but I think it is doable and should do what you want.

I will do more work on it and post if there is interest.

To find all controls of a class type on a form

--- TControlAgent->FindTControl(this, "TButton");

I added 4 buttons on a form, added code bellow to button1 click event,

TControlAgent->SetControlProperty("Enabled", "TButton", false, true, "Button3");

in this case, want controls with Enabled property whose class name is TButton, state = true or false, execute the action but but exclude control named TButton3

There result was all TButtons on the form were set to disable except for button 3

(note: the exclude option would be a lookup list of controls to be excluded from any action or be able to set a state that is not the state eg Enabled = !true or !false )

In the click event of button3 I placed the following code;

TControlAgent->SetControlProperty("Enabled", "TButton", true, true, "");

The result of this is to re-enable all the controls, this is just an idea but with with the extra work it could be possible to execute any action on any control from a single parent form for any form in a collection of forms.

I also think it could be possible to fire events, just a crazy idea...

.h file using berlin 10.1


    //---------------------------------------------------------------------------

#ifndef TControlAgentH
#define TControlAgentH
//---------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <System.TypInfo.hpp>
#include <vector>
#include <algorithm>

//---------------------------------------------------------------------------
class PACKAGE TControlAgent : public TComponent
{
private:
    std::vector<TControl*> FControls;
protected:
public:
  std::vector<UnicodeString> excludeControlNames;
    __fastcall TControlAgent(TComponent* Owner);
    TControl * __fastcall GetControl(TControl* ctrl, UnicodeString property);
    void __fastcall FindTControl(TForm *f, UnicodeString className);
  TControl* __fastcall SetControlProperty(UnicodeString property, UnicodeString className, bool state, bool exec, UnicodeString excludeControlName   );
__published:
};
//---------------------------------------------------------------------------
#endif


.cpp file


    //---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "TControlAgent.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
//---------------------------------------------------------------------------
// component to act as agent for other components derived from TControl
//
//  Components have properties and events, is it possible to get all TControls into a vector
//  then be able to get a property of a component then fire an event or carry out an action
//  on the component!!!!
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TControlAgent *)
{
    new TControlAgent(NULL);
}
//---------------------------------------------------------------------------
__fastcall TControlAgent::TControlAgent(TComponent* Owner)
    : TComponent(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TForm *f, UnicodeString className)
    {
    FControls.clear();

    for(int i = 0; i < f->ControlCount; i++)
        {
        if(f->Controls[i]->ClassName() == className)  //control classes that to set as a group
            FControls.push_back(f->Controls[i]);
        }
    //note:  could have a function that appends other class names
    }
//---------------------------------------------------------------------------
TControl* __fastcall TControlAgent::SetControlProperty(UnicodeString property, UnicodeString className, bool state, bool exec, UnicodeString excludeControlName  )
    {
    PPropInfo propinfo;
    for(int i = 0; i < FControls.size(); i++)
        {
        if(FControls[i]->ClassName() == className)
            {
            propinfo = GetPropInfo(FControls[i], property);
            if (!propinfo)
                continue;
            if(exec && FControls[i]->Name != excludeControlName )
                {
                if(property == "Enabled")
                    FControls[i]->Enabled = state;
                }
            }

        }

    }
//---------------------------------------------------------------------------
namespace Tcontrolagent
{
    void __fastcall PACKAGE Register()
    {
        TComponentClass classes[1] = {__classid(TControlAgent)};
        RegisterComponents(L"SQLite", classes, 0);
    }
}
//---------------------------------------------------------------------------

我们只是彼此的过ke 2025-01-22 04:11:32

**** 已更新 *****
TControlAgent 的进度

显然仍在进行中,但此代码有效,创建一个带有 TPanel 的表单,向此添加 6 个 TButton

添加 TControl 代理,按照

TControlAgent 代码 下面的表单代码设置 OnButtonClick 事件
.h

//---------------------------------------------------------------------------

#ifndef TControlAgentH
#define TControlAgentH
//---------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <System.TypInfo.hpp>
#include <vector>
#include <algorithm>

class TControls;
class TControlGroup;

typedef void __fastcall (__closure *TControlAgentOnClick)(System::TObject *Sender, TControls *ctrl);
typedef void __fastcall (__closure *TButtonClickEvent)(System::TObject *Sender);
enum action {aEnabled, aOnClick, aChange};
enum tcontrols {tbutton, tedit, tcombo, tcheckbox};
//---------------------------------------------------------------------------
class PACKAGE TControlAgent : public TComponent
{
private:
    std::vector<TControls*> FControls;
    std::vector<TControlGroup*> FControlGroups;

    TControlAgentOnClick FClickSupliment;
    TButtonClickEvent FOnButtonClick;
    bool FButtonClickRedirect;

protected:

public:
    std::vector<UnicodeString> excludeControlNames;  // not implemented yet
    std::vector<TControlGroup*> __fastcall Groups();
    std::vector<TControls*> __fastcall Controls(int GroupIndex);
    __fastcall TControlAgent(TComponent* Owner);
    TControl * __fastcall GetControl(TControl* ctrl, UnicodeString property);
    void __fastcall FindTControl(TForm *f, UnicodeString className);
    void __fastcall FindTControl(TPanel *p, UnicodeString GroupName, bool ClearIfControlsExists);
    void __fastcall SetControlProperty(TControl *ctrl, bool state, int Action);
    int __fastcall GetGroup(String name);
    void __fastcall SetControlClickEvent(String ClassName, String GroupName, String ExcludeGroup, int tControlType);
    void __fastcall SetButtonPropValue(TButton* b, String Property, String Value, bool v);
    int __fastcall AddTControl(TControl* c, String Group);
    void __fastcall SetButtonPropValue(String Group, String ExcludeGroup,int TControlType,String Property,String GroupValue,bool GroupV,String excludeGroupValue,bool excludeGroupV);


__published:
    __property bool TButtonClick = {read = FButtonClickRedirect, write = FButtonClickRedirect };
    __property TControlAgentOnClick OnClickSuppliment={read=FClickSupliment, write=FClickSupliment};
    __property TButtonClickEvent OnButtonClick = {read = FOnButtonClick, write = FOnButtonClick };
};
//---------------------------------------------------------------------------
class TControlGroup
    {
    public:
        UnicodeString GroupName;
        std::vector<TControls*> GroupControls;
        __fastcall TControlGroup();
    };
//---------------------------------------------------------------------------
class TControls
    {
    public:
        TControl* ctrl;
        bool WantButtonOnClick;
        bool WantControlOnChange;
        bool FireStateChange;
        bool WantOnClickSupliment;
        bool state;
        __fastcall TControls();
    };

#endif

.cpp

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "TControlAgent.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
//---------------------------------------------------------------------------
// component to act as agent for other components derived from TControl
//
//  Components have properties and events, is it possible to get all TControls into a vector
//  then be able to get a property of a component then fire an event or carry out an action
//  on the component!!!!
//---------------------------------------------------------------------------
struct IsCtrlGroup {
    String _name;

    IsCtrlGroup(String name) : _name(name)
        {
        }

    bool operator()(const TControlGroup * item) const
        {
        return (item->GroupName == _name);
        }
};
//---------------------------------------------------------------------------
struct IsClassName {
    String _name;

    IsClassName(String name) : _name(name)
        {
        }

    bool operator()(const TControl * item) const
        {
        return (item->ClassName() == _name);
        }
};
//---------------------------------------------------------------------------
struct IsCtrl {
    TControl* _ctrl;

    IsCtrl(TControl* ctrl) : _ctrl(ctrl) {
    }

    bool operator()(const TControls * item) const {
        return (item->ctrl->Name == _ctrl->Name);
    }
};
//---------------------------------------------------------------------------

static inline void ValidCtrCheck(TControlAgent *)
{
    new TControlAgent(NULL);
}
//---------------------------------------------------------------------------
__fastcall TControlAgent::TControlAgent(TComponent* Owner)
    : TComponent(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TForm *f, UnicodeString className)
    {
    FControls.clear();
    TControls* ctrl;

    for(int i = 0; i < f->ControlCount; i++)
        {
        if(f->Controls[i]->ClassName() == className)  //control classes that to set as a group
            {
            TControls* ctrl = new TControls();
            ctrl->ctrl = f->Controls[i];
            ctrl->FireStateChange = false;
            ctrl->WantOnClickSupliment = false;
            FControls.push_back(ctrl);
            }
        }
        //note:  could have a function that appends other class names
    }
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TPanel *p, UnicodeString GroupName, bool ClearIfControlsExists)
    {
    /*
    group vector[]
        --> controlsindex  vector[index]

    */
    TControlGroup* g;
    TControls* ctrl;

    int i = -1;
    int group_index = -1, controls_index = -1;

    // check if group name exists in group vector
    group_index = GetGroup(GroupName);

    //clear controls vector if exists, controls will not exist if group does not exist...
    if(ClearIfControlsExists && group_index > 0)
        FControlGroups[group_index]->GroupControls.clear();

    // if group does not exist, push new group onto vector
    if(group_index == -1)
        {
        g = new TControlGroup();
        g->GroupName = GroupName;
        FControlGroups.push_back(g);
        group_index = GetGroup(GroupName);
        }

    //group must bnow exist
    for(i = 0; i < p->ControlCount; i++)
        {
        TControls* ctrl = new TControls();
        ctrl->ctrl = p->Controls[i];
        FControlGroups[group_index]->GroupControls.push_back(ctrl);
        controls_index = FControlGroups[group_index]->GroupControls.size() -1;
        FControlGroups[group_index]->GroupControls[controls_index]->ctrl = p->Controls[i];
        }
    }
//---------------------------------------------------------------------------
int __fastcall TControlAgent::AddTControl(TControl* c, String Group)
    {
    int  index;
    TControlGroup* g;

    int group_index = GetGroup(Group);
    if(group_index == -1)
        {
        g = new TControlGroup();
    g->GroupName = Group;
        FControlGroups.push_back(g);
        group_index = GetGroup(Group);
        }

    TControls* ctrl = new TControls();
    ctrl->ctrl = c;
    FControlGroups[group_index]->GroupControls.push_back(ctrl);
    index = FControlGroups[group_index]->GroupControls.size()-1;
    return(index);

    }
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetControlClickEvent(String ClassName, String GroupName, String ExcludeGroup, int tControlType)
    {
    int group_index = GetGroup(GroupName);

    for(int i = 0; i < FControlGroups[group_index]->GroupControls.size(); i++)
        {
        if(FControlGroups[group_index]->GroupControls[i]->ctrl->ClassName() == ClassName)
            {
            switch(tControlType)
                {
                case tbutton:
                    dynamic_cast<TButton*>(FControlGroups[group_index]->GroupControls[i]->ctrl)->OnClick = FOnButtonClick;
                    break;
                case tedit:
                    break;
                case tcombo:
                    break;
                case tcheckbox:
                    break;
                }
            }
        }
    }
//---------------------------------------------------------------------------
std::vector<TControlGroup*> __fastcall TControlAgent::Groups()
    {
    return(FControlGroups);
    }
//---------------------------------------------------------------------------
std::vector<TControls*> __fastcall TControlAgent::Controls(int GroupIndex)
    {
    return(FControlGroups[GroupIndex]->GroupControls);
    }
//---------------------------------------------------------------------------
int __fastcall TControlAgent::GetGroup(String name)
    {
    int group_index =-1;
    std::vector<TControlGroup*>::iterator found = std::find_if(FControlGroups.begin(), FControlGroups.end(), IsCtrlGroup(name));
    if(found != FControlGroups.end())
         group_index =  std::distance(FControlGroups.begin(), found);
    return(group_index);
    }
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetButtonPropValue(TButton* b, String Property, String Value, bool v)
    {
    PPropInfo propinfo;
    propinfo = GetPropInfo(b, Property);
    if (!propinfo)
        return;

    if(Value.IsEmpty())
        SetPropValue(b, propinfo, v);
    else
        SetPropValue(b, propinfo, Value);

    }
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetButtonPropValue(String Group,
                                                                                                    String ExcludeGroup,
                                                                                                    int TControlType,
                                                                                                    String Property,
                                                                                                    String GroupValue,
                                                                                                    bool GroupV,
                                                                                                    String excludeGroupValue,
                                                                                                    bool excludeGroupV)
    {
    // Group can hold all TControls on a form
    // ExcludeGroup contains TControls that will be excluded from an action on the Group controls
    // Group is an existing group of TControls found on a container
    // ExcludGroup is a group that can be found on a container or added to a Group
    //  then parsed to this method in ExcludeGroup param

    int i;
    PPropInfo propinfo;
    TControl *c;
    int group_index = GetGroup(Group);
    int exclude_Group_index = GetGroup(ExcludeGroup);
    TControl* ctrl;
    for(i = 0; i < FControlGroups[group_index]->GroupControls.size(); i++)
        {
        c = FControlGroups[group_index]->GroupControls[i]->ctrl;
        //check if TControl is to be excluded

        std::vector<TControls*>::iterator found = std::find_if(FControlGroups[exclude_Group_index]->GroupControls.begin(),
                                                                                                                             FControlGroups[exclude_Group_index]->GroupControls.end(),
                                                                                                                             IsCtrl(c));

        // if found, control is in the exclude list so continue, do not apply
        // property value change
        if(found != FControlGroups[exclude_Group_index]->GroupControls.end())
            {
            c = (*found)->ctrl;
            //set property value for exclude group controls
            propinfo = GetPropInfo(c, Property);
            if(propinfo)
                {
                if(excludeGroupValue.IsEmpty())
                    SetPropValue(c, propinfo, excludeGroupV);
                else
                    SetPropValue(c, propinfo, excludeGroupValue);
                }

            continue;
            }

        //if it gets here, c is not in exclude list
        propinfo = GetPropInfo(c, Property);
        if (!propinfo)
            return;


        if(GroupValue.IsEmpty())
            SetPropValue(c, propinfo, GroupV);
        else
            SetPropValue(c, propinfo, GroupValue);

        }

    }
//---------------------------------------------------------------------------
namespace Tcontrolagent
{
    void __fastcall PACKAGE Register()
    {
        TComponentClass classes[1] = {__classid(TControlAgent)};
        RegisterComponents(L"SQLite", classes, 0);
    }
}
//---------------------------------------------------------------------------
__fastcall TControls::TControls(){}
//---------------------------------------------------------------------------
__fastcall TControlGroup::TControlGroup(){}

表单代码

.cpp

表单有一个 TPanel,上面放置了 6 个 TButton

@运行时 TButton3 被禁用

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "frmTControlTest.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TControlAgent"
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
    : TForm(Owner)
    {
    int i;
    std::vector<TControls*> group_controls;
    //get ALL controls on a container
    ControlAgent1->FindTControl(p, "Group1", true);
    //create the exclude (for want of a better name) groups
    /*
    add
    edit
    save
    delete
    cancel
    exit
    */
    ControlAgent1->AddTControl(bnSave, "Group2");
    ControlAgent1->AddTControl(bnCancel, "Group2");

    ControlAgent1->AddTControl(bnAdd, "Group3");
    ControlAgent1->AddTControl(bnEdit, "Group3");
    ControlAgent1->AddTControl(bnDelete, "Group3");
    ControlAgent1->AddTControl(bnExit, "Group3");


    i = ControlAgent1->GetGroup("Group1");

    group_controls = ControlAgent1->Controls(i);

    ControlAgent1->SetControlClickEvent("TButton", "Group1", "", tbutton);

    }
//---------------------------------------------------------------------------
void __fastcall TForm3::ControlAgent1ButtonClick(TObject *Sender)
    {
    TButton* b;
    if((b = dynamic_cast<TButton*>(Sender)) == bnAdd )
        ControlAgent1->SetButtonPropValue("Group1", "Group2", tbutton, "Enabled", "", false, "", true);
    if((b = dynamic_cast<TButton*>(Sender)) == bnCancel )
        ControlAgent1->SetButtonPropValue("Group1", "Group3", tbutton, "Enabled", "", false, "", true);
    if((b = dynamic_cast<TButton*>(Sender)) == bnSave )
        {
        ControlAgent1->SetButtonPropValue("Group1", "Group3", tbutton, "Enabled", "", false, "", true);
    //Do Stuff
        }


    }
//---------------------------------------------------------------------------

**** UPDATED *****
Progress of TControlAgent

Obviously still work in progress but this code works, create a form with a TPanel, to this add 6 TButtons

Add a TControl Agent, set the OnButtonClick event as per Form code bellow

TControlAgent code
.h

//---------------------------------------------------------------------------

#ifndef TControlAgentH
#define TControlAgentH
//---------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <System.TypInfo.hpp>
#include <vector>
#include <algorithm>

class TControls;
class TControlGroup;

typedef void __fastcall (__closure *TControlAgentOnClick)(System::TObject *Sender, TControls *ctrl);
typedef void __fastcall (__closure *TButtonClickEvent)(System::TObject *Sender);
enum action {aEnabled, aOnClick, aChange};
enum tcontrols {tbutton, tedit, tcombo, tcheckbox};
//---------------------------------------------------------------------------
class PACKAGE TControlAgent : public TComponent
{
private:
    std::vector<TControls*> FControls;
    std::vector<TControlGroup*> FControlGroups;

    TControlAgentOnClick FClickSupliment;
    TButtonClickEvent FOnButtonClick;
    bool FButtonClickRedirect;

protected:

public:
    std::vector<UnicodeString> excludeControlNames;  // not implemented yet
    std::vector<TControlGroup*> __fastcall Groups();
    std::vector<TControls*> __fastcall Controls(int GroupIndex);
    __fastcall TControlAgent(TComponent* Owner);
    TControl * __fastcall GetControl(TControl* ctrl, UnicodeString property);
    void __fastcall FindTControl(TForm *f, UnicodeString className);
    void __fastcall FindTControl(TPanel *p, UnicodeString GroupName, bool ClearIfControlsExists);
    void __fastcall SetControlProperty(TControl *ctrl, bool state, int Action);
    int __fastcall GetGroup(String name);
    void __fastcall SetControlClickEvent(String ClassName, String GroupName, String ExcludeGroup, int tControlType);
    void __fastcall SetButtonPropValue(TButton* b, String Property, String Value, bool v);
    int __fastcall AddTControl(TControl* c, String Group);
    void __fastcall SetButtonPropValue(String Group, String ExcludeGroup,int TControlType,String Property,String GroupValue,bool GroupV,String excludeGroupValue,bool excludeGroupV);


__published:
    __property bool TButtonClick = {read = FButtonClickRedirect, write = FButtonClickRedirect };
    __property TControlAgentOnClick OnClickSuppliment={read=FClickSupliment, write=FClickSupliment};
    __property TButtonClickEvent OnButtonClick = {read = FOnButtonClick, write = FOnButtonClick };
};
//---------------------------------------------------------------------------
class TControlGroup
    {
    public:
        UnicodeString GroupName;
        std::vector<TControls*> GroupControls;
        __fastcall TControlGroup();
    };
//---------------------------------------------------------------------------
class TControls
    {
    public:
        TControl* ctrl;
        bool WantButtonOnClick;
        bool WantControlOnChange;
        bool FireStateChange;
        bool WantOnClickSupliment;
        bool state;
        __fastcall TControls();
    };

#endif

.cpp

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "TControlAgent.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
//---------------------------------------------------------------------------
// component to act as agent for other components derived from TControl
//
//  Components have properties and events, is it possible to get all TControls into a vector
//  then be able to get a property of a component then fire an event or carry out an action
//  on the component!!!!
//---------------------------------------------------------------------------
struct IsCtrlGroup {
    String _name;

    IsCtrlGroup(String name) : _name(name)
        {
        }

    bool operator()(const TControlGroup * item) const
        {
        return (item->GroupName == _name);
        }
};
//---------------------------------------------------------------------------
struct IsClassName {
    String _name;

    IsClassName(String name) : _name(name)
        {
        }

    bool operator()(const TControl * item) const
        {
        return (item->ClassName() == _name);
        }
};
//---------------------------------------------------------------------------
struct IsCtrl {
    TControl* _ctrl;

    IsCtrl(TControl* ctrl) : _ctrl(ctrl) {
    }

    bool operator()(const TControls * item) const {
        return (item->ctrl->Name == _ctrl->Name);
    }
};
//---------------------------------------------------------------------------

static inline void ValidCtrCheck(TControlAgent *)
{
    new TControlAgent(NULL);
}
//---------------------------------------------------------------------------
__fastcall TControlAgent::TControlAgent(TComponent* Owner)
    : TComponent(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TForm *f, UnicodeString className)
    {
    FControls.clear();
    TControls* ctrl;

    for(int i = 0; i < f->ControlCount; i++)
        {
        if(f->Controls[i]->ClassName() == className)  //control classes that to set as a group
            {
            TControls* ctrl = new TControls();
            ctrl->ctrl = f->Controls[i];
            ctrl->FireStateChange = false;
            ctrl->WantOnClickSupliment = false;
            FControls.push_back(ctrl);
            }
        }
        //note:  could have a function that appends other class names
    }
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TPanel *p, UnicodeString GroupName, bool ClearIfControlsExists)
    {
    /*
    group vector[]
        --> controlsindex  vector[index]

    */
    TControlGroup* g;
    TControls* ctrl;

    int i = -1;
    int group_index = -1, controls_index = -1;

    // check if group name exists in group vector
    group_index = GetGroup(GroupName);

    //clear controls vector if exists, controls will not exist if group does not exist...
    if(ClearIfControlsExists && group_index > 0)
        FControlGroups[group_index]->GroupControls.clear();

    // if group does not exist, push new group onto vector
    if(group_index == -1)
        {
        g = new TControlGroup();
        g->GroupName = GroupName;
        FControlGroups.push_back(g);
        group_index = GetGroup(GroupName);
        }

    //group must bnow exist
    for(i = 0; i < p->ControlCount; i++)
        {
        TControls* ctrl = new TControls();
        ctrl->ctrl = p->Controls[i];
        FControlGroups[group_index]->GroupControls.push_back(ctrl);
        controls_index = FControlGroups[group_index]->GroupControls.size() -1;
        FControlGroups[group_index]->GroupControls[controls_index]->ctrl = p->Controls[i];
        }
    }
//---------------------------------------------------------------------------
int __fastcall TControlAgent::AddTControl(TControl* c, String Group)
    {
    int  index;
    TControlGroup* g;

    int group_index = GetGroup(Group);
    if(group_index == -1)
        {
        g = new TControlGroup();
    g->GroupName = Group;
        FControlGroups.push_back(g);
        group_index = GetGroup(Group);
        }

    TControls* ctrl = new TControls();
    ctrl->ctrl = c;
    FControlGroups[group_index]->GroupControls.push_back(ctrl);
    index = FControlGroups[group_index]->GroupControls.size()-1;
    return(index);

    }
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetControlClickEvent(String ClassName, String GroupName, String ExcludeGroup, int tControlType)
    {
    int group_index = GetGroup(GroupName);

    for(int i = 0; i < FControlGroups[group_index]->GroupControls.size(); i++)
        {
        if(FControlGroups[group_index]->GroupControls[i]->ctrl->ClassName() == ClassName)
            {
            switch(tControlType)
                {
                case tbutton:
                    dynamic_cast<TButton*>(FControlGroups[group_index]->GroupControls[i]->ctrl)->OnClick = FOnButtonClick;
                    break;
                case tedit:
                    break;
                case tcombo:
                    break;
                case tcheckbox:
                    break;
                }
            }
        }
    }
//---------------------------------------------------------------------------
std::vector<TControlGroup*> __fastcall TControlAgent::Groups()
    {
    return(FControlGroups);
    }
//---------------------------------------------------------------------------
std::vector<TControls*> __fastcall TControlAgent::Controls(int GroupIndex)
    {
    return(FControlGroups[GroupIndex]->GroupControls);
    }
//---------------------------------------------------------------------------
int __fastcall TControlAgent::GetGroup(String name)
    {
    int group_index =-1;
    std::vector<TControlGroup*>::iterator found = std::find_if(FControlGroups.begin(), FControlGroups.end(), IsCtrlGroup(name));
    if(found != FControlGroups.end())
         group_index =  std::distance(FControlGroups.begin(), found);
    return(group_index);
    }
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetButtonPropValue(TButton* b, String Property, String Value, bool v)
    {
    PPropInfo propinfo;
    propinfo = GetPropInfo(b, Property);
    if (!propinfo)
        return;

    if(Value.IsEmpty())
        SetPropValue(b, propinfo, v);
    else
        SetPropValue(b, propinfo, Value);

    }
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetButtonPropValue(String Group,
                                                                                                    String ExcludeGroup,
                                                                                                    int TControlType,
                                                                                                    String Property,
                                                                                                    String GroupValue,
                                                                                                    bool GroupV,
                                                                                                    String excludeGroupValue,
                                                                                                    bool excludeGroupV)
    {
    // Group can hold all TControls on a form
    // ExcludeGroup contains TControls that will be excluded from an action on the Group controls
    // Group is an existing group of TControls found on a container
    // ExcludGroup is a group that can be found on a container or added to a Group
    //  then parsed to this method in ExcludeGroup param

    int i;
    PPropInfo propinfo;
    TControl *c;
    int group_index = GetGroup(Group);
    int exclude_Group_index = GetGroup(ExcludeGroup);
    TControl* ctrl;
    for(i = 0; i < FControlGroups[group_index]->GroupControls.size(); i++)
        {
        c = FControlGroups[group_index]->GroupControls[i]->ctrl;
        //check if TControl is to be excluded

        std::vector<TControls*>::iterator found = std::find_if(FControlGroups[exclude_Group_index]->GroupControls.begin(),
                                                                                                                             FControlGroups[exclude_Group_index]->GroupControls.end(),
                                                                                                                             IsCtrl(c));

        // if found, control is in the exclude list so continue, do not apply
        // property value change
        if(found != FControlGroups[exclude_Group_index]->GroupControls.end())
            {
            c = (*found)->ctrl;
            //set property value for exclude group controls
            propinfo = GetPropInfo(c, Property);
            if(propinfo)
                {
                if(excludeGroupValue.IsEmpty())
                    SetPropValue(c, propinfo, excludeGroupV);
                else
                    SetPropValue(c, propinfo, excludeGroupValue);
                }

            continue;
            }

        //if it gets here, c is not in exclude list
        propinfo = GetPropInfo(c, Property);
        if (!propinfo)
            return;


        if(GroupValue.IsEmpty())
            SetPropValue(c, propinfo, GroupV);
        else
            SetPropValue(c, propinfo, GroupValue);

        }

    }
//---------------------------------------------------------------------------
namespace Tcontrolagent
{
    void __fastcall PACKAGE Register()
    {
        TComponentClass classes[1] = {__classid(TControlAgent)};
        RegisterComponents(L"SQLite", classes, 0);
    }
}
//---------------------------------------------------------------------------
__fastcall TControls::TControls(){}
//---------------------------------------------------------------------------
__fastcall TControlGroup::TControlGroup(){}

Form Code

.cpp

Form has a TPanel with 6 TButtons placed on it

@run time TButton3 is disabled

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "frmTControlTest.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TControlAgent"
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
    : TForm(Owner)
    {
    int i;
    std::vector<TControls*> group_controls;
    //get ALL controls on a container
    ControlAgent1->FindTControl(p, "Group1", true);
    //create the exclude (for want of a better name) groups
    /*
    add
    edit
    save
    delete
    cancel
    exit
    */
    ControlAgent1->AddTControl(bnSave, "Group2");
    ControlAgent1->AddTControl(bnCancel, "Group2");

    ControlAgent1->AddTControl(bnAdd, "Group3");
    ControlAgent1->AddTControl(bnEdit, "Group3");
    ControlAgent1->AddTControl(bnDelete, "Group3");
    ControlAgent1->AddTControl(bnExit, "Group3");


    i = ControlAgent1->GetGroup("Group1");

    group_controls = ControlAgent1->Controls(i);

    ControlAgent1->SetControlClickEvent("TButton", "Group1", "", tbutton);

    }
//---------------------------------------------------------------------------
void __fastcall TForm3::ControlAgent1ButtonClick(TObject *Sender)
    {
    TButton* b;
    if((b = dynamic_cast<TButton*>(Sender)) == bnAdd )
        ControlAgent1->SetButtonPropValue("Group1", "Group2", tbutton, "Enabled", "", false, "", true);
    if((b = dynamic_cast<TButton*>(Sender)) == bnCancel )
        ControlAgent1->SetButtonPropValue("Group1", "Group3", tbutton, "Enabled", "", false, "", true);
    if((b = dynamic_cast<TButton*>(Sender)) == bnSave )
        {
        ControlAgent1->SetButtonPropValue("Group1", "Group3", tbutton, "Enabled", "", false, "", true);
    //Do Stuff
        }


    }
//---------------------------------------------------------------------------

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文