2013-05-01 111 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。當它被銷燬時,底層窗口將失效,並通過正常的重新繪製邏輯恢復自身。