当我执行OnDblClick事件(Form1)打开Form2时,它会触发Form2的OnCellClick事件,而没有单击form2网格

Lui*_*ann 7 delphi delphi-10.2-tokyo

活动表格1:

procedure TForm1.Panel1DblClick(Sender: TObject);
begin
  TForm2.Create(Self).ShowModal;
end;
Run Code Online (Sandbox Code Playgroud)

活动表格2:

procedure TForm2.DBGrid1CellClick(Column: TColumn);
begin
  ShowMessage('Test');
end;
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能避免fom2的onCellClick事件?

Ser*_*yuz 4

操作系统会WM_LBUTTONDBLCLK在鼠标左键按下第二次时发布一个。当您在此处执行调用时,应用程序在显示对话框之前ShowModal没有机会处理尚未发布的消息。WM_LBUTTONUP由于在控件处理消息时TDBGrid触发事件,并且由于模态窗体现在是活动窗口,消息恰好被发布到网格,因此您会遇到问题。OnCellClickWM_LBUTTONUP

网格的行为是有记录的

当用户在网格的某一单元格中释放鼠标时发生。

尽管可能有人会说它应该提到你甚至不必按鼠标按钮......

这是一个不幸的设计决定,这不是点击的工作原理。想象一下按下一个单元上的按钮并在另一个单元上松开。不OnCellClick应该被解雇。当前的行为相当令人困惑,该事件会在您按下按钮的单元格上触发 - 前提是您在有效单元格上而不是在空白区域上释放按钮。

正如您所发现的,您甚至可以通过按下不同表单上的按钮并将其释放到该表单上的网格单元格来触发事件。在这种情况下,事件会针对当前选定的单元格触发,而鼠标位置在其中根本不起任何作用。我的意见是,这OnCellClick完全是一团糟。



您可以使用kobik的答案来解决。如果由于某种原因在任何时间段内第二次按下鼠标按钮,则以下解决方案将失败。


正如问题评论中所建议的那样,发布自己收到的消息来延迟对话框的显示是行不通的,因为发布的消息比输入消息具有更高的优先级。有关更多详细信息,请参阅文档。GetMessage

如果您点击链接,您会注意到计时器方法(也如问题评论中所建议的那样)将会起作用。与评论不同的是,时间间隔并不重要,因为WM_TIMER消息的优先级最低。这是一件好事,使其成为一种万无一失的方法。

我想将计时器放在模式对话框上,因为它拥有问题控制。

procedure TForm2.FormCreate(Sender: TObject);
begin
  DBGrid1.Enabled := False;
  Timer1.Interval := 1;
  Timer1.Enabled := True;
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
  DBGrid1.Enabled := True;
  Timer1.Enabled := False;
end;
Run Code Online (Sandbox Code Playgroud)