为什么我要一遍又一遍地调用 `GetDC` 和 `ReleaseDC`?

Why should I call `GetDC` and `ReleaseDC` again and again?

我看到的每个示例代码都是 GetDCReleaseDC 被一次又一次地调用。或者 BeginPaintEndPaint.

但我认为在屏幕上绘图的情况非常频繁(尤其是在游戏中),因此将绘图存储在内存中比一直获取和释放设备上下文要好。

所以我采取了获取 DC 并“保留它”的方式,只有在程序结束时才释放它。但是为什么人们不这样做呢?是因为GetDCReleaseDC成本太低吗?

case WM_CREATE:
    hdc = GetDC(hWnd); //hdc is declared as global HDC
    MyBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));
    return 0;
case WM_PAINT:
    MemDC = CreateCompatibleDC(hdc);
    OldBitmap = (HBITMAP)SelectObject(MemDC, MyBitmap);
    BitBlt(hdc, 0, 0, 300, 300, MemDC, 0, 0, SRCCOPY);
    SelectObject(MemDC, OldBitmap);
    DeleteDC(MemDC);
    return 0;

您在此处提供的代码有误。首先,您需要阅读更多文档。这里有一个有用的link:Painting and Drawing。基本上有两种方法可以更新 window:

  • 响应 WM_PAINT 消息。使用 BeginPaintEndPaint 函数正确绘制客户区。当客户区的一部分“无效”时(由于调整大小、从最小化状态恢复、移动之前被遮挡的 window 或以编程方式使其无效),系统会发送此消息。WM_PAINT 是低优先级消息,在消息队列变空之前收到。
  • 专门绘制部分或整个客户区,上面没有无效区域。为此使用 GetDCReleaseDC。如果您希望在应用程序 (CPU) 繁忙时使更改立即可见,这很有用。

编写一些代码来处理 WM_PAINT 消息通常几乎是强制性的,而具体绘制也是可选的,具体取决于您的应用程序的要求。

切勿自己发送或post WM_PAINT 消息,而是使某个部分或客户区无效 - 应用程序将在空闲之前收到 WM_PAINT 消息。如果您希望绘画立即发生,请调用 UpdateWindow - 这会绕过消息队列。

Windows10 中最近(2016 年 8 月)的安全更新阻止了打印机设备上下文的重用。打印一份文档后 Windows 10 将拒绝使用同一个 DC 再次打印。为每个文档创建一个新的 DC 一直是首选做法,但现在这似乎是 Windows 10 中的要求。