将表单置于其他应用程序之上 windows
Keep form on top of other application windows
我正在尝试展示一个位于所有其他应用程序之上的 VCL 表单,以便可以将数据从该表单复制到另一个应用程序,而无需在两个应用程序之间切换哪个在前。
我可以显示一个表单并将它放在所有其他应用程序的顶部,并使用 fsStayOnTop 与其他应用程序交互并使用以下代码打开它:
form := TForm2.Create(nil);
SetWindowPos(form.Handle, // handle to window
HWND_TOPMOST, // placement-order handle
form.Left, // horizontal position
form.Top, // vertical position
form.Width, form.Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
form.Show();
我目前遇到的问题是,当我单击我的表单以从中复制和粘贴数据时,我的应用程序的其他表单也会出现,这隐藏了我正在将数据复制到的应用程序.主应用程序表单使用 ShowModal 打开 TForm1,然后可以使用上面的代码打开 TForm2,我认为它会继续将 TForm1 向前推进,因为它不应该有所有者或父级。
我已经看过这个问题 How can get my form to be on top of everything all the time? 不幸的是,它并没有阻止其他表格的提出。
所以当 TForm2 被聚焦时,windows 的顺序是:
mainform
TForm1
Whatever application, normally word
TForm2
相反,我得到
Whatever application, normally word
mainform
TForm1
TForm2
我知道这个功能看起来有点奇怪,但它对于提高可用性很重要,主要是在单显示器机器上,因为用户可能会非常频繁地在我的表单和其他应用程序之间切换。
我目前在 Windows 10 Professional 64 位上使用 Delphi 10 Seattle 以防有帮助。
超级简单的例子
(如果有更好的方法来提供上述示例,我很想知道):
Form1 按钮
procedure TForm1.Button1Click(Sender: TObject);
var
form2: TForm2;
begin
form2 := TForm2.Create(self);
form2.ShowModal();
end;
Form2 按钮
procedure TForm2.Button1Click(Sender: TObject);
var
form3: TForm3;
begin
form3 := TForm3.Create(nil);
SetWindowPos(form3.Handle, // handle to window
HWND_TOPMOST, // placement-order handle
form3.Left, // horizontal position
form3.Top, // vertical position
form3.Width, form3.Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
form3.Show();
end;
Form3: FormStyle = fsStayOnTop
感谢 Nat 关于隐藏其他表格的建议,我利用从 How to get a list from all opened forms of my software?
中找到的信息想出了这个解决方案
简单的解决方案
procedure TForm2.Button1Click(Sender: TObject);
var
form3: TForm3;
ii: integer;
begin
for ii := 0 to Screen.FormCount - 1 do
Screen.Forms[ii].Visible := false;
form3 := TForm3.Create(nil);
SetWindowPos(form3.Handle, // handle to window
HWND_TOPMOST, // placement-order handle
form3.Left, // horizontal position
form3.Top, // vertical position
form3.Width, form3.Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
form3.ShowModal();
form3.Free();
for ii := 0 to Screen.FormCount - 1 do
Screen.Forms[ii].Visible := true;
end;
我们的想法是简单地使用 Screen.Forms/Screen.FormCount 遍历所有当前显示的表单并使它们不可见,然后当我们完成后使它们再次可见。
扩展解决方案
如果您的表单是使用 Application.CreateForm()
创建的,并且只是显示和关闭但从未释放,那么这也将打开所有这些表单。我找到的解决方案是存储可见表单的列表,并只使最后可见的表单可见。
procedure TForm2.Button1Click(Sender: TObject);
var
form3: TForm3;
ii: integer;
visibleForms: TList<TForm>;
begin
visibleForms := TList<TForm>.Create();
try
for ii := 0 to Screen.FormCount - 1 do
begin
if Screen.Forms[ii].Visible then
visibleForms.Add(Screen.Forms[ii]);
Screen.Forms[ii].Visible := false;
end;
form3 := TForm3.Create(nil);
SetWindowPos(form3.Handle, // handle to window
HWND_TOPMOST, // placement-order handle
form3.Left, // horizontal position
form3.Top, // vertical position
form3.Width, form3.Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
form3.ShowModal();
form3.Free();
finally
for ii := 0 to visibleForms.Count - 1 do
visibleForms[ii].Visible := true;
visibleForms.Free();
end;
end;
我正在尝试展示一个位于所有其他应用程序之上的 VCL 表单,以便可以将数据从该表单复制到另一个应用程序,而无需在两个应用程序之间切换哪个在前。
我可以显示一个表单并将它放在所有其他应用程序的顶部,并使用 fsStayOnTop 与其他应用程序交互并使用以下代码打开它:
form := TForm2.Create(nil);
SetWindowPos(form.Handle, // handle to window
HWND_TOPMOST, // placement-order handle
form.Left, // horizontal position
form.Top, // vertical position
form.Width, form.Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
form.Show();
我目前遇到的问题是,当我单击我的表单以从中复制和粘贴数据时,我的应用程序的其他表单也会出现,这隐藏了我正在将数据复制到的应用程序.主应用程序表单使用 ShowModal 打开 TForm1,然后可以使用上面的代码打开 TForm2,我认为它会继续将 TForm1 向前推进,因为它不应该有所有者或父级。
我已经看过这个问题 How can get my form to be on top of everything all the time? 不幸的是,它并没有阻止其他表格的提出。
所以当 TForm2 被聚焦时,windows 的顺序是:
mainform
TForm1
Whatever application, normally word
TForm2
相反,我得到
Whatever application, normally word
mainform
TForm1
TForm2
我知道这个功能看起来有点奇怪,但它对于提高可用性很重要,主要是在单显示器机器上,因为用户可能会非常频繁地在我的表单和其他应用程序之间切换。
我目前在 Windows 10 Professional 64 位上使用 Delphi 10 Seattle 以防有帮助。
超级简单的例子
(如果有更好的方法来提供上述示例,我很想知道):
Form1 按钮
procedure TForm1.Button1Click(Sender: TObject);
var
form2: TForm2;
begin
form2 := TForm2.Create(self);
form2.ShowModal();
end;
Form2 按钮
procedure TForm2.Button1Click(Sender: TObject);
var
form3: TForm3;
begin
form3 := TForm3.Create(nil);
SetWindowPos(form3.Handle, // handle to window
HWND_TOPMOST, // placement-order handle
form3.Left, // horizontal position
form3.Top, // vertical position
form3.Width, form3.Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
form3.Show();
end;
Form3: FormStyle = fsStayOnTop
感谢 Nat 关于隐藏其他表格的建议,我利用从 How to get a list from all opened forms of my software?
中找到的信息想出了这个解决方案简单的解决方案
procedure TForm2.Button1Click(Sender: TObject);
var
form3: TForm3;
ii: integer;
begin
for ii := 0 to Screen.FormCount - 1 do
Screen.Forms[ii].Visible := false;
form3 := TForm3.Create(nil);
SetWindowPos(form3.Handle, // handle to window
HWND_TOPMOST, // placement-order handle
form3.Left, // horizontal position
form3.Top, // vertical position
form3.Width, form3.Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
form3.ShowModal();
form3.Free();
for ii := 0 to Screen.FormCount - 1 do
Screen.Forms[ii].Visible := true;
end;
我们的想法是简单地使用 Screen.Forms/Screen.FormCount 遍历所有当前显示的表单并使它们不可见,然后当我们完成后使它们再次可见。
扩展解决方案
如果您的表单是使用 Application.CreateForm()
创建的,并且只是显示和关闭但从未释放,那么这也将打开所有这些表单。我找到的解决方案是存储可见表单的列表,并只使最后可见的表单可见。
procedure TForm2.Button1Click(Sender: TObject);
var
form3: TForm3;
ii: integer;
visibleForms: TList<TForm>;
begin
visibleForms := TList<TForm>.Create();
try
for ii := 0 to Screen.FormCount - 1 do
begin
if Screen.Forms[ii].Visible then
visibleForms.Add(Screen.Forms[ii]);
Screen.Forms[ii].Visible := false;
end;
form3 := TForm3.Create(nil);
SetWindowPos(form3.Handle, // handle to window
HWND_TOPMOST, // placement-order handle
form3.Left, // horizontal position
form3.Top, // vertical position
form3.Width, form3.Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
form3.ShowModal();
form3.Free();
finally
for ii := 0 to visibleForms.Count - 1 do
visibleForms[ii].Visible := true;
visibleForms.Free();
end;
end;