2013-05-01 124 views
0

我编写应用程序来绘制线,矩形,椭圆形在客户区。当我绘制任何东西时,我需要保存客户区的图像。当WM_PAINT消息出现时我将其恢复。如何保存hdc并恢复它?

我用HBITMAP来保存和恢复

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

但它不工作。请帮帮我。

+0

你能不能做到这一点最简单的方式做在WM_PAINT绘图以及(或代替)? – john 2013-05-01 16:23:35

+0

这在保存侧和恢复侧都是错误的。保存侧将只捕获可见像素。不可见的像素(例如,被另一个窗口覆盖)将不会被捕获。恢复方在WM_PAINT消息外调用'BeginPaint',这是不推荐的。在这种情况下,它会获得完全删除的DC,因为没有任何内容无效。你应该在'WM_PAINT'内完成所有的工作 - 当你想替换客户区时,绘制替换。当你想恢复旧的客户区时,执行旧的绘图代码。 – 2013-05-02 19:46:18

回答

3

除非你真正建立在此做了艰辛的道路,我会放弃这种做法。我看到了两个合理的替代方案:

  1. 只需执行WM_PAINT中的所有绘图。当你想让线条,矩形,椭圆等消失时,设置一些变量(或其他)来表示它们已经消失,并使窗口无效以强制重绘。这是传统的方式,大部分时间都可以找到作品。

  2. 创建第二个窗口覆盖当前窗口的客户区。将其创建为窗口类中设置为CS_SAVEBITS样式的分层窗口。在这里绘制你的线条,椭圆等,当你希望它们消失时,简单地摧毁窗口。

CS_SAVEBITS自动执行你想现在做什么:保存区的窗口,它是用来恢复的基础窗口(完全自动)当CS_SAVEBITS窗口消失下一个位图。这两者目前你正在试图做的事情有同样问题的方式:保存位图并没有跟踪在基础窗口的任何变化 - 他们只是恢复一下有创建上窗口时,这可能会变得陈旧。如果底层窗口在整个持续时间内保持静态,它才能正常工作。

如果这是一个问题,结合两种方法:离开关叠加窗口上CS_SAVEBITS。当它被销毁时,底层窗口将失效,并通过正常的重新绘制逻辑恢复自身。