Delphi 将表单放在其他应用程序窗口的顶部

Delphi 将表单放在其他应用程序窗口的顶部,delphi,vcl,delphi-10-seattle,Delphi,Vcl,Delphi 10 Seattle,我试图展示一个VCL表单,它位于所有其他应用程序的顶部,这样数据就可以从这个表单复制到另一个应用程序中,而不需要两个应用程序在前面的应用程序之间切换 我可以显示表单,并将其放在其他应用程序的顶部,使用fsStayOnTop与其他应用程序交互,并使用以下代码打开表单: form := TForm2.Create(nil); SetWindowPos(form.Handle, // handle to window HWND_TOPMOST, // placement-order hand

我试图展示一个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();
我现在遇到的问题是,当我点击我的表单,复制并粘贴其中的数据时,我的应用程序的其他表单也会出现,这会隐藏我复制数据到的应用程序。主应用程序表单使用showmodel打开一个TForm1,然后可以使用上面的代码打开TForm2,我认为这会使它向前推进TForm1,因为它不应该有所有者或父级

我已经看了这个问题,不幸的是,它并没有阻止其他形式的提出

因此,在关注TForm2时,我希望窗口的顺序是:

mainform
TForm1
Whatever application, normally word
TForm2
相反,我得到了

Whatever application, normally word
mainform
TForm1
TForm2
我知道这个功能看起来有点奇怪,但它对于提高可用性很重要,主要是在单监视器机器上,因为用户可能会频繁地在我的表单和其他应用程序之间切换

我目前正在Windows10Professional64位上使用Delphi10Seattle,以防有所帮助

超级简单的例子 (如果有更好的方法提供上述示例,我很想知道):

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建议隐藏其他表单,我利用从中找到的信息提出了此解决方案

简单解 我们的想法是简单地使用/遍历当前显示的所有表单,使它们不可见,然后在完成后使它们再次可见

扩展解 如果您的表单是使用
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;
procedure TForm2.按钮1单击(发送方:TObject);
变量
表3:TForm3;
ii:整数;
可见形式:TList;
开始
visibleForms:=TList.Create();
尝试
对于ii:=0到Screen.FormCount-1 do
开始
如果Screen.Forms[ii]可见,则
visibleForms.Add(屏幕表格[ii]);
Screen.Forms[ii].可见:=false;
结束;
form3:=TForm3.Create(nil);
SetWindowPos(form3.Handle,//句柄到窗口
HWND_最上面,//放置顺序句柄
form3.左,//水平位置
form3.Top,//垂直位置
格式3.宽度,格式3.高度,
//窗口定位选项
SWP_-noactive或SWP_-NOMOVE或SWP_-NOSIZE);
表3.ShowModal();
form3.Free();
最后
对于ii:=0到visibleForms。计数-1 do
visibleForms[ii]。Visible:=true;
visibleForms.Free();
结束;
结束;

多亏了Nat的建议,我利用从中找到的信息,提出了隐藏其他表单的解决方案

简单解 我们的想法是简单地使用/遍历当前显示的所有表单,使它们不可见,然后在完成后使它们再次可见

扩展解 如果您的表单是使用
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;
procedure TForm2.按钮1单击(发送方:TObject);
变量
表3:TForm3;
ii:整数;
可见形式:TList;
开始
visibleForms:=TList.Create();
尝试
对于ii:=0到Screen.FormCount-1 do
开始
如果Screen.Forms[ii]可见,则
visibleForms.Add(屏幕表格[ii]);
Screen.Forms[ii].可见:=false;
结束;
form3:=TForm3.Create(nil);
SetWindowPos(form3.Handle,//句柄到窗口
HWND_最上面,//放置顺序句柄
form3.左,//水平位置
form3.Top,//垂直位置
格式3.宽度,格式3.高度,
//窗口定位选项
SWP_-noactive或SWP_-NOMOVE或SWP_-NOSIZE);
表3.ShowModal();
form3.Free();
最后
对于ii:=0到visibleForms。计数-1 do
visibleForms[ii]。Visible:=true;
visibleForms.Free();
结束;
结束;

隐藏其他表单。@Nat谢谢,我将尝试一下,看看如何隐藏其他表单。@Nat谢谢,我将尝试一下,看看如何隐藏其他表单。@Nat谢谢