我目前正在开发一个应用程序,它需要为连接到系统的每个屏幕提供一个HDC。
我目前使用的代码如下:
std::vector<HDC> dcs;
HDC dcMain = ::GetDC(nullptr); // <-- don't understand this
::EnumDisplayMonitors(dcMain, nullptr, MONITORENUMPROC(&DisplayMonitorCallback), LPARAM(&dcs));我的回访如下:
BOOL DisplayMonitorCallback(const HMONITOR monitor, const HDC hdcMonitor, const LPRECT lprcMonitor, std::vector<HDC>& dcs)
{
dcs.push_back(hdcMonitor);
// here is where it gets weird!
HBRUSH br = CreateSolidBrush(RGB(0, 255, 0));
auto rst = FillRect(hdcMonitor, lprcMonitor, br);
// Process all monitors
return TRUE;
}注意,我目前正在每个屏幕上呈现一个绿色画笔。在这种情况下(即在回调中),这是非常有效的。
现在,问题是,我正在捕获那些HDC,以便稍后使用。
因此,几行之后,我将迭代我的dcs向量:
for (HDC dc : dcs)
{
HBRUSH br = CreateSolidBrush(RGB(255, 255, 0));
RECT x = { 100, 100, 500, 500 };
auto rst = FillRect(dc, &x, br);
printf("%d", rst);
}所以,我的问题是:
dcMain,我必须传递这个,这是获得一个的好方法吗?HDC并在以后迭代它们时却不能工作?发布于 2016-09-01 22:49:45
EnumDisplayMonitors()文档中提到了这一点:
要最优地为每个显示监视器绘制整个虚拟屏幕,可以使用如下代码:
hdc = GetDC(NULL);EnumDisplayMonitors(hdc,NULL,MyPaintScreenEnumProc,0);ReleaseDC(NULL,hdc);HDCs仅在回调的内部有效。这是有意义的,因为必须获得一个HDC,然后发布,但是只有EnumDisplayMonitors()知道是如何获得每个HDC的,所以只有它知道如何正确地释放每个HDC。由于没有发布枚举HDC的API函数,这意味着HDC在枚举之外无效。
MSDN告诉您如何为给定的监视器获取HDC:
HMONITOR与设备上下文
每个物理显示都由HMONITOR类型的监视器句柄表示。有效的HMONITOR保证为非空。只要物理显示器是桌面的一部分,它就具有相同的HMONITOR。发送WM_DISPLAYCHANGE消息时,任何监视器都可能从桌面上移除,因此其HMONITOR无效或其设置发生更改。因此,当发送此消息时,应用程序应检查所有HMONITORS是否有效。
任何返回显示设备上下文( DC )的函数通常都会返回主监视器的DC。若要获得另一个监视器的DC,请使用EnumDisplayMonitors函数。或者,您可以使用来自GetMonitorInfo CreateDC.函数的函数的设备名称来使用创建DC。但是,如果函数(如GetWindowDC或BeginPaint )为跨越多个显示的窗口获取DC,则DC也将跨越这两种显示。例如:
向量hdc_vector;BOOL回调DisplayMonitorCallback(HMONITOR hMonitor,HDC hdcMonitor,LPRECT lprcMonitor,LPARAM dwData) { MONITORINFOEX = {0};mi.cbSize =相当大的( mi );if (GetMonitorInfo(hMonitor,&mi)) { HDC dc = CreateDC(NULL,mi.szDevice,NULL,NULL);if (dc) lprcMonitor}.返回TRUE;}
hdc_vector dcs;EnumDisplayMonitors(dcMain,nullptr,DisplayMonitorCallback,reinterpret_cast(&dcs));用于(HDC dc : dcs) {.}(HDC dc :dc) DeleteDC(dc);
由于您显然在使用C++11,所以我建议使用std::unique_ptr来管理HDC的内存,这样您就不必手动调用DeleteDC()了。我将使用lambda进行回调,并将std::vector更改为std::map (因此在需要时可以查找任何特定监视器的HDC ):
std::unique_ptr device_hdc;std::map device_hdc_map;device_hdc_map dcs;EnumDisplayMonitors(dcMain,nullptr,HMONITOR hMonitor,HDC hdcMonitor,LPRECT lprcMonitor,LPARAM dwData -> BOOL { MONITORINFOEX = {0};mi.cbSize = sizeof( mi );如果(GetMonitorInfo(hMonitor,&mi)) { HDC dc =CreateDC(空,mi.szDevice,空,空);if (dc) hMonitor= device_hdc(dc,&:DeleteDC);}.返回TRUE;},reinterpret_cast(&dcs );.对于(device_hdc_map::value_type &dc : dcs) { //根据需要使用dc.second.get(实际的HDC) .}
https://stackoverflow.com/questions/39276282
复制相似问题