我可以使用为具有单击事件的组件创建的变量吗?

问题描述 投票:0回答:1

我有 56 个面板,我创建了一个循环穿过它们,选择一个随机面板。选择随机面板后,我将

FindComponent()
与随机面板的名称一起使用,并为随机面板分配一个变量。现在我将随机面板作为变量,我想做的是将
OnClick
事件与变量一起使用,但我在使用它时遇到了麻烦。我想在单击该面板后显示
ShowMessage()

procedure TForm1.btnStartClick(Sender: TObject);
var
  iRandomNum, iCharRandom, iCnt: integer;
  cChar: char;
  sPanelName: string;

begin
 
  Randomize;
  iRandomNum := Random(7 - 1 + 1) + 1;
  iCharRandom := Random(8 - 1 + 1) + 1;
  case iCharRandom of
    1: cChar := 'A';
    2:
      cChar := 'B';
    3:
      cChar := 'C';
    4:
      cChar := 'D';
    5:
      cChar := 'E';
    6:
      cChar := 'F';
    7:
      cChar := 'G';
    8:
      cChar := 'H';
  end;
  sPanelName := 'pnl' + cChar + IntToStr(iRandomNum);
  for iCnt := 1 to 56 do
  begin
    pnlCorrect := FindComponent(sPanelName) as TPanel;
  end;
  pnlCorrect.OnClick := showmessage('Correct panel');
end;

我尝试仅显示带有变量的

ShowMessage()
事件的
OnClick
,但它不起作用。我不断收到运行时错误。


编辑:

我的新代码添加在下面...

 procedure btnTest1Click(Sender: TObject);

  private

  procedure pnlCorrectClick(Sender: TObject);
  procedure pnlWrongClick(Sender: TObject);
{ Private declarations }
  public
    { Public declarations }
  end;

...

procedure TForm1.btnTest1Click(Sender: TObject);
var
  i, j: Integer;

  function FindPanel(iChar, iNum: Integer): TPanel;
  var
    cChar: Char;
    sPanelName: string;
  begin
    cChar := Char(Ord('A') + iChar);
    sPanelName := 'pnl' + cChar + IntToStr(iNum);
    Result := FindComponent(sPanelName) as TPanel;
    redGameTest.Lines.Add(sPanelName);
  end;

begin
  // reset the OnClick events of the panels first...
  for i := 0 to 6 do
  begin
    for j := 1 to 8 do
      FindPanel(i, j).OnClick := pnlWrongClick;
  end;

  // now, pick a random panel and assign its OnClick event...
  FindPanel(Random(8), Random(7) + 1).OnClick := pnlCorrectClick;

end;

...

procedure TForm1.FormCreate(Sender: TObject);

begin
  Randomize;
end;

...

procedure TForm1.pnlCorrectClick(Sender: TObject);
begin
  ShowMessage('Correct panel');
end;

procedure TForm1.pnlWrongClick(Sender: TObject);
begin
  ShowMessage('Wrong panel');
end;

调试器异常通知显示:

项目 PAT_P.exe 引发异常类 $C0000005,并显示消息“0x0062a218 处的访问冲突:写入地址 0x00000124”。

delphi
1个回答
0
投票

您无法像您尝试那样将像

showmessage('Correct panel');
这样的表达式直接分配给
OnClick
事件。 事件期望被分配一个类方法。

尝试类似以下内容:

type
  TForm1 = class(TForm)
  published
    btnStart: TButton;
    PanelA1: TPanel;
    ...
    procedure FormCreate(Sender: TObject);
    procedure btnStartClick(Sender: TObject);
    ...
  private
    ...
    procedure pnlCorrectClick(Sender: TObject);
    procedure pnlWrongClick(Sender: TObject);
    ... 
  end;

...

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

procedure TForm1.btnStartClick(Sender: TObject);
var
  i, j: Integer;

  function FindPanel(iChar, iNum: Integer): TPanel;
  var
    cChar: Char;
    sPanelName: string;
  begin
    cChar := Char(Ord('A') + iChar);
    sPanelName := 'pnl' + cChar + IntToStr(iNum);
    Result := FindComponent(sPanelName) as TPanel;
  end;

begin
  // reset the OnClick events of the panels first...
  for i := 0 to 7 do
  begin
    for j := 1 to 7 do
      FindPanel(i, j).OnClick := pnlWrongClick;
  end;

  // now, pick a random panel and assign its OnClick event...
  FindPanel(Random(8), Random(7) + 1).OnClick := pnlCorrectClick;
end;

procedure TForm1.pnlCorrectClick(Sender: TObject);
begin
  ShowMessage('Correct panel');
end;

procedure TForm1.pnlWrongClick(Sender: TObject);
begin
  ShowMessage('Wrong panel');
end;

话虽这么说,我建议将所有面板放入前面的数组中,然后单击按钮时不必按名称搜索任何面板,例如:

type
  TForm1 = class(TForm)
  published
    btnStart: TButton;
    PanelA1: TPanel;
    ...
    procedure FormCreate(Sender: TObject);
    procedure btnStartClick(Sender: TObject);
    ...
  private
    Panels: array[0..55] of TPanel;
    procedure pnlCorrectClick(Sender: TObject);
    procedure pnlWrongClick(Sender: TObject);
    ...
  end;

...

procedure TForm1.FormCreate(Sender: TObject);
var
  i, j, k: Integer;

  function FindPanel(iChar, iNum: Integer): TPanel;
  var
    cChar: Char;
    sPanelName: string;
  begin
    cChar := Char(Ord('A') + iChar);
    sPanelName := 'pnl' + cChar + IntToStr(iNum);
    Result := FindComponent(sPanelName) as TPanel;
  end;

begin
  Randomize;

  k := 0;
  for i := 0 to 7 do
  begin
    for j := 1 to 7 do
    begin
      Panels[k] := FindPanel(i, j);
      Inc(k);
    end;
  end;
end;

procedure TForm1.btnStartClick(Sender: TObject);
var
  i: integer;
begin
  // reset the OnClick event of the panels first...
  for i := Low(Panels) to High(Panels) do
    Panels[i].OnClick := pnlWrongClick;

  // now, pick a random panel and assign its OnClick event...
  Panels[Random(56)].OnClick := pnlCorrectClick;
end;

procedure TForm1.pnlCorrectClick(Sender: TObject);
begin
  ShowMessage('Correct panel');
end;

procedure TForm1.pnlWrongClick(Sender: TObject);
begin
  ShowMessage('Wrong panel');
end;
© www.soinside.com 2019 - 2024. All rights reserved.