开发者

MSPaint-like app writing. How to do BitBlt right?

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 ha开发者_运维百科ve 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?


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;


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;

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