【发布时间】:2012-09-09 11:37:20
【问题描述】:
我正在尝试使用带有 WinAPI 的 C++ 编写的屏幕保护程序来适应多个显示器。我发现 this article 建议重写这个基本的 WM_PAINT 处理程序:
case WM_PAINT:
{
PAINTSTRUCT ps = {0};
HDC hdc = BeginPaint(hWnd, &ps );
DoDrawing(hdc, ps.rcPaint);
EndPaint(hWnd, &ps);
}
break;
void DoDrawing(HDC hDC, RECT rcDraw)
{
//Do actual drawing in 'hDC'
}
像这样合并多个屏幕的绘图:
case WM_PAINT:
{
PAINTSTRUCT ps = {0};
HDC hdcE = BeginPaint(hWnd, &ps );
EnumDisplayMonitors(hdcE,NULL, MyPaintEnumProc, 0);
EndPaint(hWnd, &ps);
}
break;
BOOL CALLBACK MyPaintEnumProc(
HMONITOR hMonitor, // handle to display monitor
HDC hdc1, // handle to monitor DC
LPRECT lprcMonitor, // monitor intersection rectangle
LPARAM data // data
)
{
RECT rc = *lprcMonitor;
// you have the rect which has coordinates of the monitor
DoDrawing(hdc1, rc);
// Draw here now
return 1;
}
但是我的问题是 BeginPaint() 在处理 WM_PAINT 消息后在 DC 中设置的特殊优化/剪辑呢?使用这种方法,它将丢失。知道如何在 EnumDisplayMonitors() 调用中保留它吗?
【问题讨论】:
-
是什么让您认为它正在丢失?
EnumDisplayMonitors正在阻塞,所以EndPaint()在完成之前不会被调用。哦,你到底想画什么?桌面一个窗口,每个监视器一个窗口还是其他窗口?通过在启动时枚举一次,您可能会更幸运。 -
我正在尝试为每台显示器专门绘制。否则,DC 会在所有显示器上展开/拉伸。
-
你的枚举告诉你哪个监视器被传递给
DoDrawing(),那么你在不同的监视器上绘制不同的东西的实际问题是什么?如果您更仔细地阅读文档,它会向您展示如何使用EnumDisplayMonitors()来绘制单个监视器。 -
好的,让我们假设这段代码用在一个只有一个监视器的系统上。在这种情况下,BeginPaint 将使 DC 准备好剪掉所有不必要的区域。如果我将代码保持原样(上面发布),则不会使用剪切区域,因为 EnumDisplayMonitors 将返回一个新的 DC。那就是我的意思。它会正常工作,只是效率不高......
标签: c++ winapi multiple-monitors gdi