【问题标题】:Find the Handle of the window at the top of the screen在屏幕顶部找到窗口的句柄
【发布时间】:2012-08-25 21:10:41
【问题描述】:

我想检查外部应用程序(在线扑克游戏桌)的窗口何时跳过所有其他窗口,因为轮到我玩了。

问题是游戏桌在前台跳转...但是窗口没有变为活动状态...这意味着我无法检查它是否通过 API GetForegroundWindow (并且在 fatc 中,此 API 继续返回前一个窗口的句柄,如果它位于跳过所有桌面窗口的游戏桌下)。 GetTopWindow API 也不起作用。

现在的问题是:如果顶部 VISIBLE 窗口(对我的眼睛来说在所有其他打开的窗口之上的窗口)不活动,如何找到它的句柄???


不,该窗口不是 TopMost 窗口:事实上,如果我单击另一个窗口,它会进入后台。如果它应该是 TopMost 窗口,它将保持在顶部。

可能它被 WM_SHOW 或 WM_NOACTIVATE 标志置于前台。

【问题讨论】:

标签: vb.net winapi topmost


【解决方案1】:

EnumWindows 和可能的 WindowFromPoint API 函数。您可以在 VB.NET 应用程序中通过 P/Invoke 使用它们,并且能够以从上到下的顺序 (EnumWindows) 查找窗口,在识别您感兴趣的窗口的过程中检查它们的位置、标题等,或者直接定位特定位置的窗口(WindowFromPoint;我认为您感兴趣的窗口可能会在屏幕中心弹出,或者以您已经知道的另一个窗口为中心,或者您可以通过其标题轻松找到它 - 这样您就知道您的点已经对屏幕感兴趣了)。

【讨论】:

  • Ty Roman,但您的想法在这种情况下不起作用。是的,这是真的:通过 EnumWindows,我可以按从上到下的顺序获取 Windows 句柄......但是当游戏表在前台跳转时,窗口未激活,因此 z 顺序不会改变。如果我将(例如)记事本放在桌子上,当桌子跳到前台时,第一个句柄总是记事本句柄,因为记事本仍然是活动窗口。
  • WindowFromPoint.... 我在屏幕的不同位置有 6-8 个表格。我将不得不通过 WindowRect 来检查它们的位置,并检查每个标签的 5-6 个点,以确保它位于顶部...我会尝试,但我担心 WindowFromPoint API 会在该点下找到活动窗口的句柄。
  • WindowFromPoint 函数不会检索隐藏或禁用窗口的句柄,即使该点位于窗口内。 DISABLED WINDOW:一个不接收输入的窗口,例如鼠标点击和按键......并且在前台跳转时的表不接收输入,因为它没有激活。
  • WindowFromPoint 是函数家族之一(最简单)。 ChildWindowFromPointEx 也会禁用、不可见和透明的窗口。
  • 是的,我已经看到了,你……但还有另一个原因,因为我不能使用 WindowFromPoint 系列 API。如果有人有一个大显示器并打开 4 张游戏桌而没有将一张放在另一张...我不知道 4 张桌子中的一张是否需要行动,因为 ChildWindowFromPoint “看到”屏幕顶部的所有桌子,没有任何重叠...
【解决方案2】:

听起来该应用可能正在使用SetWindowPos(..., HWND_TOPMOST, ...) 成为最顶层的窗口。以这种方式定位的窗口不必处于活动状态即可显示在顶部。

在这种情况下,您可以尝试使用GetWindow(..., GW_HWNDFIRST) 在窗口管理器的 z 顺序中查找最顶层的窗口。请参阅http://support.microsoft.com/kb/126386 了解执行此操作的短代码 sn-p。

【讨论】:

  • 我在找那篇知识库文章!你什么时候知道when 打电话给它?我想你会手动获取窗口句柄,然后在从 API 调用返回句柄时进行持续轮询,你知道扑克应用程序在上面吗?
  • 不,该窗口不是 TopMost 窗口。
  • 一个未激活的窗口永远不会在 z 顺序中排在第一位,如果它是 FOR THE EYES 顶部窗口也是如此... Z 顺序中的第一个窗口是接收输入的窗口(前景窗口)。
【解决方案3】:

扑克应用程序必须使用 Win32 API(例如 SetForegroundWindow(hWnd))在轮到您时将窗口置于顶部。

为了检测这样的呼叫,您可以使用Windbg Script Tracing API calls

您可以使用它从您的 Windbg 屏幕无需使用其他工具。如果您需要更多详细信息 从 API 中,只需执行 LogViewer.exe 并打开 .lgv 文件 使用此脚本时会自动创建。

输出文件,扩展名为 .LGV。

LogViewer.exe 是 Windows 调试工具的一部分。它与您安装 Windbg 的位置相同。使用 LogViewer.exe 打开 .LGV 文件:

API_TRACING.TXT 的源代码:

$$
$$ =============================================================================
$$ Trace APIs during the Debugging Session. 
$$ Creates a log on Desktop and Windbg window.
$$ To see the more verbose log run logviewer.exe from Debugging Tools for Windows
$$ and open the file that has the .lgv extension.
$$ This file is inside LogExts on your desktop.
$$
$$ Compatibility: Win32, should work on Win64.
$$
$$ Usage: $$>< to run the program.
$$
$$ Roberto Alexis Farah
$$ Blog: blogs.msdn.com/debuggingtoolbox/
$$
$$ All my scripts are provided "AS IS" with no warranties, and confer no rights.
$$ =============================================================================
$$
!logexts.loge
!logexts.logc e *
!logexts.logo e v
!logexts.logb p
$$
$$ ====================================
$$ Logging is enabled for this process.
$$ ====================================

一旦你掌握了所有这些信息,你就会知道要从特定的调用者/DLL/等中寻找什么 API 调用,并且轮到你了,扑克窗口就在顶部,并且你可以使用这篇知识库文章Find the Handle of the TopMost Window

【讨论】:

  • >一旦您掌握了所有这些信息,您就会知道要从特定的调用者/DLL/等处寻找哪些 API 调用,这就是轮到您的时候了……如何检查? ???通过dll注入???我不知道如何进行 dll 注入>查找 TopMost 窗口的句柄.....它不是 TopMost 窗口!
  • 冷静下来。用所有的问号和大写字母冷静一下,好吗?在代码中,您需要轮询日志和调试器以识别扑克应用程序调用的 Win32 API 事件。如果您在这里需要帮助,请善待那些自愿帮助您的人
  • 不好?抱歉...我的原始语言不是英语,我会尽力而为。
猜你喜欢
  • 2013-06-16
  • 1970-01-01
  • 2010-12-06
  • 2017-08-24
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
相关资源
最近更新 更多