Подтвердить что ты не робот

Захват визуального вывода приложения DirectX - даже в фоновом режиме?

Мне нужно захватить визуальный вывод (например, снимок экрана) окна DirectX. В настоящее время я использую этот подход.
Но, когда окно находится в фоновом режиме, оно захватывает все, что перед ним.

Я вижу, что окна DirectX визуализируются даже при минимизации или в фоновом режиме, поэтому это должно быть возможно.
Но как? (Он также должен быть быстрым, и, к сожалению, он тоже должен работать на Windows XP...)

Изменить: я очень занят в эти дни... Не волнуйтесь, я верну щедрость, если она истечет.

4b9b3361

Ответ 1

Чтобы захватить окна Direct3D, которые находятся в фоновом режиме (или отключены от экрана), я считаю, что у вас есть следующие возможности:

  • Внесите и перетащите Direct3D в целевое приложение по уже опубликованной ссылке или этот более современный пример ( EasyHook может быть трудно получить настройку, но она действительно работает очень хорошо) - вы всегда можете попросить о помощи в ее работе. Я использовал эту технику для захвата в нескольких играх без проблем (совсем недавно для проекта, созданного с помощью amilight-clone). Проблема с этим подходом заключается в том, что ваша проблема связана с защитой игры, вызывающей запреты, однако FRAP также использует привязку для достижения этой цели, поэтому, возможно, ваши проблемы преувеличены? Я думаю, что геймеры, запрещенные для снятия экрана, являются дорогостоящим способом узнать.

  • Для оконных приложений в Vista/Win 7 вы можете вводить и подключать DWM и делать запросы на захват через свою общую поверхность. У меня был этот работающий на Vista, но он не закончил работу над Windows 7, вот пример его работы для Windows 7 http://www.youtube.com/watch?v=G75WKeXqXkc. Основная проблема с этим подходом заключается в использовании недокументированного API, который может означать, что ваше приложение прерывается без какого-либо предупреждения при выпуске патчей Windows. Также вам придется переделать технику для каждого нового основного вкуса Windows. Это также не касается необходимости захвата в Windows XP.

  • Также в DWM есть API-интерфейс миниатюр. Это имеет ограничения в зависимости от того, что вы пытаетесь сделать. Здесь есть информация об этом API вместе с другим DWM API http://blogs.msdn.com/b/greg_schechter/archive/2006/09/14/753605.aspx

  • Существуют и другие способы перехвата вызовов Direct3D без использования EasyHook, например, замена различных DLL-оболочками. Здесь вы найдете различные методы перехвата/перехвата игры: http://www.gamedeception.net/

  • Просто принесите приложение Direct3D на передний план (что, как я полагаю, нежелательно в вашей ситуации) - это не будет работать для окон вне экрана, если вы также не переместите окно.

  • К сожалению, единственным решением для Windows XP, о котором я могу думать, является перехват Direct3D API в той или иной форме.

Просто уточнение рендеринга Direct3D и минимизация. Во время моего довольно ограниченного тестирования по этому вопросу я нашел, что это зависит от приложения; обычно не рекомендуется, чтобы рендеринг выполнялся, когда приложение сведено к минимуму (также этот ссылка), он продолжает отображаться в фоновом режиме.

ОБНОВЛЕНО: добавлена ​​дополнительная ссылка на более современный пример инъекции для точки 1.

Ответ 2

Быстрый google, и я нашел этот Code Project, который относится к Windows XP. Я не знаю, можете ли вы применить эти знания для Windows Vista и 7??

http://www.codeproject.com/Articles/5051/Various-methods-for-capturing-the-screen

EDIT:

Я тоже нашел эту статью:

http://www.codeproject.com/Articles/20651/Capturing-Minimized-Window-A-Kid-s-Trick

Это ссылки из сообщения Джастина из комментариев. Кажется, он работал над этим с кем-то (я вижу, что это ваша ссылка).

http://spazzarama.com/2009/02/07/screencapture-with-direct3d/

Ответ 3

Код, который вы связали с (spazzarama), который вы сказали, что используете в своем проекте, захватывает передний буфер вашего устройства DirectX. Вы попробовали захватить задний буфер? Исходя из кода на вашем сайте, вы можете изменить строку 90 из

device.GetFrontBufferData(0, поверхность);

to

Surface backbuffer = device.GetBackBuffer(0, 0, BackBufferType.Mono); SurfaceLoader.Save( "Screenshot.bmp", ImageFileFormat.Bmp, backbuffer);

Это также приведет к удалению строк 96-98 в вашем связанном примере. Бэкбуффер может генерироваться без препятствующего окна.

ИЗМЕНИТЬ

Не обращай внимания на все это. Я просто понял, что ваш связанный образец кода использует дескриптор окна для определения области экрана и фактически ничего не делает с окном DirectX. Ваш образец кода не будет работать вокруг препятствия, потому что ваш регион уже нарисован с другим окном перед ним к моменту его доступа.

Лучше всего избавиться от приложения, возможно, чтобы окно DirectX появилось в верхней части экрана перед запуском кода для захвата изображения. Вы можете использовать функцию Wind32API BringWindowToTop для этого (http://msdn.microsoft.com/en-us/library/ms632673%28VS.85%29.aspx).