0

具体问题

如何在 Borland C++ Builder 上创建一组按钮并使用它?

我正在使用 Borland C++ Builder 6 和 Borland Developer Studio 2006 (Turbo C++ 2006)。

目的

使用带有索引的 for 循环来处理表单上的许多按钮,例如,更改它们的标题、大小和位置。

我知道如果Button1我创建了另一个按钮(通过TButton *Button2 = new TButton(Form1)),我是否有一个名为的按钮,并且在该按钮的单击事件中,我可以分配Button1Button2Button2 = Button1),我可以简单地修改Button1with的标题Button2->Caption。所以我想扩展它,将真实组件的指针分配给数组的元素,让它们通过for循环与所有这些元素一起工作。

好吧,如果有人找到一种将所有按钮作为数组添加到表单上的方法,那就更好了:)

尝试

在 TForm1::Button1Click() 上进行了以下测试,这是表单上按钮的事件:

  • 测试 1

    • 说明:直接创建数组
    • 代码:

      TButton Buttons[3];
      
    • 结果:编译错误:

      > [C++ Error] Unit1.cpp(23): E2248 Cannot find default constructor
      > to initialize array element of type 'TButton'
      
    • 注释:
      • 我测试了这个测试的一些变体(例如TButton Buttons = new TButton[3],使用calloc函数和其他变体),但它们都指向TButton没有没有参数的构造函数的问题,即TButton(),,但只有TButton (TComponent *AOwner)TButton(void *ParentWindow)TButton(const TButton &);
      • 有什么方法可以将运算符new与构造函数原型的参数一起用于TButton数组?
  • 测试 2

    • 描述:创建向量
    • 代码:还要添加#include "vector.h"单元标题...

      vector<TButton> Buttons;
      Buttons[0].Caption="it is ok";
      Buttons[1].Caption="mayday, mayday";
      
    • 结果:第 3 行的调试器异常:

      > Project Project1.exe raised exception class EAccessViolation
      > with message 'Acceess violation at address 401075B9 in module
      > 'vcl60.bpl'. Read of address 00000254'. Proccess stopped. Use
      > Step or Run to continue.
      
    • 注释:
      • 是的,我预计它会被提出,但我把它放在这里给某人说如何在创建后为该向量上的更多元素分配内存,因为由于vector<TButton> Buttons(3);相同的原因 test1 失败:(

一般问题

如何为任何视觉组件做到这一点?

4

3 回答 3

3

由于相同的原因,您的所有尝试都失败了 - 您正在尝试创建实际TButton对象实例的数组/向量,而不是指向实例的指针的数组/向量TButton

创建一个固定长度的按钮指针数组:

TButton* Buttons[3];
...
Buttons[0] = Button1;
Buttons[1] = Button2;
Buttons[2] = Button3;
...
for(index = 0; index < 3; ++index)
{
    TButton *Btn = Buttons[index];
    // use Btn as needed...
}

要创建按钮指针的动态长度数组:

TButton** Buttons;
...
Buttons = new TButton*[3];
Buttons[0] = Button1;
Buttons[1] = Button2;
Buttons[2] = Button3;
...
for(index = 0; index < 3; ++index)
{
    TButton *Btn = Buttons[index];
    // use Btn as needed...
}
...
delete[] Buttons;

要创建按钮指针向量:

std::vector<TButton*> Buttons;
...
Buttons.push_back(Button1);
Buttons.push_back(Button2);
Buttons.push_back(Button3);
...
for(index = 0; index < 3; ++index)
{
    TButton *Btn = Buttons[index];
    // use Btn as needed...
}
/*
Or:
for(std::vector<TButton*>::iterator iter = Buttons.begin(); iter != Buttons.end(); ++iter)
{
    TButton *Btn = *iter;
    // use Btn as needed...
}
*/
于 2012-09-10T20:43:28.387 回答
1

所有这一切都非常好,而且是正确的。但我的意思是用户的问题是其他意图。如果对于我们得到的所有按钮,每个索引都没有特别的好处——这只是一种真正的方法:目的是通过单击来控制所有组件(按钮、面板、形状等......)并且不要为每个索引一个新代码,这就是为什么我更改了一些程序的代码:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

typedef TPanel* TPanels;

TPanels Panels[3] = {Panel1, Panel2, Panel3};

int count;

for(count=0;count<3;count++)

Panels[count]->Left=random(100);

}  

正如人们所看到的,而不是index这里count。当然不要忘记插入randomize()TForm1

于 2018-06-30T18:12:47.533 回答
0

神奇的 Typedef + 伪数组 = 解决方案

  • 神奇的字体定义:

    • 经过几个小时的搜索,我typedef在 Stack Overflow 和 Google 搜索之旅中看到了一个,并想为什么不这样做:

      typedef TButton* TButtons;
      
    • 好吧,它改变了所有事情,因为我可以执行:

      TButtons Buttons[3];
      
  • 伪数组:

    • 问题仍然是如何为存储在该Buttons[3]数组上的数据分配内存,但是根据我问题的目的部分的第二段的知识,我想:忘记新数据,数据在那里,指向那里(所以我称之为构建一个伪数组,因为我只创建一个指向现有数据的指针数组):

      TButtons Buttons[3] = {Button1, Button2, Button3};
      
    • Button1当我将它们正常放在表单上时(通过我的鼠标) ,WhereButton2Button3已经创建了。

工作示例

  1. 创建一个新的 vcl/forms 应用程序项目;
  2. 将左侧的 3 个按钮( 、 、 )放在下图(Button1Button2Button3)上以演示该解决方案,并将 1 个大按钮(Button4)也作为下图来执行操作; 下图点2
  3. 在第四个按钮的单击事件上插入以下代码,即大按钮 ( Button4);

    typedef TButton* TButtons;
    TButtons Buttons[3] = {Button1, Button2, Button3};
    int index;
    
    for(index=0;index<3;index++)
    {
            Buttons[index]->Caption=(AnsiString)"teste "+index+" - "+(1+random(100));
            Buttons[index]->Left=25+4*random(100);
            Buttons[index]->Top=25+4*random(100);
    }
    
  4. 执行“沙赞!” 一边跑一边玩…… 像一个游戏项目
于 2012-09-07T23:38:39.940 回答