C++ 如何让 EnumWindows 列出所有窗口?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10246444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:47:23  来源:igfitidea点击:

How can I get EnumWindows to list all windows?

c++windowswinapi

提问by Der Hochstapler

I'm assuming, what I'm asking should actually be the default, but I'm experiencing some behavior I don't understand.

我假设,我要问的实际上应该是默认值,但是我遇到了一些我不明白的行为。

#include "stdafx.h"

using namespace std;

BOOL CALLBACK enumWindowsProc(
  __in  HWND hWnd,
  __in  LPARAM lParam
) {
  if( !::IsIconic( hWnd ) ) {
    return TRUE;
  }

  int length = ::GetWindowTextLength( hWnd );
  if( 0 == length ) return TRUE;

  TCHAR* buffer;
  buffer = new TCHAR[ length + 1 ];
  memset( buffer, 0, ( length + 1 ) * sizeof( TCHAR ) );

  GetWindowText( hWnd, buffer, length + 1 );
  tstring windowTitle = tstring( buffer );
  delete[] buffer;

  wcout << hWnd << TEXT( ": " ) << windowTitle << std::endl;

  return TRUE;
}

int _tmain( int argc, _TCHAR* argv[] ) {
  wcout << TEXT( "Enumerating Windows..." ) << endl;
  BOOL enumeratingWindowsSucceeded = ::EnumWindows( enumWindowsProc, NULL );
  cin.get();
  return 0;
}

If I invoke that code, it will list all minimized windows: enter image description here

如果我调用该代码,它将列出所有最小化的窗口: 在此处输入图片说明

Now, I'm no longer interested in only the minimized windows, now I want all of them. So I remove the IsIconiccheck:

现在,我不再只对最小化的窗口感兴趣,现在我想要所有这些。所以我删除了IsIconic支票:

BOOL CALLBACK enumWindowsProc(
  __in  HWND hWnd,
  __in  LPARAM lParam
) {
  /*
  if( !::IsIconic( hWnd ) ) {
    return TRUE;
  }
  */

  int length = ::GetWindowTextLength( hWnd );
  if( 0 == length ) return TRUE;

  TCHAR* buffer;
  buffer = new TCHAR[ length + 1 ];
  memset( buffer, 0, ( length + 1 ) * sizeof( TCHAR ) );

  GetWindowText( hWnd, buffer, length + 1 );
  tstring windowTitle = tstring( buffer );
  delete[] buffer;

  wcout << hWnd << TEXT( ": " ) << windowTitle << std::endl;

  return TRUE;
}

Now I get all windows exceptthe minimized ones (none of the previously listed window handles are listed this time): enter image description here

现在我得到了最小化窗口之外的所有窗口这次没有列出之前列出的窗口句柄): 在此处输入图片说明

For completeness, this is the stdafx.h:

为了完整起见,这是stdafx.h

#pragma once

#include "targetver.h"


#include <iostream>
#include <map>
#include <string>

namespace std {
  #if defined _UNICODE || defined UNICODE
    typedef wstring tstring;
  #else
    typedef string tstring;
  #endif
}

#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <psapi.h>

What am I doing wrong?

我究竟做错了什么?

采纳答案by Der Hochstapler

It's (as I assumed) not a problem with EnumWindowsat all. The problem is with the output stream.

这(正如我所假设的)根本不是问题EnumWindows。问题在于输出流。

While debugging, I noticed that enumWindowsProcis called just fine for every window, but that some iterations are simply not generating output.

在调试时,我注意到enumWindowsProc对于每个窗口都可以很好地调用它,但是有些迭代根本没有生成输出。

For the time being, I switched to using _tprintf, but I don't understand what the problem with the original code is. Calling wcout.flush()had no desirable effect either.

暂时改用了_tprintf,但是不明白原代码有什么问题。呼叫wcout.flush()也没有理想的效果。

回答by FrogTheFrog

Well, wcout.flush()never works, however wcout.clear()fixes your code, at least for me.

好吧,wcout.flush()永远不会奏效,但是wcout.clear()修复了您的代码,至少对我而言。

wcout << hWnd << TEXT( ": " ) << windowTitle << std::endl;
wcout.clear();
return TRUE;

And I know that this question is already one year old, however it's never too late to answer.

而且我知道这个问题已经有一年了,但是回答永远不会太晚。

回答by Stevoisiak

Here is a callback function that lists all open windows:

这是一个回调函数,列出所有打开的窗口:

#include <string>
#include <iostream>
#include <Windows.h>

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) {
        std::cout << hWnd << ":  " << windowTitle << std::endl;
    }
    return TRUE;
}

int main() {
    std::cout << "Enmumerating windows..." << std::endl;
    EnumWindows(enumWindowCallback, NULL);
    std::cin.ignore();
    return 0;
}

If you want to check if the window is minimized, you can use IsIconic().

如果要检查窗口是否最小化,可以使用IsIconic().

See Also:

也可以看看:

回答by user8988827

Documentation of Windows (dunno its accuracy) says that EnumWindows only enumerates top level windows. If you wish to enumerate child windows, you need to use EnumChildWindows function where you have to pass handle of parent window

Windows 的文档(不知道它的准确性)说 EnumWindows 只枚举顶级窗口。如果你想枚举子窗口,你需要使用 EnumChildWindows 函数,你必须传递父窗口的句柄