我有 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”。
您无法像您尝试那样将像
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;