让窗口始终保持在已经置顶的另一个窗口之上?

8

如何让一个窗口始终保持在已经一直处于最顶层的另一个窗口之上?不是要它一直处于所有其他窗口之上,我只需要它保持在特定窗口之上。

2个回答

16

感谢SLaks的答案和相关评论, 我成功地解决了如何在我的窗体之间建立父子关系的问题。我不能使用 Form.Show(owner),因为我想保持在前面的窗体是在另一个窗体之前显示的。我使用Reflector来查看Form.Show(owner)背后的代码,并发现其实质上都可以通过 Windows API 中的SetWindowLong来实现。

LONG SetWindowLong(      
    HWND hWnd,
    int nIndex,
    LONG dwNewLong
);
Form.Show(owner) 调用了 SetWindowLong 并将 nIndex 设置为 -8。MSDN 在线文档不会告诉你,但是根据 Winuser.h,nIndex 可用的常量之一是 GWL_HWNDPARENT,它的值为 -8。一旦我把这些点连接起来,问题就很容易解决了。
以下是如何设置窗口的父级,即使它已经显示:
using System.Runtime.InteropServices;

[DllImport("user32.dll")]
public static extern int SetWindowLong(HandleRef hWnd, int nIndex, HandleRef dwNewLong);

public static void SetOwner(IWin32Window child, IWin32Window owner)
{
    NativeMethods.SetWindowLong(
        new HandleRef(child, child.Handle), 
        -8, // GWL_HWNDPARENT
        new HandleRef(owner, owner.Handle));
}

感谢您发布您的解决方案。太棒了! - Jacob Seleznev

2

不要这样做

话虽如此,您可以通过将您的窗口设置为另一个窗口的子级来实现它。


1
我看过那篇博客文章,但我的意思不是让窗口始终保持在所有其他窗口的最上层,而只是在特定的窗口上方。 - Zach Johnson
1
是的,如果您的第一个模态窗口生成另一个模态窗口,则后者将成为新的最上层窗口。但现在您有原始窗口和第一个模态窗口坐落在新模态窗口后面,它们无法移动或拖动,如果用户需要隐藏在这些窗口后面的信息,这可能会令人沮丧。 - AaronLS
@aaronls:他没有制作模态窗口。 - SLaks
我的表单不是模态的。用户可以随意在它们之间交互。这些窗口彼此相邻,我正在尝试防止当用户与第二个窗口交互时,其阴影重叠到第一个窗口中。 - Zach Johnson
SLaks是正确的。如果您使用Form.Show(owner)方法,您可以将子窗口保持在“owner”窗口的顶部,而不会阻止所有者的UI。这被称为“无模式”对话框。对于顶级窗口也应该适用。 - user180326
不幸的是,我无法使用Form.Show(owner),因为第二个窗体在技术上需要成为第一个窗体的所有者,但第二个窗口在第一个窗口之后显示。 - Zach Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接