[英]Modal forms hidden by fsStayOnTop forms
I have a form (TBigForm in the example below) which allows to manipulate some complex data and needs additional information to be shown. 我有一个表格(在下面的示例中为TBigForm),该表格允许处理一些复杂的数据,并且需要显示其他信息。 I put this info in a fsStayOnTop form (OnTopForm in the example) to ensure it's always visible but can be moved out of the way if necessary.
我将此信息放在fsStayOnTop表单(示例中为OnTopForm)中,以确保它始终可见,但在必要时可以移开。 Now when some user action in TBigForm shows a modal form this often gets hidden behind OnTopForm which makes the app look frozen.
现在,当TBigForm中的某些用户操作显示模式窗体时,这通常会隐藏在OnTopForm后面,这会使应用程序看起来冻结。 How can I avoid this?
如何避免这种情况? (Searching yields many, many hits but I wasn't able to distill a solution out of them.)
(搜索会产生很多很多匹配,但我无法从中提取解决方案。)
In my real app there are a lot of places where modal forms are shown, so I would like to avoid changing all of these calls. 在我的真实应用程序中,有很多地方显示模态形式,因此我想避免更改所有这些调用。
Example : Create a new VCL application, drop a TButton on Form1, double-click the button and replace the generated Button1Click implementation stub with the following: 示例 :创建一个新的VCL应用程序,在Form1上放置一个TButton,双击该按钮,并将生成的Button1Click实现存根替换为以下内容:
type
TBigForm = class(TForm)
strict private
OnTopForm: TForm;
Button1: TButton;
procedure Button1Click(Sender: TObject);
protected
procedure DoHide; override;
procedure DoShow; override;
public
constructor Create(AOwner: TComponent); override;
end;
{ TBigForm }
procedure TBigForm.Button1Click(Sender: TObject);
begin
ShowMessage('Test');
end;
constructor TBigForm.Create(AOwner: TComponent);
begin
inherited CreateNew(AOwner);
Caption := 'Big form';
WindowState := wsMaximized;
Button1 := TButton.Create(Self);
Button1.Parent := Self;
Button1.Caption := 'Freeze!';
Button1.SetBounds(10, 10, 100, 100);
Button1.OnClick := Button1Click;
end;
procedure TBigForm.DoHide;
begin
OnTopForm.Free;
inherited DoHide;
end;
procedure TBigForm.DoShow;
begin
inherited DoShow;
OnTopForm := TForm.Create(Self);
OnTopForm.Caption := 'Important information';
OnTopForm.BorderStyle := bsToolWindow;
OnTopForm.FormStyle := fsStayOnTop;
OnTopForm.Position := poScreenCenter;
OnTopForm.Show;
end;
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var
f: TBigForm;
begin
f := TBigForm.Create(nil);
try
f.ShowModal;
finally
f.Free;
end;
end;
Start the app, click on "Button1" and then on "Freeze!". 启动应用程序,单击“ Button1”,然后单击“冻结!”。
(BTW: We use D2007.) (顺便说一句:我们使用D2007。)
Change temporarily the FormStyle of your OnTopform before displaying another Form as Modal: 在将另一个窗体显示为模态之前,暂时更改OnTopform的FormStyle:
procedure TBigForm.Button1Click(Sender: TObject);
begin
OnTopForm.FormStyle := fsNormal;
ShowMessage('Test');
OnTopForm.FormStyle := fsStayOnTop;
end;
It should work for what you want... 它应该可以满足您的需求...
在调用ShowModal()之前,尝试将模式窗体的PopupParent属性设置为StayOnTop窗体,或将Application.ModalPopupMode属性设置为pmNone以外的其他值。
Here your goody 这是你的礼物
Create an global TApplicationEvents
Declare an global var to keep track of modal form count
Hookup the OnMessage
var
Ctrl: TControl;
if Msg.hwnd <> 0 then
case Msg.message of
CM_ACTIVATE,
CM_DEACTIVATE:
begin
Ctrl := FindControl(Msg.hwnd);
if Ctrl is TForm then
if fsModal in TForm(Ctrl).FormState then
begin
if Msg.message = CM_ACTIVATE then
Inc(Modal form count var)
else
Dec(Modal form count var);
add more logic based on Modal form count var
end;
end;
end;
Have fun 玩得开心
procedure TForm1.ScreenOnActiveFormChange(Sender: TObject);
begin
if (Screen.ActiveForm <> nil) then
begin
if (Screen.ActiveForm.Handle <> Application.MainForm.Handle) then
with Screen.ActiveForm do
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
Windows.SetForeGroundWindow(Screen.ActiveForm.Handle);
end;
end;
This should work. 这应该工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.