使用 ModalResult 退出表单
我有一堆表单,我想将它们自动化,以便它们可以自行打开和关闭。
我知道如何打开它们(通过 OnActivate 函数),但我在关闭它们时遇到问题。
例如,我有
procedure TProgressForm.FormActivate(Sender: TObject);
begin
inherited;
if FModItem.IsInQueue then
begin
RunBtnClick(Self);
ModalResult := mrOK;
end;
end;
一个运行函数。我想在函数运行后关闭窗口,这就是 ModalResult 应该做的。
(我还尝试在 RunBtnClick 过程的最后添加 ModalResult 行,但这也不起作用)
并且我正在创建这样的表单:
ProgForm := TProgressForm.Create(Self, FModItem);
Self.Visible := False;
try
if ProgForm.ShowModal = mrOK then
begin
Left := ProgForm.Left;
Top := ProgForm.Top;
end;
我已经能够创建按钮来关闭表单通过将 mrOK 添加到对象检查器中的模态结果中,但我似乎无法明确执行此操作
有人能明白为什么它不起作用吗?
谢谢
I have a bunch of forms and I want to automate them so they would open and close by themselves.
I know how to get them to open (by having an OnActivate function), but I'm having trouble closing them.
So, for example, I have
procedure TProgressForm.FormActivate(Sender: TObject);
begin
inherited;
if FModItem.IsInQueue then
begin
RunBtnClick(Self);
ModalResult := mrOK;
end;
end;
which runs a function. I want to close the window after the function has been run, which is what ModalResult should do.
(I've also tried adding the ModalResult line at the very end of the RunBtnClick procedure, but that didn't work either)
and I'm creating the form like this:
ProgForm := TProgressForm.Create(Self, FModItem);
Self.Visible := False;
try
if ProgForm.ShowModal = mrOK then
begin
Left := ProgForm.Left;
Top := ProgForm.Top;
end;
I've been able to create buttons to close the form just by adding mrOK to the Modal Result in Object Inspector, but I can't seem to do it explicitly
Can anyone see why it's not working?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不起作用的原因是,在显示表单之后、开始检查对 ModalResult 的更改之前,VCL 在 TCustomForm.ShowModal 中主动将 ModalResult 设置为 0。所以在 OnActivate 和 OnShow 中,你太早了。
解决方案是延迟通知。这可以通过 PostMessage 来完成,如下所示:
来源:NLDelphi< /a>
The reason for not working is that the VCL actively sets ModalResult to 0 in TCustomForm.ShowModal áfter showing the form, but prior to starting checking changes to ModalResult. So in OnActivate and in OnShow, you are to early.
The solution is to delay the notification. This can be done by a PostMessage, as follows:
Source: NLDelphi
我将重写
ShowModal
并执行您现在在OnActvate
中执行的测试。这有两大优点:OnActivate
启动表单关闭会导致表单在屏幕上“闪烁”:它会显示并立即关闭。ShowModal
中的操作顺序,因为只有在需要实际显示表单时才调用它。当然,以这种方式使用 GUI 元素(表单)有点代码味道,因为它基本上使用 GUI 而不需要用户交互。毫无疑问,可以将其重构为使用一个中间函数,该函数返回
mrOk
并执行RunBtnClick()
的操作,而无需 GUI,并创建Form
仅在需要时。我想这是一种成本效益的情况。代码:
I'd override
ShowModal
and do the tests you now do inOnActvate
from over there. This has two big advantages:OnActivate
causes the form to "flicker" on screen: It's shown and immediately taken down.ShowModal
, because you only call it if the form needs to actually be shown.Of course, using a GUI element (a form) this way is a bit of code smell because it basically uses a GUI without the need for user interaction. This can undoubtedly be refactored to use an intermediary function that returns
mrOk
and does whatRunBtnClick()
does without needing the GUI, and creates theForm
only if needed. I guess it's a cost-benefit kind of situation.Code:
OnActivate 事件在 TCustomForm.ShowModal 中的 ModalResult 重置为 mrNone 之前触发。这意味着 OnActivate 处理程序中的 ModalResult 更改将被忽略。
The OnActivate event is triggered before the ModalResult is reset to mrNone in TCustomForm.ShowModal. This means that changing ModalResult in your OnActivate handler is ignored.
查看 TCustomForm.ShowModal(在 forms.pas 内):直到发送 CM_ACTIVATE 消息之后(所述消息触发您的 OnActivate 调用),才首先检查 ModalResult;事实上,在 OnActivate 调用返回后,它立即设置为 0,因此您的作业不起作用也就不足为奇了。
我不想对此搞得太混乱(您的代码肯定无法通过气味测试),但您可以尝试添加类似以下内容:
到事件处理程序的顶部。
Look at TCustomForm.ShowModal (inside forms.pas): ModalResult is not first checked until after the CM_ACTIVATE message is sent (said message triggers your OnActivate call); in fact, it's set to 0 immediately after your OnActivate call returns, so it's no wonder your assignment isn't working.
I don't want to mess too much with this (your code definitely fails the smell test), but you could try adding something like:
to the top of your event handler.