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

发布于 2024-12-06 16:53:43 字数 827 浏览 1 评论 0原文

我现在正在使用 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);
        宽度 = lpRect->右 - lpRect->左;
        高度 = lpRect->底部 - lpRect->顶部;
    
        HDC hDC = GetDC(hwnd);
        内存DC = CreateCompatibleDC(hDC);
        内存位图 = CreateCompatibleBitmap(hDC, 宽度, 高度);
        SelectObject(内存DC,内存位图);
        PatBlt(内存DC, 0, 0, 宽度, 高度, PATCOPY);
        ReleaseDC(hwnd, hDC);
    

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

  1. 之后如何恢复WM_PAINT中的窗口?

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

I'm writing now simple mspaint-like program in C++ using windows.h (GDI). For my program I need only pen tool. So, I need to store somewhere main window's picture (for ex. in memory HDC and HBITMAP) to draw it after in WM_PAINT message.

  1. When I first have to store window's HDC to my memory HDC and HBITMAP? In what message I should store window? For example, I think we can't do it in WM_CREATE because we have no window yet.

  2. What is the difference between PatBlt and BitBlt? What should I use for my app?

  3. How to copy window's HDC content to my memory HDC and Bitmap? I'm trying to do something like this:

        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);
    

But this don't work: program crashes.

  1. How to restore window in WM_PAINT after that?

  2. How to clear my window with white color?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云之铃。 2024-12-13 16:53:44

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;

1: I would recommend you lazy load your off-screen canvas as late as possible. If you need it in WM_PAINT and you haven't created it yet, create it then. If you need it at the point someone begins drawing, create it then. If it exists when you need it, then use it.

2: PatBlt fills a region of a bitmap using the device context's current brush. Brushes define patterns, which is why it's called PatBlt. BitBlt copies data from a source bitmap to a destination bitmap. You would use a BitBlt when you wanted to move the image from the off-screen bitmap to the frame buffer.

3: The lpRect parameter of GetClientRect is an output parameter. That means you have to supply the memory. In this case, GetClientRect is trying to write the rectangle to a null pointer and causing the crash.

RECT clientRect;
GetClientRect(hwnd, &clientRect);
width = clientRect.right - clientRect.left;
height = clientRect.bottom - clientRect.top;
断舍离 2024-12-13 16:53:44

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

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

WM_PAINT: seems to be the best place to create the memory hdc. You can do something like this

WM_PAINT:
if (!first_paint)
{
...code
first_paint = true;
}
...more code
break;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文