Как я могу получить все, что в настоящее время отображается на экране окон?C++

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

Сообщение Anonymous »

Я пишу приложение на C#, которое работает с окнами, и в нем мне нужно иметь возможность получать ВСЕ окна, которые видны и на экране.
Вместо того, чтобы просто получать активное или переднее окно, мне конкретно нужно каждое окно, которое пользователь может видеть на своем экране.
Для ясности и простоты использования я также использую Библиотека DataDink WindowScrape в качестве оболочки для User32, но она предоставляет только полезные функции и удобство чтения.
Вот все основные, которые я пробовал до сих пор, но безуспешно:
IsWindowVisible() из темы «Как проверить, имеет ли окно установленный WS_VISIBLE? (или является ли видимым)».

Код: Выделить всё

    // EnumHwnds wrapper that returns a list of WindowObjects
List windows = Window.GetWindows();

foreach (Window window in windows)
{
// Gets hwnd from window object
IntPtr hWnd = window.Hwnd;
bool isVisible = IsWindowVisible(hWnd);

if (isVisible){
Console.WriteLine(window);
}
}
Использование isWindowVisible на самом деле не возвращает истинную видимость окна, оно возвращается только в том случае, если для окна или любого из его родителей установлен WS_VISIBLE. Судя по моим выводам, он также игнорирует перекрытие и возвращает каждое видимое окно независимо от его видимости на экране.
GetWindowLong(), затем IsWindowVisible() from ветку выше.

Код: Выделить всё

    private const int GWL_STYLE = -16;
...
...
// EnumHwnds wrapper that returns a list of WindowObjects
List windows = Window.GetWindows();

foreach (Window window in windows)
{
// Gets hwnd from window object
IntPtr hWnd = GetWindowLong(window.Hwnd, GWL_STYLE);
bool isVisible = IsWindowVisible(hWnd);

if (isVisible){
GD.Print(window);
}
}
Я также попытался получить окно с помощью getWindowLong из-за комментария Jewel S. По какой-то причине приведенный выше код у меня вообще не работал и всегда возвращал false. Даже если бы мне удалось заставить его работать, это решило бы только проблему видимости родительского/дочернего элемента, а не проблему перекрытия окон.
Рассмотрение маскировки окон из статьи Рэймонда Чена

Код: Выделить всё

static bool IsWindowCloaked(IntPtr hwnd)
{
bool isCloaked = false;
int result = DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, out isCloaked, sizeof(bool));
return (result == S_OK) && isCloaked;
}

static bool IsWindowVisibleOnScreen(IntPtr hwnd)
{
return IsWindowVisible(hwnd) && !IsWindowCloaked(hwnd);
}

...
...

// EnumHwnds wrapper that returns a list of WindowObjects
List windows = Window.GetWindows();

foreach (Window window in windows)
{
// Gets hwnd from window object
IntPtr hWnd = GetWindowLong(window.Hwnd, GWL_STYLE);
bool isVisible = IsWindowVisibleOnScreen(hWnd);

if (isVisible){
GD.Print(window);
}
}
Вероятно, это было самое многообещающее решение на данный момент, но, к сожалению, оно не решило мою проблему. хотя маскировка окон действительно помогает устранить некоторые окна, она не учитывает ранее упомянутые проблемы (отношения дочерних/родительских окон и перекрытие окон).
Вкратце
Вкратце
Я хочу, чтобы все окна, которые пользователь может физически видеть на своем экране. Я хочу игнорировать окна, закрытые другим (то есть невидимые для пользователя), и принимать окна, которые частично открыты.
До сих пор я использовал библиотеку User32, но У меня не очень большой опыт работы с C# и я возился с библиотеками Windows, поэтому готов признать, что это может быть не решение.
Я также готов переписать это на C++ если это более жизнеспособно.
ПРИМЕЧАНИЕ
. Этот пост отмечен тегами C#, C и C++, поскольку, насколько мне известно, эту библиотеку можно использовать на всех трех языках, и решение на любом из этих языков было бы полезно.

Подробнее здесь: https://stackoverflow.com/questions/782 ... en-windows
Ответить

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

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

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

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

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