C# 获取鼠标指针下方的窗口句柄,同时忽略半透明窗口
我已经创建了一个半透明表单(60%不透明,背景颜色为黑色),我的应用程序可以在整个屏幕上最大化地启动。基本上,它在整个桌面上投射灰色 当用户将鼠标移到桌面上的某个窗口上时,我希望获得该窗口的句柄(hWnd) 对我来说,最简单的方法是:C# 获取鼠标指针下方的窗口句柄,同时忽略半透明窗口,c#,.net,windows,winapi,transparency,C#,.net,Windows,Winapi,Transparency,我已经创建了一个半透明表单(60%不透明,背景颜色为黑色),我的应用程序可以在整个屏幕上最大化地启动。基本上,它在整个桌面上投射灰色 当用户将鼠标移到桌面上的某个窗口上时,我希望获得该窗口的句柄(hWnd) 对我来说,最简单的方法是: 暂时隐藏我的窗体(或暂时将窗体的不透明度设置为0.0) 致电[GetCursorPos][1] 致电[WindowFromPoint][2] 再次出示我的表格 这种方法的问题是我的表单/屏幕会闪烁,这是我不喜欢的。 我尝试用两种方法解决这个问题: 我想应该有一种
- 我想应该有一种方法可以通过调用(传入桌面的hWnd和
)直接在我的表单下面获取窗口的hWnd,但它似乎不起作用。我还玩了[ChildWindowFromPoint][4]和[RealChildWindowFromPoint][5],但没有成功。(P.S.Raymond Chen讨论了这些调用之间的差异,在我看来,ChildWindowFromPointEx的设计正是为了满足我的需要)CWP\u SKIPTRANSPARENT
- 我试图在隐藏表单之前使用(1)
和(2)SendMessage(GetDesktopWindow(),WM_SETREDRAW,false,0)
来阻止整个桌面刷新(有点“冻结”屏幕)。这并不完全正确:屏幕的某些区域会冻结,一些奇怪的黑色块会出现,等等。然而,我确实知道(1)确实有效,因为有一次我打电话(1)但没有打电话(2),我的桌面看起来完全冻结(不得不重新启动,甚至TaskMgr没有正确渲染)。我还尝试在我的表单上使用SuspendLayout和ResumeLayout,但我认为它们不适合处理我的情况SendMessage(GetDesktopWindow(),WM_SETREDRAW,true,0)
任何帮助都将不胜感激。您可以自己进行检查,因为您需要定制超出标准功能范围的功能
EnumWindows()
以获取顶级窗口的列表PtInRegion()
确定鼠标是否在窗口上方。移除所有不符合要求的窗户GetNextWindow()
,从剩余的一个窗口开始遍历z顺序,找出哪个候选项位于顶部因为我是一个新用户,不得不删除一堆有用的链接。那有点蹩脚。你是在找顶层窗口,还是需要子窗口?您希望如何处理遇到的半透明窗口?@David Heffernan是的,只查找顶级窗口(桌面的直接子窗口)。不完全确定,但EnumWindows甚至可能会枚举z顺序渲染(4)不必要。如果没有记录,那么你就不能依赖它behaviour@sertac我确实看过,但没有医生。不过我打赌你是对的。我认为获取所有顶级窗口列表的另一种方法是Process.getprocesss()。并检查.MainWindowTitle(如果它不是null或空白,我认为这意味着它是一个顶级窗口)和.MainWindowHandle