在VC ++中,我使用EnumWindows(...),GetWindow(...)和GetWindowLong()来获取窗口列表并检查窗口是否是顶窗(没有其他窗口作为所有者),以及窗口是否可见(WS_VISIBLE)。然而,虽然我的桌面只显示了5个窗口,但这个EnumWindows给了我50个窗口,多么有趣!任何Windows极客请帮我澄清......
答案 0 :(得分:30)
Raymond在MSDN博客上的这篇文章中描述了仅列出任务栏中的窗口(或类似地在Alt-Tab框中)的方法:
http://blogs.msdn.com/b/oldnewthing/archive/2007/10/08/5351207.aspx
这是检查窗口是否显示在alt-tab中的超级函数:
BOOL IsAltTabWindow(HWND hwnd)
{
TITLEBARINFO ti;
HWND hwndTry, hwndWalk = NULL;
if(!IsWindowVisible(hwnd))
return FALSE;
hwndTry = GetAncestor(hwnd, GA_ROOTOWNER);
while(hwndTry != hwndWalk)
{
hwndWalk = hwndTry;
hwndTry = GetLastActivePopup(hwndWalk);
if(IsWindowVisible(hwndTry))
break;
}
if(hwndWalk != hwnd)
return FALSE;
// the following removes some task tray programs and "Program Manager"
ti.cbSize = sizeof(ti);
GetTitleBarInfo(hwnd, &ti);
if(ti.rgstate[0] & STATE_SYSTEM_INVISIBLE)
return FALSE;
// Tool windows should not be displayed either, these do not appear in the
// task bar.
if(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
return FALSE;
return TRUE;
}
答案 1 :(得分:4)
您正在谈论的窗口,X按钮和标题栏等不是唯一的窗口。按钮,下拉菜单,标签,图标,文本框,任务栏以及其他所有内容都是一个窗口 1 。所以EnumWindows
正在做它应该做的事情:枚举所有顶级窗口。
1 即使这是真的,EnumWindows
也只列举顶级窗口。这意味着it won't enumerate any child windows:
EnumWindows函数不会枚举子窗口,但系统拥有的具有WS_CHILD样式的几个顶级窗口除外。
然而,桌面上的许多东西都是窗户,而不仅仅是你正在考虑的“窗户”。
答案 2 :(得分:0)
@jondinham 提供的 answer 非常适合我。所以我想出了自己的解决方案。
1.我在之前的解决方案中遇到的问题
在 Windows 10 家庭版 1909 上运行,我得到两个额外的意外 Windows“计算器”和“设置”。
另外,无法检测到Tencent QQ的窗口,因为以下失败:
// the following removes some task tray programs and "Program Manager"
ti.cbSize = sizeof(ti);
GetTitleBarInfo(hwnd, &ti);
if(ti.rgstate[0] & STATE_SYSTEM_INVISIBLE)
return FALSE;
不过我觉得这个bug可能是腾讯QQ的特殊性导致的,我连DeferWindowPos的窗口都做不出来。
也许有人可以帮我弄清楚为什么会发生这种情况,并帮助改进@jondinham 之前的解决方案。
2.我的解决方案
我试图检查窗口的图标,并过滤掉没有自己图标或使用与系统默认图标相同的图标的窗口。我使用来自 answer 和 answer 的代码片段并进行了一些修改。这个解决方案对我来说非常有效。
HICON get_windows_HICON_critical(HWND hwnd)
{
// Get the window icon
HICON icon = reinterpret_cast<HICON>(::SendMessageW(hwnd, WM_GETICON, ICON_SMALL, 0));
if (icon == 0) {
// Alternative method. Get from the window class
icon = reinterpret_cast<HICON>(::GetClassLongPtrW(hwnd, GCLP_HICONSM));
}
// Alternative method: get the first icon from the main module (executable image of the process)
if (icon == 0) {
icon = ::LoadIcon(GetModuleHandleW(0), MAKEINTRESOURCE(0));
}
// // Alternative method. Use OS default icon
// if (icon == 0) {
// icon = ::LoadIcon(0, IDI_APPLICATION);
// }
if(icon == ::LoadIcon(0, IDI_APPLICATION)){
// Filter out those with default icons
icon = 0;
}
return icon;
}
static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
int length = GetWindowTextLength(hWnd);
char* buffer = new char[length + 1];
GetWindowText(hWnd, buffer, length + 1);
std::string windowTitle(buffer);
// List visible windows with a non-empty title
if (IsWindowVisible(hWnd) && length != 0) {
HICON icon = get_windows_HICON_critical(hWnd);
if(icon!=0){
std::cout << hWnd << ": " << windowTitle << std::endl;
}
}
return TRUE;
}
3.我的解决方案的问题
根据this question,我的解决方案无法处理Windows Store APP。