【问题标题】:Delphi7, Create many controls with same propertiesDelphi7,创建许多具有相同属性的控件
【发布时间】:2013-07-13 21:11:56
【问题描述】:

我是德尔福的新手。

我想创建一个应用程序,在其中创建多个按钮。声明一个 Tbuttons 数组并一个一个地创建按钮并不是很令人满意,因为它令人困惑并且需要很多时间。使用 Command For 也不令人满意,因为如果需要,我将无法更改某些按钮的属性,例如它们的位置。

所以我决定在 TForm1 类中声明一个过程,它根据我发送给该过程的属性创建按钮。但由于某种原因它不起作用(没有任何语法错误):

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.

【问题讨论】:

  • “不工作”是什么意思???什么时候 ?其中有哪些错误?她没有人能跳进你的脑袋里,用你的眼睛看。请阅读catb.org/~esr/faqs/smart-questions.html
  • CreateButton 中有两个 Button.Height... 将第二个更改为 Button.Top := T;
  • 对不起,我的意思是按钮 1,2 没有创建
  • 您如何确定它们不是创建的,而不是创建在错误的位置、错误的所有者或创建的不可见?作为一名程序员,你应该对声明和事实非常敏锐和确定。否则,您的程序将做任何事情,而不是用户要求的事情。 “我看不到屏幕上的按钮”和“未创建按钮”之间有很多英里
  • 你看到代码中的任何地方(Button.hide)了吗?不,因此它们的可见自动变为 TRUE,因此它们不是不可见的。另外,我以特定坐标发送按钮。 Button1.top = 100, Button1.Left = 50 and Button2.top = 200, Button2.Left = 40 即使参数没有传入 "CreateButton" 按钮也会自动创建在 (Top, Left = 0, 其中他们没有)

标签: delphi class properties controls delphi-7


【解决方案1】:

AS:在与话题发起者的交流过程中,答案也增长了。总的结果就像http://pastebin.ca/2426760

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

这是 Pascal 语言的基础知识,如何将参数传递给过程/函数。

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

其实我觉得参数没有问题
Button = nil,表示不发送“Button1”和“Button2”的值

http://pastebin.ca/2427238


感谢 Bill 发现这一点。使用单独的属性来定位控件既低效又容易出现复制粘贴错误。

使用第二个链接:

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;

实际上,您如何处理指向新创建按钮的指针? 在您的代码中,您只需松开它们!

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

在您的代码中,这些指针将丢失!如果您确实需要这些值 - 将它们传递到过程之外。如果你不这样做 - 不要要求他们 - 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;

现在到那些 B1、B2...

您声称要在表单上设置 2 个按钮,但您的代码显示您尝试在第 2 个表单上创建三个表单和一个按钮,在第 3 个表单上创建一个按钮。那你真正想要什么???您是否检查过 B1 和 B2 表单是在尝试向它们添加按钮之前创建的?

也许你真的想要

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

然后遵循 DRY 原则并将所有变量保存在一个位置。

http://docwiki.embarcadero.com/Libraries/XE2/en/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;

Delphi array initialization致敬

以后您可以随时向数组添加更多坐标并使其保持一致。 好吧,把这归结为 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;

虽然 Delphi 5 和 Dephi 7 是很棒的版本,但它们已经过时了。我绝对建议您升级到 Delphi XE 或更新版本,或者转而使用 CodeTyphon


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

在表单类的 PUBLISHED 部分声明单一用途的过程也不是一种很好的风格。你最好在 PRIVATE 部分声明它们。坚持“最小可见性”将帮助您使相互依赖关系可控。否则一年后你的程序就会变得一团糟,你不能改变任何东西而不破坏其他一切。我现在正在从事一个有 10 多年历史的项目,我非常清楚地看到“一切都是公开的”的后果。这是一个巨大的痛苦!

【讨论】:

  • 其实我觉得参数没有问题。
  • @NikolaidisDimitris 那么您打算向CreateButton 声明第一个参数是什么? Button 参数从FormCreate 传递到CreateButton 的值是什么?后者是如何使用它的?
  • B1 和 B2 是 2 个按钮。 OnFormCreate 过程发送这两个按钮的参数。 B1 Button's Name = Button1, left = 100, top = 50. 所以 CreateButton 的变量 "Button, L, T" 取值: Button:= Button, T:= 50 = Button.Top; L:= 100 = Button.Left
  • var B1, B2: TForm1; - B1 和 B2 是表格。按钮确实有类型TButton,而不是TForm。而且这些按钮既没有名称也没有标题(您知道区别,不是吗?)因为编译后不再有“Button1”或“B2”,而只有无名的内存地址。如果您需要这些按钮具有名称或标题 - 您应该制作字符串表达式并分配这些属性。
  • 上面是CreateButtonCreateButtonsFormCreate 的固定代码 - 尝试一下,尝试了解它们的区别。
猜你喜欢
  • 2015-05-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多