2010-08-10 108 views
2

我創建了一個可以正常工作的動畫,但是它會彈出。我需要雙緩衝的幫助,因爲我對它一無所知。雙緩衝幫助

這是我的OnPaint()方法的代碼:

VOID onPaint(HDC hdc) 
{ 
    Graphics graphics(hdc); 
    Pen  pen(Color(255, 0, 0, 255)); 
    graphics.DrawEllipse(&pen, sf , 0, 10, 10); 
} 

它工作正常,但閃爍。我試過這個代碼,但它沒有工作:

VOID onPaint(HDC hdc,HWND hWnd) 
{ 
    HDC hDC=GetDC(hWnd);; 
    HDC memDC = CreateCompatibleDC(hDC); 
    HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,10,10); 
    HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC,hMemBmp); 
    BitBlt(hDC, 0, 0, 10, 10, memDC, 0, 0, SRCCOPY); 
    Graphics graphics(memDC); 
    Pen  pen(Color(255, 0, 0, 255)); 
    graphics.DrawEllipse(&pen, sf , 0, 10, 10); 

    // Always select the old bitmap back into the device context 
    SelectObject(memDC, hOldBmp); 
    DeleteObject(hMemBmp); 
    DeleteDC(memDC); 
} 
+1

您可以通過縮進四個空格來格式化您的代碼。 – 2010-08-10 22:28:32

+0

感謝您的提示,但對於我的問題 – Ramilol 2010-08-10 22:30:50

+1

在您的代碼示例中的任何想法,它看起來像你blitting新制作的內存DC,然後*然後*繪製它,這是通常的做法相反。 – JustJeff 2010-08-10 22:36:46

回答

9

它看起來像你只是過早地將屏幕外DC複製到顯示器。嘗試移動呼叫使用BitBlt降四線,使其最後一行開始清理,像這樣前:

VOID onPaint(HDC hdc,HWND hWnd) 
{ 
    // this line looks a little odd : 
    HDC hDC = GetDC(hWnd); 
    // .. usually the hdc parameter passed to onPaint would already refer to 
    // the on-screen DC that windows wants updated. Also worth noting is that 
    // when you use GetDC(), you should have a matching ReleaseDC() 
    // As a quick test, you might just replace the above line with 
    //  HDC hDC = hdc; 

    HDC memDC = CreateCompatibleDC(hDC); 
    HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,10,10); 
    HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC,hMemBmp); 

    // draw to the off-screen map .. 
    Graphics graphics(memDC); 
    Pen  pen(Color(255, 0, 0, 255)); 
    graphics.DrawEllipse(&pen, sf , 0, 10, 10); 

    // now that you've drawn on the offscreen map, go ahead 
    // and put it on screen. 
    BitBlt(hDC, 0, 0, 10, 10, memDC, 0, 0, SRCCOPY); 

    // Always select the old bitmap back into the device context 
    SelectObject(memDC, hOldBmp); 
    DeleteObject(hMemBmp); 
    DeleteDC(memDC); 
} 

有關此代碼的另一件事,你已經通過了一定「10」離屏位圖的寬度和高度,以及將寬度和高度參數用於執行副本的BitBlt()。窗口客戶端區域正在更新的可能性要大得多。 「黑色方塊」是將10x10屏幕外地圖拍攝到窗戶客戶區域的結果。您可以嘗試使用另一個GDI函數來獲取屏幕位圖的尺寸,或者至少您可以#define寬度和高度值,並在參數中使用這些值。

另一件殺死你的東西可能是'sf'在行「graphics.DrawEllipse(& pen,sf,0,10,10)」 - 因爲你創建了一個令人難以置信的小10x10地圖,如果'sf'的值是0..10之外的任何值,DrawEllipse()調用會將橢圓完全放在離屏地圖中可用像素的外部。因此,底線,您可能希望使屏幕外地圖與窗口客戶端區域大小相同,並確保將BitBlt()調用向下移動,以便在離線地圖上的所有繪圖操作完成後,屏幕地圖。

+0

我有相同的結果黑色正方形 – Ramilol 2010-08-10 22:44:13

+0

我得到一個錯誤不能轉換HWND HDC – Ramilol 2010-08-10 22:53:14

+0

如果這個onPaint函數被調用迴應WM_PAINT,那麼你應該使用BeginPaint獲取DC和EndPaint。您還需要獲得內存位圖和blit的正確大小,可能是GetClientRect。看起來你並沒有初始化內存位圖,所以除了橢圓形繪製的位置之外,你將擁有隨機數據。 – 2010-08-10 23:31:50