• 0
Pax Beach

Снимок экрана в полноэкранном приложении DirectX

Вопросы

Мне нужно сделать снимок экрана из своего приложения в приложении DirectX (в игре).

По-быстрому накидал приложение, исходники здесь: MakeScreenshot-Forum.zip

screen.jpg.ee04f8b3fb65b38a05dcabf7a6ad22ef.jpg

1. по нажатию единственной кнопки будет выполнена серия из 16 снимков экрана. Если запущен Скайп, то фотографироваться будет содержимое его окна.

2. По нажатии CTRL+ALT+F9 будет сделан единичный снимок

3. Label внизу показывает сколько миллисекунд затрачено на вывод снимка

4. В комментах так же вы найдете, как работать со снимками через буфер обмена.

 

Работа выполняется через GetDC(NULL);

Windows 10 x64. Снимки делаются. И DirectX тоже нормально фотографируется.

НО! только в оконных приложениях.

Если приложение DirectX полноэкранное, то на всех снимках одна и та же картинка с первого снимка.
То есть изменение буфера экрана в приложении ни как не отражается на снимках.

 

Что нужно? Необходимо делать снимки конкретного приложения через интерфейс DirectX, а точнее, я так понимаю, через DirectShow. Тогда не будет разницы в окне оно или на полный экран.

Помогите плиз, знающие люди, с решением этой задачи.

Гарантирую вам от сообщества большой почет, от меня огромный респект, если это принесет доход, то еще и очень приятный бонус.

 

Ссылки теме:

1. DIRECTX FOR DELPHI

2. unofficial version of DelphiX

3. DirectX для начинающих

4. MinHook - The Minimalistic x86/x64 API Hooking Library

5. Various methods for capturing the screen

6. Вывод графики на рабочий стол Windows с использованием оверлеев DirectX

7. Project JEDI

8. Реализация перехвата вызовов API — исчерпывающе про внедрение DLL, если разобраться, + это на Delphi

UPD:

9. Серия видео уроков Пишем D3D-хук — все понятно, только в Delphi перенести нужно.

UPD 2:

Научился рисовать в Direct3D и ловить интерфейс IDirect3DDevice9. Теперь делаю DLL ловушку для реализации снимков.

 

Изменено пользователем Pax Beach

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 ответов на этот вопрос

  • 0
7 минут назад, Rusland сказал:

Поиск — это искусство.

Спасибо тебе огромное! Не понимаю, как я мог его не найти.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Приведенный класс не корректно работает в полноэкранном режиме.

К тому же в режиме DirectX не верно определяется видеоадаптер.

Разбираюсь с этим пока.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
23 минуты назад, Rusland сказал:

Может из этого граббера можно получить какую-то полезную информацию

компилится?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Компилится, но не понял как он должен грабить видео

Изменено пользователем Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 минуту назад, Rusland сказал:

Компилится, но не понял как он должен грабить видео

Это граббер с утройств, написер с камеры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
4 минуты назад, Rusland сказал:

тогда ой )

В этом видимо есть какой-то потенциал, если научиться получить DX контекст в качестве устройства для метода ICreateDevEnum

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Собственно где я это нашел,  и обсуждалось что нужно переделать эти исходники, чтобы делать снимок с DirectX

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
3 минуты назад, Rusland сказал:

Собственно где я это нашел,  и обсуждалось что нужно переделать эти исходники, чтобы делать снимок с DirectX

давай уже ссылку, может там люди что-нить еще рассказывают )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

ссылку не найду... но там старая тема и ничего интересно кроме этих исходников

Хотя вот нашел. Может тебе на Си писать dll? Есть же решения.

Еще чего-то про оверлеи, не знаю полезно ли оно.

А может можно эмулировать нажатие Printscreen и брать из буфера обмена?

Изменено пользователем Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Никакие оверлеи, и уж тем более всяческие эмуляции нажатий, или посылки сообщений окну не позволят устойчиво снимать скрин direct-x приложения (полноэкранного). Директ работает не так, как GDI, а посему в определенный момент в памяти ничего не будет, там, откуда вы пытаетесь получить инфу. ЕДинственный метод - хучить вызовы и свою dll в процесс, как впрочем и делает большинство граберов, которые позволяют подобное (это если выражаться очень условно). Посему, если это не бот - решение именно такое. Вышеописанный класс работает НА direct-x но С экранной памятью - в полноэкранном режиме это бессмысленно

 

Вот, для общего развития C# – SCREEN CAPTURE WITH DIRECT3D 9 API HOOKS

Там шарп, но для понимания сути пойдет. Да и на крайний случай, можно либо переписать, либо засунуть в dll шарп-код а потом дергать оттуда нужное. 

 

P.S. к слову, если внизу цифры верные (для одного скрина), то это п... очень медленно. И на 10-ке, ну и на 8-ке со скрипом лучше использовать Desktop Duplication API. Скорость работы такая же, как и у GDI, но при этом чертовски маленькая нагрузка на систему.

