Axenic
Гость
|
|
« : 15-02-2010 18:33 » |
|
Проблема в следующем GDI+ делает снимок экрана когда попало, и очень часто бывает, что кадр ещё полностью не отрендился, а снимок экрана уже делается, из-за чего не все эелементы окна попадают в кадр. Fraps делает снимки как надо и так понял он использует для снятие скриншотов технологию DirectX. Я ничего не понимаю в DirectX и мне не сильно хочется тратить 2-3 месяца на его изучение чтобы узнать написать только одну функцию. Для моего проекта мне вполне хватает GDI+ который я по мере продвижения подучиваю. Если у кого-нибудь есть функция, которая делает снимок игры в полноэкранном режиме и записывает это все в Bitmap, то выложите пожалусто. И если у Вас её нет, но вы знаете как просто её написать, тоже выложите
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #1 : 16-02-2010 13:35 » |
|
Задача однозначно не в одну функцию. Тебе надо получить HDC оверлея, а для этого надо получить доступ к интерфейсу IDirectDraw процесса, осуществляющего вывод видеопотока через DirectX. Если это твой процесс то задача решается просто, иначе надо перехватывать API-функцию DirectDrawCreate. Ну и еще вариант - видео-драйвер-фильтр.
|
|
|
Записан
|
|
|
|
Axenic
Гость
|
|
« Ответ #2 : 16-02-2010 18:26 » |
|
Загрузил
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 09-03-2011 21:11 » |
|
Задача однозначно не в одну функцию. Тебе надо получить HDC оверлея, а для этого надо получить доступ к интерфейсу IDirectDraw процесса, осуществляющего вывод видеопотока через DirectX. Если это твой процесс то задача решается просто, иначе надо перехватывать API-функцию DirectDrawCreate. Ну и еще вариант - видео-драйвер-фильтр.
о, я так понимаю, это то, что мне сейчас надо ) А как такой перехват функции DirectDrawCreate делается ?
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #4 : 10-03-2011 07:49 » |
|
Алексей1153++, есть множество способов перехвата API-функций (подмена адреса перехватываемой функции в библиотеке, подмена адреса функции в адресном пространстве процесса, использование DebugApi), также есть несколько способов внедрения в адресное пространство чужого процесса (хук, CreateRemoteThread). Все это с примерами есть на wasm.ru. Также у Рихтера есть примеры. Правда во всех этих способах есть особенности, связанные с админскими правами, битностью системы (x86, x64).
Добавлено через 6 минут и 46 секунд: Также надо будет и DirectDrawCreateEx перехватывать. С точки зрения простоты, то проще миррор-видеодрайвер замутить, просто пример из DDK скомпилировать и установить, но тормоза при этом ощутимые, да и полномочия нужны админские при установке + перезагрузка системы.
|
|
« Последнее редактирование: 10-03-2011 07:56 от zubr »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 10-03-2011 09:36 » |
|
zubr, да, я уже понял, что это не то немного ) Вечером поизучаю, как до поверхности (surface) десктопа добраться
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #6 : 10-03-2011 12:27 » |
|
Алексей1153++, если там DirectX, то других вариантов нет.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #7 : 11-03-2011 17:43 » |
|
так, что-то я запутался, с чего начинать. Всё-таки перехватить функцию DirectDrawCreateEx надо сначала ? Или же при помощи DX API можно прямо как-то с видеопамяти весь текущий битмап вытащить ?
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #8 : 11-03-2011 18:44 » |
|
Насколько я помню, интерфейсы DirectX не предоставляют методов для возможности перехватывать чужой видеопоток. Поэтому остаются менее документированные способы перехвата. Перехватив DirectDrawCreateEx и DirectDrawCreate мы можем получить указатель на объект IDirectDraw, а у этого интерфейса есть метод получения указателя на объект IDirectDrawSurface. В свою очередь у объекта IDirectDrawSurface есть метод GetDC. Получив контекст видеопотока с ним можно работать как с обычным контекстом монитора.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #9 : 11-03-2011 18:53 » |
|
ок, спасибо. А перехват надо в отдельной DLL делать, я правильно понимаю ? И ещё - как определить, что поверхность принадлежит именно десктопу? Или там у них нет различий - поверхность всегда одна и та же?
Никогда перехваты не делал, никак не могу мозги направить в нужное русло...
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #10 : 11-03-2011 19:37 » |
|
Почему только декстоп? А если юзер открыл винамп с фильмом, здесь не декстоп, но на рабочем столе видео присутствует. По логике любое приложение, использующее DirectX, чтобы получить объект IDirectDraw, использует DirectDrawCreateEx или DirectDrawCreate. Определить можно имя процесса в котором произошло обращение к вышеуказанным функциям. Для перехвата надо внедряться в адресное пространство чужого процесса, а для этого можно использовать глобальный хук (dll), также можно делать инжект в внедряемый процесс, тут тоже удобнее всего, чтобы внедряемый код был в виде dll. Можно перехватывать, вообще не внедряясь в чужой процесс, для этого можно использовать DebugApi, тогда твой код перехвата может находиться в потоке основного приложения, причем для каждого перехватываемого процесса надо будет соответственно создавать отладочный поток в основном приложении. У каждого из способов перехвата есть свои преимущества и недостатки, трудно сказать, какой из них лучше.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #11 : 11-03-2011 21:01 » |
|
Самым привлекательным по описанию для меня показался этот способ Можно перехватывать, вообще не внедряясь в чужой процесс, для этого можно использовать DebugApi, тогда твой код перехвата может находиться в потоке основного приложения, причем для каждого перехватываемого процесса надо будет соответственно создавать отладочный поток в основном приложении. попробую разобраться
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #12 : 11-03-2011 22:33 » |
|
Недостатки этого метода: 1. Требуются админские полномочия, про UAC не знаю, не проверял, возможно будет выскакивать. 2. Зачастую разработчики ПО защищают свои проги от отладки, в этом случае будет облом, хотя при определенных извращениях защиту можно обойти (на хитрую ж..пу есть хрен с винтом, а на хр. с винтом есть ж..па с закоулками). 3. Если понадобится отключиться от отлаживаемого процесса, то это надо делать корректно, иначе можно убить отлаживаемый процесс.
|
|
|
Записан
|
|
|
|
|