delphi 是否可以将为组件创建的变量与单击事件一起使用?

dsf9zpds  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(156)

我有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“。

5f0d552i

5f0d552i1#

您不能像您尝试的那样,将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;

相关问题