0

我正在尝试使用带有 WinAPI 的 C++ 编写的屏幕保护程序来适应多个监视器。我发现这篇文章建议重写这个基本的 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() 调用中保留它吗?

4

1 回答 1

0

答案实际上在EnumDisplayMonitors的 MSDN 文档中有所描述。当您将 HDC 参数传递给 EnumDisplayMonitors 时,它传递给回调函数的 DC 是您最初通过这些更改传入的 DC 的子集:

  • 剪辑已进一步缩小,仅覆盖原始剪辑与监视器剪辑矩形的交叉点。
  • DC 的颜色格式适用于特定的监视器,而不是窗口的“主要”监视器。

请注意,在现代 Windows 中(至少从 Win8 开始),实际上您将永远不会真正看到 Window DC 的不同颜色格式,因为 GDI 始终以 32 位颜色运行。

于 2017-10-02T22:34:50.340 回答