试图筛选特定监视器到缩略图的问题(在剪贴板上)

发布于 2025-02-08 08:09:48 字数 2603 浏览 2 评论 0原文

我在这里的最终目标是尝试在对话框上显示一小部分监视器缩略图。这样,用户就可以单击其中一个缩略图,然后我为它们执行某个操作。

我已经找到了如何使用enumdisplayMonitors从此处的问题中获取监视矩形数组:

struct MonitorRects
{
    std::vector<RECT>   rcMonitors;
    std::vector<CString> strMonitorNames;

    static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
    {
        MonitorRects* pThis = reinterpret_cast<MonitorRects*>(pData);
        pThis->rcMonitors.push_back(*lprcMonitor);

        MONITORINFOEX sMI{};
        sMI.cbSize = sizeof(MONITORINFOEX);
        GetMonitorInfo(hMon, &sMI);

        pThis->strMonitorNames.push_back(sMI.szDevice);

        return TRUE;
    }

    MonitorRects()
    {
        EnumDisplayMonitors(nullptr, nullptr, MonitorEnum, (LPARAM)this);
    }
};

我将其扩展(用于时间到)以记住Monitor名称的列表。目前,我在clistbox中显示监视名称列表,以便用户选择这种方式,但最终我想要显示缩略图的列表。


因此,我的下一个任务是尝试创建屏幕抓取,并最初将其复制到剪贴板。我以为我会尝试将其粘贴到图像编辑器中,只是为了看看我是否捕获了正确的信息。因此,我创建了此功能(基于Internet上的代码):

BOOL CCenterCursorOnScreenDlg::CaptureRect(const CRect& rcCapture, CImage &rImage)
{
    // destroy the currently contained bitmap to create a new one
    rImage.Destroy();

    // create bitmap and attach it to this object 
    if (!rImage.Create(rcCapture.Width(), rcCapture.Height(), 32, 0))
    {
        AfxMessageBox(L"Cannot create image!", MB_ICONERROR);
        return FALSE;
    }


    // create virtual screen DC
    CDC dcScreen;
    dcScreen.CreateDC(_T("DISPLAY"), nullptr, nullptr, nullptr);

    // copy the contents from the virtual screen DC 
    BOOL bRet = ::BitBlt(rImage.GetDC(), 0, 0, rcCapture.Width(), rcCapture.Height(),
        dcScreen.m_hDC, rcCapture.left, rcCapture.top,
        SRCCOPY | CAPTUREBLT);

    // do cleanup and return
    dcScreen.DeleteDC();
    rImage.ReleaseDC();

    if (!(OpenClipboard() &&
        EmptyClipboard() &&
        ::SetClipboardData(CF_BITMAP, (HBITMAP)rImage)))
        AfxMessageBox(L"Error copying image to clipboard", MB_ICONERROR);
    CloseClipboard();

    return bRet;
}

我遇到了两个问题:

  1. 当我将剪贴板粘贴到HypersNap中时,图像为空白。我预计这是相关的显示。
  2. Hypersna“冻结”,我不得不崩溃。

我使用此代码在对话框中创建图像:

CRect rcMonitor = m_monitors.rcMonitors.at(0);
CImage img;
CaptureRect(rcMonitor, img);

请更新

如果执行此操作,

rImage.Save(L"d:\\testthumb.jpg", Gdiplus::ImageFormatJPEG);

:并手动打开JPG,它是正确捕获的屏幕。因此,在这种情况下,我的问题是将cimage复制到剪贴板。并不是说我真的需要这样做(因为我的最终目标是用户可以点击的缩略图列表。但是我最好现在坚持一个问题。

My ultimate goal here is to try and display a small list of monitor thumbnails on a dialog. This is so that the user can click on one of those thumbnails and I then perform a certain action for them.

I have found out how to use EnumDisplayMonitors to get the array of monitor rectangles from a question here on SO:

struct MonitorRects
{
    std::vector<RECT>   rcMonitors;
    std::vector<CString> strMonitorNames;

    static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
    {
        MonitorRects* pThis = reinterpret_cast<MonitorRects*>(pData);
        pThis->rcMonitors.push_back(*lprcMonitor);

        MONITORINFOEX sMI{};
        sMI.cbSize = sizeof(MONITORINFOEX);
        GetMonitorInfo(hMon, &sMI);

        pThis->strMonitorNames.push_back(sMI.szDevice);

        return TRUE;
    }

    MonitorRects()
    {
        EnumDisplayMonitors(nullptr, nullptr, MonitorEnum, (LPARAM)this);
    }
};

I extended it (for the timebeing) to also remember the list of monitor names. For now, I display the list of monitor names in a CListBox for the user to select that way, but eventually I want a list of display thumbnails.


So my next task was to try and create a screen grab and initially copy it to the clipboard. I thought I would try to paste it into a image editor, just to see if I had captured the right information. So I created this function (based on code on the internet):

BOOL CCenterCursorOnScreenDlg::CaptureRect(const CRect& rcCapture, CImage &rImage)
{
    // destroy the currently contained bitmap to create a new one
    rImage.Destroy();

    // create bitmap and attach it to this object 
    if (!rImage.Create(rcCapture.Width(), rcCapture.Height(), 32, 0))
    {
        AfxMessageBox(L"Cannot create image!", MB_ICONERROR);
        return FALSE;
    }


    // create virtual screen DC
    CDC dcScreen;
    dcScreen.CreateDC(_T("DISPLAY"), nullptr, nullptr, nullptr);

    // copy the contents from the virtual screen DC 
    BOOL bRet = ::BitBlt(rImage.GetDC(), 0, 0, rcCapture.Width(), rcCapture.Height(),
        dcScreen.m_hDC, rcCapture.left, rcCapture.top,
        SRCCOPY | CAPTUREBLT);

    // do cleanup and return
    dcScreen.DeleteDC();
    rImage.ReleaseDC();

    if (!(OpenClipboard() &&
        EmptyClipboard() &&
        ::SetClipboardData(CF_BITMAP, (HBITMAP)rImage)))
        AfxMessageBox(L"Error copying image to clipboard", MB_ICONERROR);
    CloseClipboard();

    return bRet;
}

I encounter two issues:

  1. When I paste the clipboard into HyperSnap the image is blank. I anticipated it being of the display in question.
  2. HyperSna "froze" and I had to crash it.

I used this code to create the image in the dialog:

CRect rcMonitor = m_monitors.rcMonitors.at(0);
CImage img;
CaptureRect(rcMonitor, img);

Update

If I do this:

rImage.Save(L"d:\\testthumb.jpg", Gdiplus::ImageFormatJPEG);

And manually open the JPG it is correctly captured of the screen. So in this instance my issue was copying that CImage to the clipboard. Not that I really need to do that (as my ultimate goal is a list of thumbnails the user can click. But I best stick with the one question for now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文