我有一些vcl mdi应用程序,我需要在其中做一些工作,并在上面显示另一种无模式的进度形式。并且由于此进度表是从某个线程更新的,并且上面有一些按钮(以取消操作),因此我使用application.ProcessMessages更新了进度。在此过程中,我需要禁用所有主窗体控件。我是这样做的:
MainForm.enabled := false;
... do some work here, update progress ...
MainForm.enabled := true;
但是,在此之后,我的主窗体进入了其他不很酷的Windows应用程序。如果我删除已启用/禁用的这两行-它会保持在应有的位置。
有什么解决办法吗?
答案 0 :(得分:1)
一个简单的BringTofront
可以工作。可以在将enabled
设置为true
之前或之后。
MainForm.enabled := false;
// ... do some work here, update progress ...
MainForm.enabled := true;
MainForm.BringTofront;
或
MainForm.enabled := false;
// ... do some work here, update progress ...
MainForm.BringTofront;
MainForm.enabled := true;
修改: 如下所述,使用上面的代码,主窗体在成为焦点之前将落后于其他窗体。这种情况发生在Delphi 7中,但似乎没有发生在Delphi 2009中。
当当前活动窗体关闭或隐藏时,Delphi尝试切换到主窗体。但是,如果禁用了主窗体,Delphi将无法激活它,而会将其移到后面。解决方案非常简单,只需在隐藏或释放其他表单之前将Enabled
设置为true
。无需致电BringTofront
。
MainForm.enabled := false;
ProgressForm.Show; // Or Application.CreateForm(...)
// ... do some work here, update progress ...
MainForm.enabled := true;
ProgressForm.Hide; // Or ProgressForm.Free;
修改: 这是导致此行为的Delphi代码:
procedure TCustomForm.CMShowingChanged(var Message: TMessage);
....
begin
....
NewActiveWindow := 0;
if (GetActiveWindow = Handle) and not IsIconic(Handle) then
NewActiveWindow := FindTopMostWindow(Handle);
if NewActiveWindow <> 0 then
begin
SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_HIDEWINDOW or
SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE);
SetActiveWindow(NewActiveWindow);
end else
ShowWindow(Handle, SW_HIDE);
....
end;
另一种解决方法是处理第二种形式的CM_SHOWINGCHANGED
消息:
procedure CMSHOWINGCHANGED(var Message: TMessage); message CM_SHOWINGCHANGED;
procedure TProgressForm.CMSHOWINGCHANGED(var Message: TMessage);
begin
if not visible then
Application.MainForm.Enabled := True;
inherited;
end;
答案 1 :(得分:0)
好的,看起来我找到了解决方案。进度表的PopupMode设置为pmAuto。在这种情况下,主窗体位于顶部。
它以这种方式工作:
procedure TMainForm.DoSomenthing;
begin
enabled := false;
try
// open progress form
Include(ProgressFrm.FFormState, fsModal);
ProgressFrm.Show;
.... do something, update progress ....
// close progress form
ProgressFrm.Hide;
Exclude(ProgressFrm.FFormState, fsModal);
finally
enabled := true;
BringToFront;
end;
end;