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