类似于MSPaint的应用程序编写。如何正确执行BitBlt?

问题描述 投票:1回答:2

我正在使用windows.h(GDI)在C ++中编写类似于mspaint的简单程序。对于我的程序,我只需要钢笔工具。因此,我需要将主窗口的图片存储在某个地方(例如,在内存HDC和HBITMAP中),以便在WM_PAINT消息中进行绘制。

  1. 当我第一次必须将窗口的HDC存储到内存HDC和HBITMAP时?我应该在什么消息中存储窗口?例如,我认为我们无法在WM_CREATE中完成此操作,因为我们还没有窗口。

  2. PatBlt和BitBlt有什么区别?我应该为我的应用程序使用什么?

  3. 如何将窗口的HDC内容复制到我的内存HDC和位图?我正在尝试做这样的事情:

        LPRECT lpRect;
        GetClientRect(hwnd, lpRect);
        width = lpRect->right - lpRect->left;
        height = lpRect->bottom - lpRect->top;
    
        HDC hDC = GetDC(hwnd);
        memoryDC = CreateCompatibleDC(hDC);
        memoryBitmap = CreateCompatibleBitmap(hDC, width, height);
        SelectObject(memoryDC, memoryBitmap);
        PatBlt(memoryDC, 0, 0, width, height, PATCOPY);
        ReleaseDC(hwnd, hDC);
    

但是这不起作用:程序崩溃。

  1. 此后如何在WM_PAINT中还原窗口?

  2. 如何用白色清除我的窗口?

c++ windows winapi gdi
2个回答
4
投票

1:我建议您尽可能延迟加载屏幕外画布。如果您在WM_PAINT中需要它,但尚未创建它,则创建它。如果在有人开始绘图时需要它,则可以创建它。如果您需要时存在它,请使用它。

2:PatBlt使用设备上下文的当前笔刷填充位图的区域。笔刷定义了图案,这就是为什么它被称为PatBlt的原因。 BitBlt将数据从源位图复制到目标位图。要将图像从屏幕外的位图移动到帧缓冲区时,可以使用BitBlt。

3:GetClientRect的lpRect参数是输出参数。这意味着您必须提供内存。在这种情况下,GetClientRect试图将矩形写入空指针并导致崩溃。

RECT clientRect;
GetClientRect(hwnd, &clientRect);
width = clientRect.right - clientRect.left;
height = clientRect.bottom - clientRect.top;

0
投票

WM_PAINT:似乎是创建内存hdc的最佳位置。你可以做这样的事情

WM_PAINT:如果(!first_paint){...码first_paint = true;}...更多代码休息;

© www.soinside.com 2019 - 2024. All rights reserved.