如何识别已经枚举过的窗口?

问题描述 投票:0回答:2

我有一个用

EnumWindows
枚举窗口的进程。 EnumWindowsProc 创建一个长时间处理窗口句柄的线程。

主线程定期调用

EnumWindows
来检查是否有新的窗口需要枚举。我需要能够识别已经枚举的窗口,以便不会为那些已经枚举的窗口重新创建更多线程。

我刚刚更改了窗口的标题栏以识别之前枚举的窗口,但是一些后台窗口(例如 GDI+ 帮助程序窗口、用户会话帮助程序窗口)无法重命名,因此为它们创建线程会浪费内存每次

EnumWindows
通话。我可以对程序进行硬编码来识别这些名称,但这似乎并不理想。

有人可以告诉我是否有更好的方法来做到这一点?我不需要处理那些不可见的窗口,只需处理那些可见的窗口(例如任务栏上的窗口)。感谢您的阅读!

c++ winapi
2个回答
0
投票

您可以通过检查其

WS_VISIBLE
样式来过滤掉不可见的窗口:

if(GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE)
    ; // the window is visible

要确定是否已有线程处理该窗口,您可以保留已知窗口的哈希表:

std::unordered_set<HWND> S;

// when new window is found:
S.insert(hwnd);

// when done processing the window:
S.erase(hwnd);

// to check if the window is known:
if(S.find(hwnd) == S.end())
    ; // the window is not in the set

窗口句柄是系统全局的,在窗口的生命周期内不会改变。然而,如果窗口被创建和销毁,它们最终可能会被重用——但据我所知,没有办法解决这个问题。


0
投票

主线程定期调用EnumWindows来检查是否有新的窗口需要枚举。

我建议使用

SetWindowsHookEx()
来检测何时创建新窗口。

我刚刚更改了窗口的标题栏以识别之前已枚举的窗口。

一种侵入性较小的方法可能是使用

SetProp()
在每个窗口内存储自定义标记,然后您可以稍后查找该标记。在销毁每个窗口之前,您必须在每个窗口上调用
RemoveProp()
,但您也可以使用钩子来实现这一点。

或者,您可以简单地将每个

HWND
存储在您自己的列表中,然后在添加任何新的
HWND
之前检查该列表。您仍然需要使用钩子来检测每个
HWND
何时被销毁,以便您可以将其从列表中删除。

© www.soinside.com 2019 - 2024. All rights reserved.