Использование Desktop Duplication API

426
12 августа 2017, 03:45
#include "stdafx.h"
#include "stdafx.h"
#include "iostream"
#include "D3D9.h"
#include <Wincodec.h>
#include <chrono>
#include <shellapi.h>
#include <d3d11.h>
#include <dxgi1_2.h>
#include <Atlbase.h>
#include <comdef.h>
#include <windows.h>
#include <shlobj.h>
#include <shellapi.h>
#include <dxgi1_2.h>
#include <d3d11.h>
#include <memory>
#include <algorithm>
#include <string>
#pragma comment(lib, "D3D11.lib")
#pragma comment(lib, "D3d9.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "gdi32.lib")
using namespace System;
#define EXIT(hr) { if (FAILED(hr)) \
                { Console::WriteLine("Error!"); \
                Console::ReadKey(); return -1; } }
HBITMAP ExtractBitmap(ID3D11Texture2D* d3dtex, ID3D11Device* pDevice) 
{
    HRESULT hr;
    HBITMAP hBitmapTexture = NULL;
    HGDIOBJ hBitmap;
    D3D11_TEXTURE2D_DESC desc;
    ID3D11Texture2D* pNewTexture = NULL;
    D3D11_TEXTURE2D_DESC description;
    d3dtex->GetDesc(&desc);
    d3dtex->GetDesc(&description);
    description.BindFlags = 0;
    description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
    description.Usage = D3D11_USAGE_STAGING;
    if (FAILED(pDevice->CreateTexture2D(&description, NULL, &pNewTexture)))
    {
        Console::WriteLine("CreateTexture2D failed!");
        return NULL;
    }
    ID3D11DeviceContext* ctx = NULL;
    pDevice->GetImmediateContext(&ctx);
    ctx->CopyResource(pNewTexture, d3dtex);
    D3D11_MAPPED_SUBRESOURCE resource;
    UINT subresource = D3D11CalcSubresource(0, 0, 0);
    ctx->Map(pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource);
    // Copy from texture to bitmap buffer.
    uint8_t* sptr = reinterpret_cast<uint8_t*>(resource.pData);
    uint8_t* dptr = new uint8_t[desc.Width*desc.Height * 4];
    for (size_t h = 0; h < desc.Height; ++h)
    {
        size_t msize = std::min<size_t>(desc.Width * 4, resource.RowPitch);
        memcpy_s(dptr, desc.Width * 4, sptr, msize);
        sptr += resource.RowPitch;
        dptr += desc.Width * 4;
    }
    dptr -= desc.Width*desc.Height * 4;
    // Swap BGR to RGB bitmap.
    uint32_t *dPtr = reinterpret_cast<uint32_t*>(dptr);
    for (size_t count = 0; count < desc.Width*desc.Height * 4; count += 4)
    {
        uint32_t t = *dPtr;
        uint32_t t1 = (t & 0x00ff0000) >> 16;
        uint32_t t2 = (t & 0x000000ff) << 16;
        uint32_t t3 = (t & 0x0000ff00);
        uint32_t ta = (t & 0xFF000000);
        *(dPtr++) = t1 | t2 | t3 | ta;
    }
    hBitmapTexture = CreateCompatibleBitmap(GetDC(NULL), desc.Width, desc.Height);
    SetBitmapBits(hBitmapTexture, desc.Width*desc.Height * 4, dptr);
    return (HBITMAP)CopyImage(hBitmapTexture, IMAGE_BITMAP, desc.Width, desc.Height, LR_CREATEDIBSECTION);
}

int main(array<System::String^> ^args)
{
    HRESULT hr;
    // Supported feature levels.
    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
        D3D_FEATURE_LEVEL_9_1
    };
    D3D_FEATURE_LEVEL d3dFeatLvl;
    ID3D11Device* pDevice = nullptr;
    ID3D11DeviceContext* pImmediateContext = nullptr;
    // Get device object.
    hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE,
        NULL, 0, featureLevels,
        ARRAYSIZE(featureLevels),
        D3D11_SDK_VERSION,
        &pDevice,
        &d3dFeatLvl,
        &pImmediateContext);
    EXIT(hr);
    // Get DXGI device.
    IDXGIDevice* DxgiDevice = nullptr;
    hr = pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&DxgiDevice));
    EXIT(hr);
    // Get DXGI adapter.
    IDXGIAdapter* DxgiAdapter = nullptr;
    hr = DxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&DxgiAdapter));
    DxgiDevice->Release();
    DxgiDevice = nullptr;
    EXIT(hr);
    // Get DXGI output.
    IDXGIOutput* DxgiOutput = nullptr;
    hr = DxgiAdapter->EnumOutputs(0, &DxgiOutput);
    DxgiAdapter->Release();
    DxgiAdapter = nullptr;
    EXIT(hr);
    DXGI_OUTPUT_DESC OutputDesc;
    DxgiOutput->GetDesc(&OutputDesc);
    // Query interface for Output1.
    IDXGIOutput1* DxgiOutput1 = nullptr;
    hr = DxgiOutput->QueryInterface(__uuidof(DxgiOutput1), reinterpret_cast<void**>(&DxgiOutput1));
    DxgiOutput->Release();
    DxgiOutput = nullptr;
    EXIT(hr);
    // Create desktop duplication.
    IDXGIOutputDuplication* DeskDupl = nullptr;
    hr = DxgiOutput1->DuplicateOutput(pDevice, &DeskDupl);
    DxgiOutput1->Release();
    DxgiOutput1 = nullptr;
    EXIT(hr);
    DXGI_OUTDUPL_DESC OutputDuplDesc;
    DeskDupl->GetDesc(&OutputDuplDesc);
    ///////////////////////////////////////////////////////////////////////////
    ID3D11Texture2D* AcquiredDesktopImage = nullptr;
    IDXGIResource* DesktopResource = nullptr;
    DXGI_OUTDUPL_FRAME_INFO FrameInfo;
    // Get new frame.
    hr = DeskDupl->AcquireNextFrame(500, &FrameInfo, &DesktopResource);
    EXIT(hr);
    // If still holding old frame, destroy it.
    if (AcquiredDesktopImage)
    {
        AcquiredDesktopImage->Release();
        AcquiredDesktopImage = nullptr;
    }
    // Query interface for IDXGIResource.
    hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&AcquiredDesktopImage));
    DesktopResource->Release();
    DesktopResource = nullptr;
    EXIT(hr);
    HBITMAP hBmp = (HBITMAP)ExtractBitmap(AcquiredDesktopImage, pDevice);
    ///////////////////////////////////////////////////////////////////////////
    System::Drawing::Bitmap::FromHbitmap(IntPtr(hBmp))->Save("Screenshot.bmp");
    Console::WriteLine("END!");
    Console::ReadKey();
    return 0;
}

Привожу пример своего исходника по работе с Desktop Duplication API (на C++/CLI). К сожалению, не могу добиться от него результата - картинка получается пустая. Каким образом можно поправить этот код, чтобы он работал; +добавить цикл, чтобы можно было получать скрины не вызывая функцию целиком.

READ ALSO
Отправка Post запроса на Random.org

Отправка Post запроса на Random.org

Нужна помощь с Randomorg API

378
Вращение блока при движении мышкой

Вращение блока при движении мышкой

Нужна анимация как на сайте https://openaicom/ Карточка сверху в правом блоке и ряд внизу

549
Не работают стили с подгружаемых файлов

Не работают стили с подгружаемых файлов

Стили на сайте работают если добавлять с внешнего источника, если со своих файлов нетСайт на CakePHP

204