试图筛选特定监视器到缩略图的问题(在剪贴板上)
我在这里的最终目标是尝试在对话框上显示一小部分监视器缩略图。这样,用户就可以单击其中一个缩略图,然后我为它们执行某个操作。
我已经找到了如何使用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;
}
我遇到了两个问题:
- 当我将剪贴板粘贴到HypersNap中时,图像为空白。我预计这是相关的显示。
- 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:
- When I paste the clipboard into HyperSnap the image is blank. I anticipated it being of the display in question.
- 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论