4

当用户双击 dbgrid 时,我会显示一个非模态表单。

当他们关闭该表单时,我想刷新网格。

为此,我尝试了以下方法:

1 - 定义自定义消息常量:

const
  WM_REFRESH_MSG = WM_USER + 1;  //defined in a globally available unit

2 - 在我的非模态表单的 OnClose 事件中,我有这个:

procedure TMyNonModalForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  PostMessage(Self.Handle,WM_REFRESH_MSG,0,0);
end;

3 - 在包含 dbGrid 的表单的私有声明中,我有这个:

procedure OnRefreshRequest(var Msg: TMessage); message WM_REFRESH_MSG;

...

procedure TMyFormWithADBGrid.OnRefreshRequest(var Msg: TMessage);
begin
  RefreshGrid;
end;

完成这些操作后,PostMessage 会正常触发,但 OnRefreshRequest 过程永远不会运行。我究竟做错了什么?

4

5 回答 5

9

请注意,WM_USER 不是作为您自己的消息基础的正确常量,除非您正在编写直接从 TWinControl 下降的自定义控件。请改用 WM_APP。

此外,将 UM_ 用于用户消息而不是 WM_ 被认为是一种很好的风格,因为该前缀应该为 Windows 头文件保留。

于 2009-05-14T09:59:21.797 回答
6

除了另一个答案中的消息名称之外,您正在向 Self.Handle 发布消息,而 Self 正在离开。您可能打算发布到不同的句柄(启动无模式句柄的窗口)。当您创建它时,让您的无模式窗口访问该句柄,并在那里发布消息。

于 2009-05-13T20:21:08.890 回答
2

发布消息需要发送到另一个窗口句柄,而不是您列出的 self.handle。一种方法是在非模态表单上创建一个新属性,并在显示非模态表单之前为其分配另一个表单的句柄。

除此之外,并正确实施 WM_REFRESH_MSG(CheGueVerra 正确)它应该可以正常工作。

于 2009-05-13T20:21:33.850 回答
1

您可以尝试更改声明的结尾以匹配您尝试发送的消息。

procedure OnRefreshRequest(var Msg: TMessage); message WM_CEA_REFRESH;

应该是这个

procedure OnRefreshRequest(var Msg: TMessage); message WM_REFRESH_MSG;
于 2009-05-13T20:10:26.050 回答
1

我上传了一个“凯文会做什么?”的例子。到 Embarcadero 的新闻组论坛 embarcadero.public.attachments。

基本上,当非模态表单关闭时,主表单(或您想要的任何表单/对象)订阅的自定义事件。在主要(或其他)形式...

var
  NonModalForm :TfmNonModalForm;
begin
  NonModalForm := TfmNonModalForm.Create(nil); 
  NonModalForm.Execute(NonModalFormClosingListener);

在执行方法中

procedure TfmNonModalForm.Execute(YourListenerMethod: THeyIClosedEvent);
begin
   FHeyIClosedEvent := YourListenerMethod;
   Show();
end;

如果您无法访问论坛并需要其他代码,请发表评论,我会发布缺失的部分。

祝你好运

于 2009-05-15T15:32:29.070 回答