Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как отличить Рабочий стол от полноэкранного приложения  (Прочитано 19551 раз)
0 Пользователей и 6 Гостей смотрят эту тему.
CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« : 16-06-2009 16:13 » 

Я написал программу. Она создает скриншоты и "лепит" их на Рабочий стол в качестве обоев. При таком подходе программа должна делать скриншот только если в данный момент работает полноэкранное приложение. Я сделал так:

Код:
CWnd* pForegroundWindow=GetForegroundWindow();
if (!pForegroundWindow) continue;

// Определить размер этого окна вместе с элементами управления
CRect WindowRect;
pForegroundWindow->GetWindowRect(&WindowRect);

// Определить размер клиентской области этого окна
CRect ClientRect;
pForegroundWindow->GetClientRect(ClientRect);

// Сравнить размеры, если не совпадают - continue
if (WindowRect.Width() != ClientRect.Width() || WindowRect.Height() != ClientRect.Height()) continue;

Все хорошо, кроме одного - если нет открытых окон или все окна свернуты, скриншот создается. Следующее не помогло:

Код:
if (pForegroundWindow->m_hWnd == NULL) continue;
if (pForegroundWindow == GetDesktopWindow()) continue;
if (GetFocus() == GetDesktopWindow()) continue;

Вопрос такой. Каким способом можно отличить Рабочий стол от полноэкранного приложения? Или каким другим способом можно определить, что текущее окно является полноэкранным?
Записан
zubr
Гость
« Ответ #1 : 16-06-2009 17:02 » 

Определяй класс окна (GetClassName)
Цитата
#32768 The class for a menu.
#32769 The class for the desktop window.
#32770 The class for a dialog box.
#32771 The class for the task switch window.
#32772 Windows NT/Windows 2000/Windows XP: The class for icon titles.
Записан
CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 16-06-2009 18:52 » 

Не получается. Я сделал следующее:

Код:
CWnd* pForegroundWindow=GetForegroundWindow();
if (!pForegroundWindow) continue;

fstream file("log.txt", ios::out|ios::app);

char str[101]={0};
if (!GetClassName(pForegroundWindow->m_hWnd, str, 100))
{
    file << "!GetClassName..." << endl;
}

file << str << endl;

#32769 в файле log.txt не появилось ни разу. Что за черт?
Записан
CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 16-06-2009 18:54 » 

Для трея, для папок классы определяются, а Рабочего стола словно совсем нет. И ошибки нет и класса нет.
Записан
zubr
Гость
« Ответ #4 : 17-06-2009 03:45 » 

По идее GetShellWindow должен выдавать хендл рабочего стола. Также можно сделать GetWindow с параметром GW_HWNDLAST.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 17-06-2009 04:04 » new

Spy++ говорит, что класс рабочего стола - SysListView32
а заголовок окна - "FolderView"

(собственно белое поле любой папки имеет те же самые значения)
Записан

CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 17-06-2009 05:49 » 

Спасибо, я все это опробую, но дома. На работе у меня почему-то ничего полноэкранного не нашлось.

Еще такая просьба. Во вложении находится тестовая программа, которая показывает класс верхнего окна. У меня, если щелкнуть по Рабочему столу, она показывает "Progman". Это у меня WinXP SP2 стоит. А что покажет у вас?

* TestScreenShoter.zip (4.19 Кб - загружено 1118 раз.)
Записан
zubr
Гость
« Ответ #7 : 17-06-2009 06:35 » 

У меня тоже Progman, поэтому ориентироваться только по названию класса - ненадежно.
P.S. Кстати GetShellWindow или GetWindow( , GW_HWNDLAST) после GetClassName дают тот же результат - "Progman"
« Последнее редактирование: 17-06-2009 06:41 от zubr » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 17-06-2009 06:47 » 

а поискать дочерние окна у этого Progman попробуй ?


* progman and co.GIF (2.42 Кб - загружено 1871 раз.)
« Последнее редактирование: 17-06-2009 06:49 от Алексей1153++ » Записан

CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 17-06-2009 07:26 » 

в общем, я пришел вот к чему:

Код:
// Вытащить hwnd верхнего окна
CWnd* pForegroundWindow=GetForegroundWindow();
if (!pForegroundWindow) continue;

char ClassWnd[101]={0};
if (!GetClassName(pForegroundWindow->m_hWnd, ClassWnd, 100)) continue;

CString name;
pForegroundWindow->GetWindowText(name);

// Нельзя делать скриншот, активен Рабочий стол
if (name == "" || (CString)ClassWnd == "Progman") continue;

// Определить размер этого окна вместе с элементами управления
CRect WindowRect;
pForegroundWindow->GetWindowRect(&WindowRect);

// Определить размер клиентской области этого окна
CRect ClientRect;
pForegroundWindow->GetClientRect(ClientRect);

// Сравнить размеры, если не совпадают - continue
if (WindowRect.Width() != ClientRect.Width() || WindowRect.Height() != ClientRect.Height()) continue;

Нашел в DXSDK полноэкранную демку. Вроде работает. Сам ScreenShoter во вложении, если кому нужен - берите. Программа писалась вот для чего - создание скриншотов "вешается" на ту же кнопку, что и быстрое сохранение в игре. Тогда на Рабочем столе всегда будет картинка на момент выхода из игры. Да, скриншоты создаются в папке с программой.

* ScreenShoter.zip (21.31 Кб - загружено 1071 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 17-06-2009 07:40 » 

прикольно ))) Осталось продумать скрины для более чем 1 игр )
Записан

zubr
Гость
« Ответ #11 : 17-06-2009 09:09 » 

Цитата
создание скриншотов "вешается" на ту же кнопку, что и быстрое сохранение в игре
Исходя из этого, как я понимаю, игра твоя. Если это так, то вообще не понятно, зачем было такую бодягу с поиском окна разводить. Свое окно известно, сделал ему SetForegroundWindow, а затем скрин экрана.
Записан
CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 17-06-2009 09:57 » 

Исходя из этого, как я понимаю, игра твоя. Если это так, то вообще не понятно, зачем было такую бодягу с поиском окна разводить. Свое окно известно, сделал ему SetForegroundWindow, а затем скрин экрана.
Речь идет о ЛЮБОЙ игре.
Записан
CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 17-06-2009 13:20 » 

в общем я попробовал все, что под рукой было - NeverWinter Nights, Morrowind, Oblivion, Hitman.Blood Money, Gothic. Не сработало только в Готике.
Записан
zubr
Гость
« Ответ #14 : 17-06-2009 14:26 » 

Цитата
Речь идет о ЛЮБОЙ игре.
Тогда как кнопкой быстрого сохранения из игры (не твоей) будет вызываться скриншутер?
Записан
CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 17-06-2009 15:18 » 

Тогда как кнопкой быстрого сохранения из игры (не твоей) будет вызываться скриншутер?

А никак :ф) Он запускается отдельно, "висит" в трее и "ловит" нажатие соответствующей кнопки на клавиатуре.
Записан
zubr
Гость
« Ответ #16 : 17-06-2009 16:08 » 

Тогда вообще задача упрощается, точнее результат сужается до конкретных приложений, а не всех полноэкранных (ведь полноэкранной может быть не только игра, да и игра может быть не полноэкранной).
1. В хуке на клавишу определяешь из какого приложения нажата клавиша (полный путь к экзешнику).
2. Делаешь возможность в своей программе устанавливать приложения для скриншутера.
Записан
CTAPOBEP
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 17-06-2009 16:21 » 

1. В хуке на клавишу определяешь из какого приложения нажата клавиша (полный путь к экзешнику).
2. Делаешь возможность в своей программе устанавливать приложения для скриншутера.

Да, это тоже вариант, буду иметь в виду, спасибо :ф) Но, в принципе, меня вполне устраивает то, что есть.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines