我正在尝试使用IDXGISurface1::GetDC
捕获鼠标光标,在这里我可以捕获主监视器光标,但是当我切换到辅助监视器时,我无法绘制鼠标光标,我使用DrawIconEx
来绘制光标IDXGISurface1
的帮助下,在捕获的图像上方。
此问题仅在Windows 8.1专业版中出现,我尝试DXGI desktop duplication sample使用GetMouse
和DrawMouse
通过渲染管道发送。在主屏幕中,当切换到辅助屏幕时没有画图时,鼠标可以正常工作,这是同样的问题(在Windows 10中可以正常工作)。
我浏览了许多博客,但都没有得到任何解决方案,请帮我解决问题。
图像捕获代码:
//
// Get next frame and write it into Data
//
_Success_(*Timeout == false && return == DUPL_RETURN_SUCCESS)
DUPL_RETURN DUPLICATIONMANAGER::GetFrame(_Out_ FRAME_DATA* Data, _Out_ bool* Timeout, IDXGIOutputDuplication* m_DeskDupl)
{
IDXGIResource* DesktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
// Get new frame
HRESULT hr = m_DeskDupl->AcquireNextFrame(500, &FrameInfo, &DesktopResource);
if (hr == DXGI_ERROR_WAIT_TIMEOUT)
{
*Timeout = true;
return DUPL_RETURN_SUCCESS;
}
*Timeout = false;
if (FAILED(hr))
{
return ProcessFailure(m_Device, L"Failed to acquire next frame in DUPLICATIONMANAGER", L"Error", hr, FrameInfoExpectedErrors);
}
// If still holding old frame, destroy it
if (m_AcquiredDesktopImage)
{
m_AcquiredDesktopImage->Release();
m_AcquiredDesktopImage = nullptr;
}
// QI for IDXGIResource
hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_AcquiredDesktopImage));
DesktopResource->Release();
DesktopResource = nullptr;
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to QI for ID3D11Texture2D from acquired IDXGIResource in DUPLICATIONMANAGER", L"Error", hr);
}
Data->Frame = m_AcquiredDesktopImage;
Data->FrameInfo = FrameInfo;
return DUPL_RETURN_SUCCESS;
}
鼠标捕获代码:
bool TimeOut;
FRAME_DATA CurrentData;
HRESULT hr = S_OK;
BYTE* pBuf = NULL;
RECT rcOutput;
// Get respective monitor coordinates
hr = GetOutputRect(rcOutput);
DWORD dwOutputWidth = rcOutput.right - rcOutput.left;
DWORD dwOutputHeight = rcOutput.bottom - rcOutput.top;
pBuf = pBits;
std::vector<DXGIOutputDuplication> vOutputs = GetOutputDuplication();
// Iterating through multiple monitors.
for (std::vector<DXGIOutputDuplication>::iterator iter = vOutputs.begin(); iter != vOutputs.end(); iter++)
{
CComPtr<IDXGISurface1> spDXGISurface1;
DXGIOutputDuplication& out = *iter;
DXGI_OUTPUT_DESC outDesc;
out.GetDesc(outDesc);
//Call frame capturing method.
DUPL_RETURN Ret=GetFrame(&CurrentData, &TimeOut, out.m_DXGIOutputDuplication);
if (Ret != DUPL_RETURN_SUCCESS)
{
DoneWithFrame();
break;
}
if (TimeOut)
{
continue;
}
// Do copy resource
out.m_D3DDeviceContext->CopyResource(out.m_lGDIGPUImage, CurrentData.Frame);
HRESULT hr=out.m_lGDIGPUImage->QueryInterface(IID_PPV_ARGS(&m_lIDXGISurface));
if (FAILED(hr))
{
MessageBoxW(nullptr, L"Create QueryInterface failed.", L"Error", MB_OK);
}
else
{
CURSORINFO lCursorInfo = { 0 };
lCursorInfo.cbSize = sizeof(lCursorInfo);
auto lBoolres = GetCursorInfo(&lCursorInfo);
if (lBoolres == TRUE)
{
if (lCursorInfo.flags == CURSOR_SHOWING)
{
auto lCursorPosition = lCursorInfo.ptScreenPos;
auto lCursorSize = lCursorInfo.cbSize;
HDC lHDC;
// Get DC using IDXGISurface1::GetDC
m_lIDXGISurface->GetDC(FALSE, &lHDC);
DrawIconEx(
lHDC,
lCursorPosition.x,
lCursorPosition.y,
lCursorInfo.hCursor,
0,
0,
0,
NULL,
DI_NORMAL | DI_DEFAULTSIZE);
m_lIDXGISurface->ReleaseDC(nullptr);
}
}
}
out.m_D3DDeviceContext->CopyResource(out.m_DualImage,out.m_lGDIGPUImage);