使用IDXGISurface1 :: GetDC在辅助监视器捕获的屏幕上绘制鼠标光标

时间:2018-10-08 06:31:28

标签: c++ directx-11 directx-10 dxgi

我正在尝试使用IDXGISurface1::GetDC捕获鼠标光标,在这里我可以捕获主监视器光标,但是当我切换到辅助监视器时,我无法绘制鼠标光标,我使用DrawIconEx来绘制光标IDXGISurface1的帮助下,在捕获的图像上方。

此问题仅在Windows 8.1专业版中出现,我尝试DXGI desktop duplication sample使用GetMouseDrawMouse通过渲染管道发送。在主屏幕中,当切换到辅助屏幕时没有画图时,鼠标可以正常工作,这是同样的问题(在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);

0 个答案:

没有答案