Как я могу получить EnumWindows для списка всех окон?

Я предполагаю, что то, что я прошу, должно быть по умолчанию, но я испытываю некоторое поведение, которое я не понимаю.

#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;
}

если я вызову этот код, он отобразит все свернутые окна: enter image description here

теперь меня больше не интересуют только свернутые окна, теперь я хочу их все. Поэтому я удаляю 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;
}

теперь я получаю все окна за исключением свернутые (ни один из ранее перечисленных дескрипторов окна перечислены на этот раз): enter image description here

для полноты, это 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>

что я делаю не так?

4 ответов


Ну wcout.flush() не работает, однако wcout.clear() исправления кода, по крайней мере для меня.

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

и я знаю, что этому вопросу уже год, однако никогда не поздно ответить.


это (как я предполагал) не проблема с EnumWindows на всех. Проблема заключается в выходном потоке.

во время отладки, я заметил, что enumWindowsProc называется просто отлично для каждого окна, но что некоторые итерации просто не генерируют выходные данные.

на данный момент я переключился на использование _tprintf, но я не понимаю, в чем проблема с исходным кодом. Зову wcout.flush() также не имело желаемого эффекта.


вот переписал функцию обратного вызова, которая перечисляет все открытые окна:

#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);

    // Ignore windows if invisible or missing a 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;
}

Если вы хотите проверить, свернуто ли окно, вы можете использовать IsIconic().

Читайте Также:


документация Windows (не знаю ее точности) говорит, что EnumWindows перечисляет только окна верхнего уровня. Если вы хотите перечислить дочерние окна, вам нужно использовать функцию EnumChildWindows, где вы должны передать дескриптор родительского окна