2010-03-18 23 views
5

Tôi chưa viết gì với GDI một thời gian (và không bao giờ với GDI +), và tôi chỉ đang làm một dự án thú vị, nhưng với cuộc sống của tôi, tôi không thể cách để tăng gấp đôi bộ đệm GDI +GDI + đệm đôi trong C++

void DrawStuff(HWND hWnd) { 
    HDC   hdc; 
    HDC   hdcBuffer; 
    PAINTSTRUCT ps; 
    hdc = BeginPaint(hWnd, &ps); 
    hdcBuffer = CreateCompatibleDC(hdc); 
    Graphics graphics(hdc); 
    graphics.Clear(Color::Black); 

    // drawing stuff, i.e. bunnies: 

    Image bunny(L"bunny.gif"); 
    graphics.DrawImage(&bunny, 0, 0, bunny.GetWidth(), bunny.GetHeight()); 

    BitBlt(hdc, 0,0, WIDTH , HEIGHT, hdcBuffer, 0,0, SRCCOPY); 
    EndPaint(hWnd, &ps); 
} 

Các công trình trên (mọi thứ hiển thị hoàn hảo), nhưng nó nhấp nháy. Nếu tôi thay đổi Graphics graphics(hdc); thành Graphics graphics(hdcBuffer);, tôi sẽ không thấy gì cả (mặc dù tôi nên bitblt'ing buffer-> hWnd hdc ở dưới cùng).

đường ống dẫn Thông điệp của tôi được thiết lập đúng (WM_PAINT gọi DrawStuff), và tôi buộc một thông điệp WM_PAINT mỗi vòng lặp chương trình bằng cách gọi RedrawWindow(window, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);

Tôi có lẽ sẽ về một cách sai lầm để làm điều này, bất kỳ ý tưởng ? Các tài liệu MSDN là khó hiểu nhất.

Trả lời

6

CreateCompatibleDC(hdc) tạo DC có bitmap đơn sắc 1x1 pixel làm bề mặt bản vẽ. Bạn cũng cần phải CreateCompatibleBitmap và chọn bitmap đó vào hdcBuffer nếu bạn muốn một bề mặt vẽ lớn hơn.

Edit:

nhấp nháy đang được gây ra bởi WM_ERASEBKGND, khi bạn làm điều này

hdc = BeginPaint(hWnd, &ps); 

Bên trong lời kêu gọi BeginPaint, Windows sẽ gửi WndProc của bạn nhắn WM_ERASEBKGND nếu nó nghĩ rằng nền cần phải được vẽ lại, nếu bạn không xử lý thông điệp đó, thì DefWindowProc sẽ xử lý nó bằng cách điền vào hình chữ nhật vẽ bằng cọ lớp, vì vậy để tránh nhấp nháy, bạn nên xử lý nó và trả về TRUE.

case WM_ERASEBKGND: 
    return TRUE; // tell Windows that we handled it. (but don't actually draw anything) 

của Windows cho rằng nền của bạn nên được xoá hoàn toàn bởi vì bạn nói với nó rằng nó nên, đó là những gì RDW_ERASE phương tiện, vì vậy bạn có lẽ nên rời khỏi rằng trong số RedrawWindow bạn gọi

+0

Cảm ơn, tôi đã thêm hBmp = CreateCompatibleBitmap (hdc, WIDTH, HEIGHT); SelectObject (hdcBuffer, hBmp); để mã (và BitBlt hoạt động) nhưng nó vẫn nhấp nháy. –

1

Bạn đang xử lý WM_ERASEBKGND? Tôi tin rằng nó được gọi ngay trước khi WM_PAINT và thường blits màu nền của cửa sổ mà bạn có thể không muốn xảy ra.

2

bạn có thể thử cách sau ...

void DrawAll(CDC *pDC) 
{ 
    CRect rect; 
    GetClientRect(&rect); 

    Bitmap *pMemBitmap = new Bitmap(rect.Width(), rect.Height()); 

    Graphics* pMemGraphics = Graphics::FromImage(pMemBitmap); 

    Graphics graphics(pDC->m_hDC); 

    // use pMemGraphics do something.... 

    Status status; 
    if ((status = graphics.DrawImage(pMemBitmap, 0, 0)) !=Ok) 
    { 
     //some error 
    } 

    delete pMemGraphics; 
} 
+1

Vui lòng thêm mô tả vào mã của bạn để giải thích rõ hơn về giải pháp của bạn. chúng tôi đang ở đây để tìm hiểu làm thế nào để có được câu trả lời thời gian tiếp theo chúng ta gặp vấn đề này, không phải làm thế nào để sao chép chúng. –

+0

Sẽ không làm lộ pMemBitmap này? – Pruyque