gpt4 book ai didi

delphi - 如何在运行时使用另一个过程中的过程在组合框上设置 onChange 事件?

转载 作者:行者123 更新时间:2023-12-02 01:32:12 32 4
gpt4 key购买 nike

我有一个动态代码,它在 StringGrid 单元格中创建一个组合框,并且该组合是在运行时创建的,我应该为其设置 onChange 事件。我正在使用下面的代码,但是这个代码引发了一个异常,有人可以帮助我成为 TNotifyEvent 中的comboBoxOnChange 方法吗?

procedure TForm1.gridSelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
var
R: TRect;
combo : TComboBox;
procedure comboBoxOnChange(Sender: TObject);
begin
combo.Visible := false;
combo.Free;
end;
begin
combo := TComboBox.Create(self);
combo.Parent := self;
//[DCC Error] Unit1.pas(57): E2010 Incompatible types: 'TNotifyEvent' and 'procedure, untyped pointer or untyped parameter'
combo.OnChange := comboBoxOnChange;

combo.Items.Add('Item1');
combo.Items.Add('Item2');
combo.Items.Add('Item3');
combo.Items.Add('Item4');
combo.Items.Add('Item5');
combo.Items.Add('Item6');
combo.Items.Add('Item7');
combo.Items.Add('Item8');
combo.Items.Add('Item9');
combo.Items.Add('Item10');

R := Grid.CellRect(ACol, ARow);
R.Left := R.Left + grid.Left;
R.Right := R.Right + grid.Left;
R.Top := R.Top + grid.Top;
R.Bottom := R.Bottom + grid.Top;

combo.Left := R.Left + 1;
combo.Top := R.Top + 1;
combo.Width := (R.Right + 1) - R.Left;
combo.Height := (R.Bottom + 1) - R.Top;
combo.Visible := True;
combo.SetFocus;
CanSelect := True;
end;

最佳答案

如果您手动声明并填写 TMethod 记录,然后在将其分配给目标事件时对其进行类型转换,则可以使用任何非类方法过程作为事件处理程序。另外,不是类的成员意味着隐藏的 Self 参数丢失,因此您必须显式声明它。

对于嵌套过程,只要该过程不尝试访问其包含过程中的任何内容,这种方法就可以正常工作,因为当事件实际触发时,这些变量将不再处于作用域内。

话虽如此,更大的问题是控件无法从其自己的事件之一中 Free() 自身,否则您将收到 AccessViolation 错误。这是因为在事件处理程序退出后,RTL 仍然需要访问该对象。因此,您必须延迟调用 Free() 直到事件处理程序退出之后,例如使用 PostMessage() 发布自定义窗口消息,以便它通过消息队列。

试试这个:

type
TForm1 = class(TForm)
//...
protected
procedure WndProc(var Message: TMessage); override;
//...
end;

const
APPWM_FREE_OBJECT = WM_APP + 100;

procedure TForm1.WndProc(var Message: TMessage);
begin
if Message.Msg = APPWM_FREE_OBJECT then
TObject(Message.LParam).Free
else
inherited;
end;

procedure TForm1.gridSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
var
combo : TComboBox;
M: TMethod;
//...

procedure comboBoxOnChange(Self: Pointer; Sender: TObject);
begin
TComboBox(Sender).Visible := false;
//combo.Free;
PostMessage(Form1.Handle, APPWM_FREE_OBJECT, 0, LPARAM(Sender));
end;

begin
combo := TComboBox.Create(Self);
combo.Parent := Self;
//...

M.Code := Addr(comboBoxOnChange);
M.Data := combo;
combo.OnChange := TNotifyEvent(M);

CanSelect := True;
end;

关于delphi - 如何在运行时使用另一个过程中的过程在组合框上设置 onChange 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16692790/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com