Я пытаюсь захватить курсор мыши с помощью IDXGISurface1::GetDC
Здесь я могу захватить курсор основного монитора, но когда я переключаюсь на дополнительный монитор, я не могу нарисовать курсор мыши, я использую DrawIconEx
для рисования курсора поверх захваченногоИзображение с помощью IDXGISurface1
.
Эта проблема возникает только в Windows 8.1 pro, я пробовал с DXGI образец дублирования рабочего стола они используют 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);