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



我有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;

我试图只显示一个带有变量OnClick事件的ShowMessage(),但它不起作用。我一直收到一个运行时错误。


编辑:

下面添加了我的新代码。。。

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引发异常类$C000005,消息为"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;

最新更新