我尝试显示一个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聚焦时,我想要的窗口顺序是:
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
答案 0 :(得分:0)
感谢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;