C#查找顶级窗口

C#查找顶级窗口,c#,windows,pinvoke,C#,Windows,Pinvoke,如果我有子句柄,如何查找顶级窗口 编辑: 例如,我正在尝试在WindowsMediaPlayer12中获取播放按钮的句柄。 我想我可以用GetForeGroundIndow()获取窗口(WMP窗口)的主句柄,然后在其子窗口中找到play按钮。。。在大多数情况下,GetForegroundWindow()可以工作,我可以获得整个聚焦窗口的句柄,但有时(在本例中)它只返回窗口当前聚焦子窗口的句柄。 所以,在本例中,GetForegroundWindow()返回播放器上部的句柄,play按钮不是它的子

如果我有子句柄,如何查找顶级窗口

编辑:
例如,我正在尝试在WindowsMediaPlayer12中获取播放按钮的句柄。
我想我可以用GetForeGroundIndow()获取窗口(WMP窗口)的主句柄,然后在其子窗口中找到play按钮。。。在大多数情况下,GetForegroundWindow()可以工作,我可以获得整个聚焦窗口的句柄,但有时(在本例中)它只返回窗口当前聚焦子窗口的句柄。
所以,在本例中,GetForegroundWindow()返回播放器上部的句柄,play按钮不是它的子按钮。我想知道如何控制整个球员

EDIT2:
示例2:打开Opera浏览器并在地址栏中单击。调用getForeGroundIndow()。您将仅获得Opera窗口部分的句柄,而不是显示的整个Opera窗口。尝试列出该句柄的子级。没有孩子。

bold是我正在寻找的句柄。)

您是否尝试过使用WindowInteropHelper类

IntPtr windowHandle=新的WindowInteropHelper(myWindow).Owner

IntPtr windowHandle=新的WindowInteropHelper(myWindow).Handle

编辑:

现在您的问题已经编辑好了,我认为您的解决方案可以是从主窗口手柄向下俯冲,而不是从焦点控件向上俯冲。。尝试:

windowmainwindow=Application.Current.mainWindow
继续调用,直到返回
NULL

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

public enum GetAncestorFlags
{
    GetParent = 1,
    GetRoot = 2,
    GetRootOwner = 3
}

[DllImport("user32.dll")]
public static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestorFlags gaFlags);

IntPtr wHandle = GetForgroudWindow();
IntPtr rootHandle = GetAncestor(wHandle, GetAncestorFlags.GetRoot);

rootHandle应该是进程的最顶部窗口。从那里,您可以遍历这些子对象以找到您要查找的子对象。

这样做完全是错误的。您最初的问题是,“如果我有孩子,我如何找到顶级窗口?”您的更新现在会问,“如果我有顶级窗口,我如何找到孩子?”这是一个完全不同的问题。如果你想演奏音乐,为什么不提个问题呢。回答起来又好又容易,而且肯定不会涉及你认为会涉及的任何事情。我不是在尝试演奏音乐。这只是一个例子。如果仔细阅读,您会发现本例中的GetForegroundWindow()不是顶级的,因为这样我就可以控制播放按钮。您选择了一个不使用普通窗口控件的应用程序。类似于这种类型的应用程序(Opera浏览器、Visual Studio…)。我只是想知道如何处理前景中的完整窗口,而不仅仅是它在这种情况下的一部分。我仍然无法理解这个问题。你问了两个截然相反的问题。我很困惑;在我尝试过的每种情况下都返回0,因此在每种情况下只有GetForeGroundIndow()应该可以工作,但在某些情况下它可以工作,而在某些情况下则不行。如果
GetForeGroundIndow()
不是
0
,并且
GetParent(GetForeGroundIndow())
0
,那么您就找到了顶级窗口。好,这就是答案。但这并没有解决我的问题。我仍然无法从应用程序窗口获取所有的孩子。你们似乎把孩子和父母搞混了。请注意,WMP和Opera等应用程序具有非常不寻常的窗口层次结构。要更好地理解它们,请使用Spy++之类的工具。我还建议,自动化API可能是一种更好的方法。