使用DirectX 10/11的全屏游戏截图

时间:2019-08-12 10:08:44

标签: c++ directx

我整天都在搜索有关该主题的答案,这就是我发现的:

  1. WinAPI屏幕截图-否

  2. 您可以使用过时的DirectX 9截屏

  3. 您可以使用带有新DirectX的Hook截屏

我已经尝试过的:

#include <cstdio>
#include "screenshoter.h"
#include <d3d9.h>
#include <wincodec.h>
#include <Windows.h>
#include <iostream>
#include <string>
#include <Psapi.h>
#include <algorithm>
#include <vector>

HWND targetHWND = nullptr;

BOOL CALLBACK enumWindowsProc(__in HWND hWnd, __in LPARAM lParam) {
    int length = GetWindowTextLength(hWnd);
    if (length == 0)
        return true;
    auto buffer = new TCHAR[512];
    memset( buffer, 0, ( 512 ) * sizeof( TCHAR ) );
    GetWindowText( hWnd, buffer, 512 );
    auto windowTitle = std::string(buffer);
    DWORD proc = NULL;
    GetWindowThreadProcessId(hWnd, &proc);
    GetModuleFileNameEx(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, proc), nullptr, buffer, 512);
    auto filePath = std::string(buffer);
    auto pos = filePath.find_last_of('\\');
    auto fileName = filePath.substr(pos + 1);
    delete[] buffer;
    if (windowTitle == "Overwatch" && fileName == "Overwatch.exe")
        targetHWND = hWnd;
        //std::cout << Title: " << windowTitle << " |  Filename: " << fileName << std::endl;
    return true;
}

int screenshoter::take() {
    std::cout << EnumWindows(enumWindowsProc, NULL) << std::endl;
    IDirect3DSurface9* pRenderTarget=NULL;
    IDirect3DSurface9* pDestTarget=NULL;
    IDirect3D9 *pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    IDirect3DDevice9* Device=NULL;
    D3DPRESENT_PARAMETERS d3dpp = { 0 };
    D3DDISPLAYMODE DisplayMode;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = targetHWND;
    d3dpp.Windowed = ((GetWindowLong(targetHWND, GWL_STYLE) & WS_POPUP) != 0) ? FALSE : TRUE;
    if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &Device)))
    {
        pD3D->Release();
        return false;
    }
    const char file[] = "Pickture.bmp";
    // sanity checks.
    if (Device == NULL)
        return 0;

    // get the render target surface.
    HRESULT hr = Device->GetRenderTarget(0, &pRenderTarget);
    // get the current adapter display mode.
    hr = pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&DisplayMode);

    // create a destination surface.
    hr = Device->CreateOffscreenPlainSurface(DisplayMode.Width,
                                             DisplayMode.Height,
                                             DisplayMode.Format,
                                             D3DPOOL_SYSTEMMEM,
                                             &pDestTarget,
                                             NULL);
    //copy the render target to the destination surface.
    hr = Device->GetRenderTargetData(pRenderTarget, pDestTarget);
    //save its contents to a bitmap file.

    hr = D3DXSaveSurfaceToFile(file,
                               D3DXIFF_JPG,
                               pDestTarget,
                               NULL,
                               NULL);

    // clean up.
    pRenderTarget->Release();
    pDestTarget->Release();
    return 0;
}

我的程序搜索游戏进程/窗口

但是问题是我的系统上没有d3dx9.h

所以我不能使用D3DXIFF_JPG

0 个答案:

没有答案