Truong Doan Quoc
Truong Doan Quoc

Reputation: 3

How to save hdc and restore it?

I write an application to draw line, rect, ellipse in client area. I need save image of client area when i draw any thing. And I restore it when message WM_PAINT occur.

I use HBITMAP to save and restore

SAVE

RECT rc;
GetClientRect(hMain, &rc); // hMain: handle main window
hdc = GetDC(hMain);
HDC hdcMem = CreateCompatibleDC(hdc);
// hbm: handle bitmap to save and restore
hbm = CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top);

SelectObject(hdcMem, hbm);
BitBlt(hdcMem, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
    hdc, rc.right - rc.left, rc.bottom - rc.top, SRCCOPY); 
ReleaseDC(hMain, hdc);

RESTORE

PAINTSTRUCT ps;
HDC hdc = BeginPaint(hMain, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
HDC hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hbm);
BitBlt(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
    hdcMem, rc.right - rc.left, rc.bottom - rc.top, SRCCOPY);
ReleaseDC(hMain, hdc);
EndPaint(hMain, &ps);

But it doesn't work. Please help me.

Upvotes: 0

Views: 806

Answers (1)

Jerry Coffin
Jerry Coffin

Reputation: 490108

Unless you're really set on doing this the hard way, I'd abandon this approach. I see two reasonable alternatives:

  1. Just do all the drawing inside of WM_PAINT. When you want the lines, rectangles, ellipses, etc., to disappear set some variable (or whatever) to indicate they're gone, and invalidate the window to force a redraw. This is the conventional way, and works find most of the time.

  2. Create a second window overlaying the client area of your current window. Create that as a layered window with the CS_SAVEBITS style set in its window class. Draw your lines, ellipses, etc., on here and simply destroy the window when you want them to disappear.

CS_SAVEBITS automatically does what you're trying to do right now: saves a bitmap of the area under the window, which is used to restore the underlying window (completely automatically) when the CS_SAVEBITS window disappears. Both this and the way you're currently trying to do things have the same problem: the saved bitmap does not track any changes in the underlying window -- they just restore what was there when the upper window was created, which may become stale. It only works correctly if the underlying window remains static for the duration.

If that's a problem, combine the two approaches: leave off the CS_SAVEBITS on the overlay window. When it's destroyed, the underlying window will be invalidated, and restore itself by normal re-paint logic.

Upvotes: 3

Related Questions