控制指针

时间:2018-12-16 08:09:32

标签: delphi

我想创建所有列表框的数组并访问它们。我尝试使用指针来完成此操作,但是我的程序在运行时崩溃,并且地址访问错误……

type ControlsCount = 4;
type PLB = ^TListBox;

var listBoxes: array of PLB;

procedure TExport.FormCreate(Sender: TObject);
var i: word; n: integer;
begin
  with FormExport do
  begin
    ListRowHeight := List_sex.height;
    List_sex.items.add('---');
    List_sex.items.add('Man');
    List_sex.items.add('Woman');
    List_sex.onmousemove:=ListMouseMove;

    setLength(listBoxes, ControlsCount);
    n := -1;
    for i := 0 to ControlsCount - 1 do
        if Components[i] is TWinControl then
          if TWinControl(Components[i]).CanFocus then
            begin
            inc(n);
            // mistake here: should be listBoxes[n] not listBoxes[i]
            listBoxes[i] := PLB(Components[i]);
            end;
    realControlsCount := n;
  end;
end;

procedure TExport.resetListBoxes;
var i: word;
begin
 for i := 0 to realControlsCount-1 do
  begin
    TListBox(listBoxes[i]^).height := ListRowHeight;
  end;
end;

所以在这里,我尝试将控件的指针设置为listBoxes [i]。

listBoxes[i] := PLB(Components[i]);

在这里我尝试访问它:

TListBox(listBoxes[i]^).height := ListRowHeight;

这是产生错误的行。

我在做什么错了?

2 个答案:

答案 0 :(得分:3)

只需删除所有指针内容,然后检查控件是否真的为TListBox。另外,您在访问另一个列表ControlsCount

时滥用了Components[i]
 var listBoxes: array of TListBox;
 ...
for i := 0 to ControlsCount - 1 do
  if Controls[i] is TListBox then  //note strict constraint
     listBoxes[n] := Controls[i] as TListBox;
 ...
  listBoxes[i].height := ListRowHeight;

Aslso考虑使用TList<TListBox>而不是数组

答案 1 :(得分:1)

关于答案MBo,这就是我将其与TList一起使用的方式

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, Generics.Collections,
  FMX.Layouts, FMX.ListBox, FMX.Controls.Presentation, FMX.StdCtrls;

type
  TForm1 = class(TForm)
    lst1: TListBox;
    lst2: TListBox;
    lst3: TListBox;
    btn1: TButton;
    pnl1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  listboxes: TList<TListBox>; // Define list that will contain listboxes

implementation

{$R *.fmx}

procedure TForm1.btn1Click(Sender: TObject);
var
  lstbx: TListBox;
begin
  for lstbx in listboxes do
    ShowMessage(lstbx.Height.ToString); Loop through all listboxes and show their height
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  control: TControl;
begin
  listboxes := TList<TListBox>.Create; // Create the TList

  for control in pnl1.Controls do
  begin
    if control is TListBox then
      listboxes.Add(control as TListBox); // Loop through all listboxes on a panel and add then to the list if they are a listbox
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  listboxes.Free; // Free the list
end;

end.