从窗口类名获取窗口句柄

8
我正在尝试获取我进程中子窗口的窗口句柄,唯一的信息是窗口类名。是否有任何win32函数可供使用?我是用C#编写的。
更详细的说明:这是一个Visual Studio插件,用C#编写。因此,我的进程是Visual Studio,它有很多窗口。其中一个窗口有一个窗口类“VsTipWindow”。我不知道该窗口的直接父窗口,我只有类名。是否有办法让我仅通过这个类名获取窗口句柄?
4个回答

3

FindWindow 是你所需要的 Win32 调用函数(如果有多个具有相同类名的窗口,而 FindWindow 无法返回你要查找的窗口,则需要使用 FindWindowEx 函数)。


我刚刚注意到你问题中的 findwindow 标签 - 猜得不错。 :) - MusiGenesis
FindWindow只能找到顶层窗口,FindWindowEx才是你真正需要的,但最好调用Enum函数以便不会错过任何窗口。 - Anders
@Anders:已经添加了FindWindowEx链接。在大多数类似情况下,FindWindow会返回您想要的窗口。最安全的方法是首先不要操纵窗口类名。 - MusiGenesis

1

1
WindowFromPoint在这里不适用,除非您建议用户在特定时间或事件将光标指向此窗口! - Anders
1
@Anders,VsTipWindow是一种ToolTipWindow。TooltipWindows的特点是当鼠标悬停在另一个窗口上时可见,并在鼠标离开窗口时消失。但无论如何,WindowFromPoint与鼠标指针本身无关。它提供任意点的窗口句柄。它是否适用于此并不是问题,请阅读我的前3个单词。我只是想给出另一个想法,以防Einar的第一个想法行不通。我们甚至不知道他打算做什么。 - OlimilOops

0
首先需要注意的是,窗口和窗口类之间不存在一对一的关系,多个窗口可以使用同一个类。
我猜你唯一的选择是从顶层 Visual Studio 窗口开始递归调用 EnumChildWindows(或者如果你知道某个作为 VsTipWindow 窗口祖先的窗口,则可以使用该窗口更高级别的窗口)。在 EnumChildWindows 的回调函数中,您将调用 GetClassName 并将字符串与 VsTipWindow 进行比较,直到找到该窗口。
由于你提到了未知的父窗口,我假设你想要寻找一个子窗口,但如果这个窗口是一个顶层窗口,你需要使用 EnumWindows(并且你应该使用 GetWindowThreadProcessId 来确保你在找到具有该类名的窗口后也获得正确的进程)。
(我相信 .NET 有与本机 API 相同的功能,否则你需要 PInvoke。)

1
谢谢,那个解决了问题。虽然要明确一下,“EnumChildWindows 递归”实际上只需使用顶层窗口句柄调用它一次,EnumChildWindows 函数本身已经进行了递归。 - Einar Egilsson

0
Win32窗口类是控件的通用实现,窗口的句柄是控件的实例。因此,您将具有相同窗口类(例如:EDIT)的多个窗口句柄。严格来说,窗口类是指向窗口过程的指针。
像.NET(甚至MFC)这样的框架倾向于为所有窗口控件共享少量窗口类,然后它们将分派到适当的控件(即它们具有单个通用窗口过程)。这对于像Visual Studio或Office这样的大型应用程序也是如此。
因此,这使得仅通过其窗口类检测特定窗口非常困难。但是,您可以使用FindWindow枚举具有特定窗口类的所有窗口,您还将获得可能有所帮助的窗口文本。使用GetWindowThreadProcessId,您可以检测窗口是否属于Visual Studio。

好的。但在这种特殊情况下,我知道每次只有一个具有该特定窗口类的活动窗口,所以这不是问题。我可能应该在问题中说明这一点 :) - Einar Egilsson

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