BOOL WINAPI DwmGetDxSharedSurface ( HWND hwnd, HANDLE* phSurface, LUID* pAdapterLuid, ULONG* pFmtWindow, ULONG* pPresentFlags, ULONGLONG* pWin32kUpdateId )
//堆代码 duidaima.com //动态载入该函数 typedef HRESULT(WINAPI* DwmGetDxSharedSurface_t)(HWND, HANDLE*, LUID*, ULONG*, ULONG*, ULONGLONG*); DwmGetDxSharedSurface_t DwmGetDxSharedSurface = NULL; //获取地址 HMODULE hUser32 = LoadLibraryA("user32.dll"); if (hUser32 == NULL) { std::cout << "LoadLibraryA failed" << std::endl; return 0; } DwmGetDxSharedSurface = (DwmGetDxSharedSurface_t)GetProcAddress(hUser32, "DwmGetDxSharedSurface"); //Dwm函数 在 user32.dll 中,真是离谱 if (DwmGetDxSharedSurface == NULL) { std::cout << "GetProcAddress failed" << std::endl; return 0; } std::cout << DwmGetDxSharedSurface << std::endl;
其他,暂时还没了解。
HRESULT hr = S_OK; hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory)); if (FAILED(hr)) { throw "CreateDXGIFactory1 failed"; return 0; } pFactory->EnumAdapters(0, &pAdapter); const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; D3D11CreateDevice(pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_BGRA_SUPPORT, featureLevels, 6, D3D11_SDK_VERSION, &device, NULL, NULL); if (device == NULL) { throw "D3D11CreateDevice failed"; return 0; }
HANDLE phSurface = NULL; // 使用DWM截取屏幕 DwmGetDxSharedSurface(hWnd, &phSurface, NULL, NULL, NULL, NULL); if (phSurface == NULL) { throw "Get Shared Surface Failded"; return 0; }
HRESULT hr = S_OK; ID3D11Texture2D* sharedSurface = NULL; hr = device->OpenSharedResource(phSurface, __uuidof(ID3D11Texture2D), (void**)&sharedSurface);//打开对应资源 if (FAILED(hr)) { throw "OpenSharedResource failed"; return 0; } D3D11_TEXTURE2D_DESC shared_desc; sharedSurface->GetDesc(&shared_desc); D3D11_TEXTURE2D_DESC description; description.ArraySize = 1; description.BindFlags = 0; description.CPUAccessFlags = D3D11_CPU_ACCESS_READ; description.Format = DXGI_FORMAT_B8G8R8A8_UNORM; description.Height = shared_desc.Height; description.MipLevels = 1; description.SampleDesc = { 1, 0 }; description.Usage = D3D11_USAGE_STAGING; description.Width = shared_desc.Width; description.MiscFlags = 0; hr = S_OK; ID3D11Texture2D* texture = NULL; hr = device->CreateTexture2D(&description, NULL, &texture); if (FAILED(hr)) { sharedSurface->Release(); throw "CreateTexture2D failed"; return 0; } ID3D11DeviceContext* context = NULL; device->GetImmediateContext(&context); context->CopyResource(texture, sharedSurface); D3D11_MAPPED_SUBRESOURCE mappedResource; context->Map(texture, 0, D3D11_MAP_READ, 0, &mappedResource);这里我们其实就已经拿到了对应的图片资源
typedef struct D3D11_MAPPED_SUBRESOURCE { void *pData; UINT RowPitch; UINT DepthPitch; } D3D11_MAPPED_SUBRESOURCE;其中的pData应该是一段对应像素排列位BGRA的位图。RowPitch是每行数据站的字长。为了方便我采用的是用OpenCV直接读入这段数据
cv::Mat mat(shared_desc.Height, shared_desc.Width, CV_8UC4, mappedResource.pData, mappedResource.RowPitch); cv::imshow("mat", mat); cv::waitKey(0); //转BMP写出 std::vector<uchar> buffer; cv::imencode(".bmp", mat, buffer);当然也能用MFC
HBITMAP hbmp = CreateBitmap(shared desc.Width, shared desc.Height, 1 32, mappedResource.pData); CImage img; img.Attach(hbmp); img.Save(L"233.bmp"); img.Detach(); DeleteObject(hbmp);资源释放
context->Release(); texture->Release(); sharedSurface->Release(); device->Release(); pAdapter->Release(); pFactory->Release(); FreeLibrary(hUser32);采用CloseHandle没法正常关掉phSurface,暂时不知道什么解决或方法,或是需不需要关掉。
#pragma comment(lib, "d3d11.lib") #pragma comment(lib, "dxgi.lib")问题