Как отличить интерактивные окна пользовательских приложений от неинтерактивных?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как отличить интерактивные окна пользовательских приложений от неинтерактивных?

Сообщение Anonymous »

Эта программа для Windows должна представлять собой небольшую терминальную утилиту, которая аккуратно складывает окна работающего приложения.
Пользователь передает имя исполняемого приложения, которое он хочет выполнить. Для этого программа ищет вероятные процессы с именами исполняемых файлов, которые точно соответствуют вводу пользователя. Пользователь подтверждает выбранное приложение, когда его спрашивают, и программа объединяет эти окна (не уделяя им фокуса).
Проблема
Проблема этой программы в том, что она отображает и объединяет ВСЕ окна приложения, включая те, с которыми пользователь не должен взаимодействовать (иногда они скрыты при запуске приложения). Это вызывает проблемы с рабочим столом, и я не знаю, как отличить окна, обращенные к пользователю, от других окон. Существует ли набор флагов свойств, которые обычно используют обычные окна, и которые мне нужно проверить?
См. изображение ниже. Эти окна не являются интерактивными, как обычные окна, и обладают странными свойствами.
Прошу прощения за длину кода, но он скомпилируется в среде Windows.
Изображение

// C++ standard library
#include
#include
#include
#include
#include
#include
#include
#include

// Windows API
#include

// Windows API helpers
#include

/**
* @brief Takes a snapshot of all processes in the system and returns a vector containing each process entry.
*
*/
static std::vector getAllProcesses( ) {
// Take the snapshot.
HANDLE snapshotHandle = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); // @Todo Handle errors.
assert( snapshotHandle != INVALID_HANDLE_VALUE );

// Get all the processes in the snapshot.
PROCESSENTRY32 processEntry;
processEntry.dwSize = sizeof( PROCESSENTRY32 ); // Must initialize this member before iterating.
bool noErrors = Process32First( snapshotHandle, &processEntry ); // @Todo Handle errors.
assert( noErrors ); // For now, assume this always succeeds the first time.
std::vector result;
result.push_back( processEntry ); // Append the first process entry.
// Query for the next process entry.
DWORD errorCode = ERROR_SUCCESS;
if ( !Process32Next( snapshotHandle, &processEntry ) ) {
errorCode = GetLastError( );
}
while ( errorCode != ERROR_NO_MORE_FILES ) {
result.push_back( processEntry );
errorCode = ERROR_SUCCESS;
if ( !Process32Next( snapshotHandle, &processEntry ) ) {
errorCode = GetLastError( );
}
}

CloseHandle( snapshotHandle );
return result;
}

/**
* @brief Returns the name of the executable file for a process.
*
*/
static std::wstring getProcessName( PROCESSENTRY32 const& p ) {
std::wstring result;
size_t const nameLength = wcslen( p.szExeFile );
for ( size_t i = 0; i < nameLength; ++i ) {
result.push_back( p.szExeFile );
}
return result;
}

/**
* @brief Returns the ID of the process that opened a given window.
*
*/
static DWORD getWindowProcessID( HWND windowHandle ) {
DWORD processID = 0;
DWORD threadID = GetWindowThreadProcessId( windowHandle, &processID );
if ( threadID == 0 ) {
std::abort( );
}
return processID;
}

/**
* @brief Determines whether a given window was opened by a given process.
*
* @return true if the process opened the window.
* @return false if the process did not open the window.
*/
static bool windowOpenedByProcess( HWND windowHandle, DWORD processID ) {
return getWindowProcessID( windowHandle ) == processID;
}

/**
* @brief Returns a vector containing the IDs of the given processes.
*
*/
static std::vector getProcessIDs( std::vector const& processes ) {
std::vector ids;
for ( const PROCESSENTRY32& i : processes ) {
ids.push_back( i.th32ProcessID );
}
return ids;
}

/**
* @brief Determines whether a given window was opened by any of the given processes.
*
* @return true if the window was opened by one of the processes.
* @return false if the window was not opened by any of the processes.
*/
static bool windowOpenedByProcessAnyOf( HWND windowHandle, std::vector const& processes ) {
std::vector processIDs = getProcessIDs( processes );
for ( const DWORD& i : processIDs ) {
if ( windowOpenedByProcess( windowHandle, i ) ) {
return true;
}
}
return false;
}

/**
* @brief Returns a string where all alphabetic characters in the given string have been demoted to lowercase.
*
*/
template Container toLower( Container const& c ) {
Container result;
for ( Element const& e : c ) {
if ( isalpha( e ) ) {
int const lowerAsInt = tolower( e );
// assert((lowerAsInt >= CHAR_MIN) && (lowerAsInt 0; --count ) {
std::wstring processName = toLower( getProcessName( processes.at( i ) ) );
size_t foundAt = processName.find( searching );
if ( foundAt != std::wstring::npos ) {
++i; // Found a loose match. Move on to the next one.
} else {
processes.erase( processes.begin( ) + i ); // No match. Remove this one.
}
}
}

/**
* @brief Takes a vector of processes and removes the ones whose executable name does not exactly match the filtering
* key.
*
*/
static void filterProcessesNotMatchingName( std::vector& processes, std::wstring const& searchFor ) {
size_t count = processes.size( );
for ( size_t i = 0; count > 0; --count ) {
if ( getProcessName( processes.at( i ) ) == searchFor ) {
++i;
} else {
processes.erase( processes.begin( ) + i );
}
}
}

/**
* @brief Returns a vector containing the executable names of all given processes.
*
*/
static std::vector getProcessNames( std::vector const& allProcesses ) {
std::vector result;
for ( PROCESSENTRY32 const& i : allProcesses ) {
result.push_back( getProcessName( i ) );
}
return result;
}

/**
* @brief Converts a narrow string to a wide string.
*
*/
static inline std::wstring narrowToWideString( std::string const& as ) {
// deal with trivial case of empty string
if ( as.empty( ) )
return std::wstring( );

// determine required length of new string
size_t reqLength = ::MultiByteToWideChar( CP_UTF8, 0, as.c_str( ), ( int )as.length( ), 0, 0 );

// construct new string of required length
std::wstring ret( reqLength, L'\0' );

// convert old string to new string
::MultiByteToWideChar( CP_UTF8, 0, as.c_str( ), ( int )as.length( ), &ret[0], ( int )ret.length( ) );

// return new string ( compiler should optimize this away )
return ret;
}

/**
* @brief Prints a container type as a numbered list to standard output.
*
*/
static void printNumberedList( std::set const& container ) {
int n = 1;
for ( auto const& i : container ) {
std::wcout

Подробнее здесь: https://stackoverflow.com/questions/791 ... nteractive
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»