简体   繁体   English

Delphi7,创建许多具有相同属性的控件

[英]Delphi7, Create many controls with same properties

I am new to Delphi. 我是Delphi的新手。

I would like to make an application in which will create a number of Buttons. 我想制作一个将在其中创建多个按钮的应用程序。 Declaring an array of Tbuttons and create the buttons 1 by 1 is not very satisfying, because it is confusing and takes a lot of time. 声明一个Tbuttons数组并按1逐个创建按钮不是很令人满意,因为这很混乱并且需要很多时间。 Using the Command For is also unsatisfying, because i won't be able to change some of button's properties, if needed, for example their position. 使用Command For也不令人满意,因为如果需要,我将无法更改按钮的某些属性,例如其位置。

So i decided to declare a procedure in TForm1 Class, which creates the buttons based on what properties I send to the procedure. 因此,我决定在TForm1类中声明一个过程,该过程根据我向该过程发送的属性创建按钮。 But for some reason it is not working (There aren't any syntax Errors): 但是由于某种原因,它不起作用(没有任何语法错误):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)                       //Declaring the procedure
  procedure CreateButton(Button: TButton; L: Integer; T: Integer); 
  procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  B1, B2: TForm1;         //Declaring controls
implementation

{$R *.dfm}

procedure TForm1.CreateButton(Button: TButton; L: Integer; T: Integer);
begin
  Button:= TButton.Create(Self);
  Button.Parent:= Self;
  Button.Width:= 100; Button.Height:= 50;
  Button.Left:= L; Button.Top:= T;
end;


procedure TForm1.FormCreate(Sender: TObject);
Var
  Button1, Button2: TButton;
begin
  B1.CreateButton(Button1, 100, 50);           //Sending properties
  B2.CreateButton(Button2, 200, 40);           //Sending properties
end;

end.

AS: during the communication with topic starters answer grown too. AS:在与主题交流的过程中,答案也越来越多。 The total outcome is like http://pastebin.ca/2426760 总结果就像http://pastebin.ca/2426760

 procedure TForm1.CreateButton(VAR Button: TButton; CONST L: Integer; CONST T: Integer);

That is of basics of Pascal language how to pass parameters to procedures/functions. 这是Pascal语言的基础,如何将参数传递给过程/函数。

http://docwiki.embarcadero.com/RADStudio/XE4/en/Parameters_(Delphi) http://docwiki.embarcadero.com/RADStudio/XE4/en/Parameters_(Delphi)

Actually, I don't think there is any problem with the parameters 实际上,我认为参数没有任何问题
Button = nil, which means the values of "Button1" and "Button2" are not sent, however Button = nil,这意味着不会发送“ Button1”和“ Button2”的值

http://pastebin.ca/2427238 http://pastebin.ca/2427238


Kudoes to Bill for spotting this. 比尔(Bill)很荣幸发现这一点。 Using separate properties to position your controls is both inefficient and prone to copy-paste errors. 使用单独的属性放置控件的效率低下,并且容易出现复制粘贴错误。

Using the 2nd link: 使用第二个链接:

procedure TForm1.CreateButton(out Button: TButton; const L: Integer; const T: Integer);
begin
  Button:= TButton.Create(Self);
  Button.Parent:= Self;
  Button.SetBounds( L, T, 100, 50); 
end;

Actually what do you do with pointers to newly created buttons ? 实际上,您如何使用指向新创建的按钮的指针? In your code you just loose them! 在您的代码中,您只需松开它们!

procedure TForm1.FormCreate(Sender: TObject);
Var
  Button1, Button2: TButton;
begin
...
end;

In this your code those pointers would be just lost! 在您的代码中,这些指针将丢失! If you do need those values - pass them outside of the procedure. 如果确实需要这些值,请在过程之外传递它们。 If you do not - do not ask for them - http://en.wikipedia.org/wiki/YAGNI http://en.wikipedia.org/wiki/KISS_principle 如果您不这样做-请勿提出要求-http: //en.wikipedia.org/wiki/YAGNI http://en.wikipedia.org/wiki/KISS_principle

Procedure TForm1.CreateButton(const L, T: Integer);
begin
  With TButton.Create(Self) do begin
       Parent := Self;
       SetBounds( L, T, 100, 50); 
       Caption := 'Caption at ' + IntToStr(T);
       Name := 'Name at ' + IntToStr(L);
  End; 
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  B1.CreateButton( 100, 50);           //Sending properties
  B2.CreateButton( 200, 40);           //Sending properties
end;

Now to those B1, B2... 现在对那些B1,B2 ...

You claim that you want 2 buttons on the form, but you code shows you try to make THREE FORMS and one button on the 2nd form and one button on the 3rd form. 您声称希望在表单上有2个按钮,但是代码显示您尝试制作三个表单,在第2个表单上创建了一个按钮,在第3个表单上创建了一个按钮。 So what do you really want ??? 那么你到底想要什么? And do you check that B1 and B2 forms were created befoe tryign to add buttons to them ? 并且您是否在尝试为按钮添加B1和B2表单之后创建了表单?

Perhaps you really wanted 也许你真的想要

procedure TForm1.FormCreate(Sender: TObject);
begin
  SELF.CreateButton( 100, 50);           //Sending properties
  SELF.CreateButton( 200, 40);           //Sending properties
end;

Then to go with DRY principle and to keep all the variables in one place. 然后遵循DRY原理,并将所有变量都放在一个位置。

http://docwiki.embarcadero.com/Libraries/XE2/en/System.Types.TPoint http://docwiki.embarcadero.com/Libraries/XE2/zh/System.Types.TPoint

Procedure TForm1.CreateButtons(const a: array of TPoint);
Var p: TPoint;
Begin
    for p in a do
        CreateButton( p.x, p.y );
End;

type TPointDynArray = array of TPoint;

procedure TForm1.FormCreate(Sender: TObject);
begin
   CreateButtons( TPointDynArray.Create(
       Point( 100,50 ), Point(200, 40) ) );
end;

Kudos to Delphi array initialization Delphi数组初始化致敬

Later you can always add more coordinates to an array and keep it consistent. 以后,您总是可以向数组添加更多坐标并保持一致。 Well, to bring down this to Delphi 7 abilities that would - somewhat redundantly - be coded like 好吧,将其归结为Delphi 7的一些功能,这些功能可能有点冗余

const BtnCnt = 2;
      BtnLocations : array [1..BtnCnt] of TSize = (
         ( cx: 100, cy: 50 ), ( cx: 200, cy: 40 ) 
      );

Procedure TForm1.CreateButtons(const a: array of TSize);
Var i: integer;
Begin
    for i := Low(a) to High(a) do
        with a[i] do
             CreateButton( cx, cy );
End;

procedure TForm1.FormCreate(Sender: TObject);
begin
   CreateButtons( BtnLocations );
end;

But while Delphi 5 and Dephi 7 were great releases, they are very outdated. 但是,尽管Delphi 5和Dephi 7是不错的版本,但它们已经过时了。 I definitely suggest you either upgradeing to Delphi XE or more recent, or side-stepping to CodeTyphon 我绝对建议您要么升级到Delphi XE或更新版本,要么回避到CodeTyphon


TForm1 = class(TForm)                       //Declaring the procedure
    procedure CreateButton(Button: TButton; L: Integer; T: Integer); 

Declaring that one-purpose procedure in PUBLISHED section of the form class is also not a very good style. 在form类的PUBLISHED部分中声明一个目的过程也不是一个很好的样式。 You'd better declare them in PRIVATE section. 您最好在PRIVATE部分中声明它们。 Adhering to "least visibility" would help you to make interdependencies controllable. 坚持“最少可见性”将帮助您使相互依赖性可控。 Otherwise in a year your program would become a spaghetti mess, where you just cannot change anything without ruining everything else. 否则,一年之内,您的程序将变成一团意大利面条,您无法在不破坏其他所有内容的情况下进行任何更改。 I am workign on a project with 10+ years of history now and i see the consequences of "everything is public" very clear. 我现在正在从事一个拥有10多年历史的项目,并且我很清楚地看到“一切都是公共的”的后果。 It is a great pain! 真是太痛苦了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM