【问题标题】:C++: How do I make a VCL component reference itself?C++:如何使 VCL 组件引用本身?
【发布时间】:2019-03-17 03:07:00
【问题描述】:

我在 RAD Studio 10.2 中使用 C++ Builder。我不确定我是否在标题中正确地问了这个问题,但我想说的是,每当我使用 C++ 关键字“this”时,它都会引用我试图访问的组件的父级,但是而不是组件本身。

例如,下面的代码改变了Form的颜色和字体颜色,而不是Panel的颜色和字体颜色:

void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
    this->Color = cl3DLight;
    this->Font->Color = clMaroon;
}

此外,如果我执行与上述相同的操作但省略关键字“this”,它仍会更改表单的属性而不是面板的属性(参见下面的代码)。

void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
    Color = cl3DLight;
    Font->Color = clMaroon;
}

我该如何编写代码以便它访问面板的“颜色”和“字体->颜色”而不是表单?谢谢。

注意:我之所以不这样做是因为:Panel1->Color = "cl3DLight"; 是因为我试图为运行时创建的组件找到一种方法。 p>

【问题讨论】:

  • 您的表单有面板吗?如果是,声明是什么(实例名称是什么)?
  • 是的。 TPanel *Panel1; 是声明,“Panel1”是组件的名称。
  • 你试过了吗:Panel1->Color = /*...*/;?
  • 是的,抱歉,我一定没有在原帖中澄清这一点。我正在尝试为在运行时创建的组件找到一种方法,因此我不能使用组件的实例名称。

标签: c++builder vcl


【解决方案1】:

Sender 参数表示生成事件的组件。您可以将该指针类型转换为正确的类型,以便访问该组件的属性。

如果您确定附加到事件的所有内容都是TPanel,则可以直接对其进行类型转换(正如 Remy 在下面的 cmets 中指出的那样):

void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
    TPanel *panel = static_cast<TPanel *>(Sender);
    panel->Color = cl3DLight;
    panel->Font->Color = clMaroon;
}

如果您对不同的控件类型使用相同的事件处理程序,则可以改为测试适当的类型:

void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
    TPanel *panel = dynamic_cast<TPanel *>(Sender);
    if (panel) 
    {
      panel->Color = cl3DLight;
      panel->Font->Color = clMaroon;
    }
}

【讨论】:

  • 效果很好!谢谢。我发现即使是普通演员也可以,所以因为我已经声明了TPanel *panel;,所以这是我的代码:panel = (TPanel *) Sender;
  • 只有在您可以 100% 确定事件仅分配给 TPanel 时才有效。使用dynamic_cast 可以保护您,以防万一。现在你已经获得了两者的信息。 :-)
  • @awesomedisplayname 你应该使用static_cast而不是C风格的演员:panel = static_cast&lt;TPanel *&gt;(Sender);当你知道类型时使用static_cast,当你需要发现类型时使用dynamic_cast
  • 另一方面,Sender 通常仅在您将相同的事件处理程序分配给 多个 控件时使用。如果事件处理程序仅分配给单个控件,则可以直接引用该控件,例如:void __fastcall TForm1::Panel1MouseEnter(TObject *Sender) { Panel1-&gt;Color = cl3DLight; Panel1-&gt;Font-&gt;Color = clMaroon; }
  • @KenWhite 谢谢,我之前没有看到那个注释。无论哪种方式,我仍然建议不要在这个特定示例中使用 dynamic_cast,因为应用程序知道它正在创建 TPanel 对象,因此无需将运行时开销浪费在它可以在编译时执行的操作上。跨度>
猜你喜欢
  • 2018-02-08
  • 2012-05-12
  • 2021-11-08
  • 2013-04-11
  • 1970-01-01
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 2011-09-15
相关资源
最近更新 更多