Изменено пользователем Gingercat

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От Вадим Смоленский
      Целый месяц бодаюсь с Microsoft Store, пытаясь разместить у них свое UWP-приложение в виде пакета appx. Получаю отлуп за отлупом. Проблема: приложение должно располагать папкой для пользователя, отличной от установочного каталога, где он мог бы сохранять файлы. Там же должны храниться файлы настроек. Раньше, создавая дистрибутив в InnoSetup, я всегда предусматривал создание такой папки по адресу <user>\AppData\Roaming\MyApp. Теперь всё полагается указывать в разделе Deployment - но как там указать такой адрес? Вроде бы, есть графа "Remote path", и логично существовать каким-то макросам для нее, вроде AppData - но никакой информации на эту тему я найти не смог. Видел лишь упоминания таких макросов, как res, assets, classes, library - однако все они, как я понял, относятся к мобильным платформам.
      Попытки обходных маневров не удались. Сначала я решил всё класть в установочный каталог, а при первом запуске создавать нужную папку и перебрасывать в нее несколько файлов. На моем компьютере это работает, но при тестировании в Microsoft Store отчего-то валится (присылают скриншот с сообщением "Access is denied"). То ли нельзя стирать файлы в установочном каталоге, то ли нельзя в таком режиме создавать новый каталог. Потом я прочитал где-то, что UWP-приложениям всё равно, где лежат файлы, они могут их менять даже в установочном каталоге. Попробовал всё валить в одну кучу и так работать. Увы, опять отрапортовали о падении ("The app tries to create a file under WindowsApps folder").
      Получается, что все-таки нужно как-то заставить appx-дистрибутив создавать при установке папку по адресу <user>\AppData\Roaming\MyApp. Но как?
      Спрашивал на experts-exchange, там знатоков не нашлось. Если и здесь нет, может, кто-нибудь хотя бы подскажет, в каких местах есть смысл спросить?
    • От Вадим Смоленский
      Проект для Windows, автономная БД SQLite, никаких клиент-серверных дел, компоненты и операции самые простые: SQL-запрос в TFDQuery, вызов метода Open. Всё работает нормально, но отдельные пользователи жалуются на эпизодические непредсказуемые падения при поиске. Интересно, что после каждого такого падения всё опять функционирует нормально, но потом приложение не удается нормально закрыть, приходится вызывать диспетчер задач.
      Стабильно воспроизвести не могут ни пользователи, ни я сам. Мне удалось это считанные несколько раз - я лишь смог убедиться через отладчик, что проблема при закрытии связана именно с базой данных: вставлял в обработчик FormCloseQuery оператор TFDConnection.Close - и программа пару раз упала именно на этом операторе.
      Найти корень зла пока не удалось. Показалось только, что проблема возникает лишь тогда, когда поиск приводит к слишком большому (несколько тысяч) числу записей в TFDQuery.
      Может, стоит поменять какие-нибудь установки в TFDConnection или TFDQuery ?
    • От Вадим Смоленский
      Упаковываю свое приложение в appx при помощи кнопки Deploy в Deployment Manager. При этом в разделе Опций "Manifest File" выставлено "Auto Generate". В итоге получается файл AppxManifest.xml; насколько я понимаю, этот манифест также включается в состав итогового пакета appx.
      Пробую загрузить получившийся appx в Microsoft Store. Грузится очень долго и в итоге выдает ошибку: "You don't have permissions to specify the following namespaces in the appx manifest file of the package MyApp.appx: restricted namespace: http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
      В файле AppxManifest.xml действительно отыскивается такой фрагмент. Убираю его, заодно убираю фрагмент  <Capabilities> ... </Capabilities> (если не убрать, получившийся xml даже не отобразится в браузере), переименовываю в MyApp.manifest, меняю установку для манифеста на "Custom", указываю имя. Всё повторяю. Результат ровно тот же.
      Полностью меняю содержимое MyApp.manifest, беря шаблон отсюда. Всё повторяю. Результат опять тот же. Опять магазину не нравится фрагмент манифеста насчет restricted capabilities, которого теперь, по идее, там быть не должно.
      Такое ощущение, что при формировании пакета appx не имеют никакого значения установки по поводу манифеста. Он всегда запихивается в appx в некоем дефолтном варианте, повлиять на который невозможно.
      Или все-таки возможно?
    • От Вадим Смоленский
      При упаковке Windows-приложения в appx все дополнительные файлы приходится класть в одну папку с исполнимым файлом, ибо Deployment Manager, судя по всему, не предусматривает возможности сразу положить их в AppData. Но я все-таки хочу, чтобы некоторые файлы были легко доступны пользователям, поэтому организовал приложение так, что оно при первом запуске создает новый каталог в AppData:
      MyDirectory:=GetSpecialFolderPath(CSIDL_APPDATA)+'\MyApp'; CreateDir(MyDirectory); TDirectory.SetAttributes(MyDirectory,[TFileAttribute.faNormal]); После этого в созданный каталог переносятся некоторые файлы, и всё работает хорошо, за исключением одного момента: этот новый каталог невозможно открыть, например, в Проводнике. Из самого приложения легко можно открыть диалоговое окно и увидеть в нем этот каталог и все файлы; можно их читать и в них писать, но вне приложения этот каталог невидим. Всё равно что не существует.
      Мне казалось, что присвоение каталогу атрибута faNormal дожно все проблемы решить. Увы, не решает. В чем тут закавыка?
    • От Вадим Смоленский
      Устанавливая и запуская свое Windows-приложение, предназначенное для Microsoft Store и запакованное в appx, наткнулся на интересный феномен. Чтобы узнать адрес текущего каталога, я всегда использовал функцию SysUtils.GetCurrentDir. Полученный полный адрес был мне нужен, например, чтобы показывать в TWebBrowser файлы хелпов (относительные адреса там почему-то не прокатывают). Раньше адресом текущего каталога всегда был адрес, где лежит исполнимый файл - условно говоря, C:\Program Files\MyApp. Теперь, когда пакет создается по принципам UWP,  исполнимый файл и прочее хозяйство кладется в каталог C:\Program Files\WindowsApps\MyApp_1.0.0.0_x86__sp51hrchc9zqj.  При этом функция GetCurrentDir почему-то возвращает совершенно другой адрес, а именно C:\WINDOWS\system32. Соответственно, TWebBrowser ничего не показывает.
      Функция SysUtils.GetDir ведет себя так же.
      Как быть?
    • От Вадим Смоленский
      В RAD Studio, начиная с Berlin, предусмотрена возможность создавать пакеты appx для загрузки приложений в Microsoft Store. К сожалению, материалов на эту тему пока немного, толковая ссылка нашлась лишь одна:
      https://community.embarcadero.com/blogs/entry/appx-development-for-windows-10-store
      Там толково объяснено, как создать appx для приложения из одного исполнимого файла. Я попробовал, всё получилось. Но как быть, если пакет должен содержать и другие файлы? В моем случае это файл базы данных, целая папка html-файлов для хелпов, и т.п. Где я должен их указать? Логично было бы предположить, что за это ответственен манифест (Project => Options => Application => Manifest File), который можно кастомизировать. Но сколько я ни гуглил, не смог найти ничего о структуре этого манифеста применительно к файлам. Похоже, манифест здесь все-таки ни при чем.
      Раньше я всё это делал в Inno Setup. Как поступать теперь - непонятно...
    • От Edward Tarasov
      поставил этот патч 
      https://cc.embarcadero.com/item/30805
      Версия PAserver на mac стала - 10.1.1.37, test connection отвечает success, но при компиляции выдаеться ошибка - [PAClient Error] Error: E0014 Connection refused. Platform Assistant Server version mismatch - expecting version '10.0.1.23'. 
      10.0.1.23 - это старая версия PA... откатиться нельзя ибо не пашет, тоесть этот патч исправляет старую проблему - но добавляет эту... суть в том, как я понял после 4-х часовго гугления, что надо исправить PAclient, у которого версия почему то осталась старая... кто знает как с этим быть?
    • От Вадим Смоленский
      Коллеги! Хотел бы еще раз привлечь ваше внимание к проблеме, недавнее обсуждение которой, к сожалению, заглохло. Не был бы столь настойчив, но это касается всех из нас, кто работает с Windows. Речь о дефекте платформы FMX, выражающемся в том, что щелчок по иконке в панели задач не приводит к сворачиванию приложения, как это задумано. Пользователь sargon предложил следующее решение:
      WM_SYSCOMMAND: begin if wParam = SC_MINIMIZE then PlatformWin.MinimizeApp else if wParam = SC_RESTORE then PlatformWin.RestoreApp; DefWindowProc(HWND, uMsg, wParam, LPARAM); sleep(50); // у FMX какая-то беда с потоками, иногда при нажатии по иконуе приложения в TaskBar окно не сворачивается а снова активируется, sleep уменьшает количество таких глюков Winapi.Windows.SetActiveWindow(FormToHwnd(LForm)); // после разворота активирует окно - проверил в Berlin и Tokyo 10.2.2 end; Фрагмент нужно вставить в FMX.Platform.Win в функцию function WndProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
      Я последовал этому совету, но стало только хуже: перестало работать сворачивание даже при щелчке по системной кнопке "Minimize". С щелчком по иконке тоже никаких сдвигов. Что здесь может быть не так?
    • От Edward Tarasov
      Чего то под конец написания диплома, вылазиет все больше и больше ошибок... еще одна!
      Удалил не нужный layout - теперь пишет -'asentor for bron not found' , и так со всем чтобы не удалил - причем под винду компилиться норм, а с ведройдом беда! кто то сталкивался?
    • От Edward Tarasov
      Подскажите плз студенту, весь инет перерыл - ничего кроме tmapview не нашел, и тот позволяет только отображать маркеры и прокладывать через них маршрут... ок маршрут проложили а как включить навигацию? чтобы телка сказала - поверни те туда то.... не ясно, и возможно ли вообще такое? 
      Кстатить при использовании tmapview вместо карты - пустой экран.
      вообщем надо передать в tmapview мое местоположение и куда надо идти, затем включить навигацию
      Кто занет как сделать ?????????
      Или может есть возможность использовать встроенные возможности навигации?
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу