Date: 13.09.2017 15:15:40
Не работает, потому что запроса одного кадра недостаточно. Один кадр не обязан содержать всю необходимую информацию: он может содержать только позицию указателя к примеру, а само изображение идет в следующем кадре. См. https://msdn.microsoft.com/en-us/library/windows/desktop/hh404615(v=vs.85).aspx
Поэтому нужно в цикле сохранять кадры, а потом уже думать, как из них собрать все что нужно. А чтобы получить следующий кадр без исключения, нужно правильно освобождать ресурсы. Как-то так:
ID3D11Texture2D* AcquiredDesktopImage = nullptr;
IDXGIResource* DesktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
HBITMAP hBmp;
Int32 num=0;
while(true)
{
// If still holding old frame, destroy it.
if (AcquiredDesktopImage)
{
AcquiredDesktopImage->Release();
AcquiredDesktopImage = nullptr;
}
// Get new frame.
hr = DeskDupl->AcquireNextFrame(5000, &FrameInfo, &DesktopResource);
if (FAILED(hr))
{
if(hr == DXGI_ERROR_ACCESS_LOST)
{
Console::WriteLine("DXGI_ERROR_ACCESS_LOST");
}
else if(hr==DXGI_ERROR_WAIT_TIMEOUT)
{
Console::WriteLine("DXGI_ERROR_WAIT_TIMEOUT");
}
else
{
Console::WriteLine("Failed to acquire next frame: 0x"+Convert::ToString(hr,16));
}
Console::ReadKey();
continue;
}
// Query interface for IDXGIResource.
hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&AcquiredDesktopImage));
DesktopResource->Release();
DesktopResource = nullptr;
EXIT(hr);
hBmp = (HBITMAP)ExtractBitmap(AcquiredDesktopImage, pDevice);
///////////////////////////////////////////////////////////////////////////
String ^ str="C:\\Images\\Screenshot";
str+=Convert::ToString(num);
str+=".bmp";
Console::WriteLine(Convert::ToString(num));
//save image to file
System::Drawing::Bitmap ^ bmp;
bmp=System::Drawing::Bitmap::FromHbitmap(IntPtr(hBmp));
bmp->Save(str);
delete bmp;//no longer need bitmap
hr = DeskDupl->ReleaseFrame();//no longer need the frame
if (FAILED(hr))
{
Console::WriteLine("Failed to release frame");
break;
}
num++;
System::Threading::Thread::Sleep(2000);//wait some time for next frame
}
Только что вы пытаетесь сделать? Для простого снимания скриншотов не обязательно приплетать DirectX. Можно наверно обойтись средствами GDI, скажем переносом BitBlt из одного DC в другой.
Автор: VadimTagil