2010-03-18 23 views
5

Non ho scritto nulla con GDI per un po 'di tempo (e mai con GDI +), e sto solo lavorando a un progetto divertente, ma per la vita di me, non riesco a capire come raddoppiare tampone GDI +GDI + doppio buffering in 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); 
} 

I lavori precedenti (tutto rende perfettamente), ma sfarfalla. Se cambio Graphics graphics(hdc); a Graphics graphics(hdcBuffer);, non vedo nulla (anche se dovrei essere bitblt'ing il buffer-> hWnd hdc in fondo).

mio messaggio oleodotto è impostato correttamente (WM_PAINT chiama DrawStuff), e sto forzando un messaggio WM_PAINT ogni ciclo di programma chiamando RedrawWindow(window, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);

Sono probabilmente andando circa il modo sbagliato di fare questo, tutte le idee ? La documentazione MSDN è criptica al meglio.

risposta

6

CreateCompatibleDC(hdc) crea una DC con una bitmap monocromatica 1x1 pixel come superficie di disegno. È necessario anche CreateCompatibleBitmap e selezionare quella bitmap in hdcBuffer se si desidera una superficie di disegno più grande di quella.

Edit:

il tremolio è provocato da WM_ERASEBKGND, quando si esegue questa

hdc = BeginPaint(hWnd, &ps); 

All'interno della chiamata a BeginPaint, Windows invia il WndProc un messaggio WM_ERASEBKGND se pensa che il fondo deve essere ridisegnato, se non gestisci quel messaggio, DefWindowProc lo gestisce riempiendo il rettangolo di pittura con il tuo pennello di classe, quindi per evitare lo sfarfallio, dovresti gestirlo e restituire VERO.

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

di Windows pensa che il vostro sfondo deve essere cancellata perché si è detto che si deve, questo è ciò che RDW_ERASE mezzi, in modo probabilmente si dovrebbe lasciare che fuori della vostra RedrawWindow chiamata

+0

Grazie, ho aggiunto HBMP = CreateCompatibleBitmap (HDC, larghezza, altezza); SelectObject (hdcBuffer, hBmp); al codice (e il BitBlt funziona) ma sfarfalla ancora. –

1

State di manovrare in WM_ERASEBKGND? Credo che venga chiamato proprio prima di WM_PAINT e di solito blits il colore di sfondo della finestra che probabilmente non vorrai accadere.

2

si può provare segue ...

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

Aggiungi una descrizione al tuo codice, per una migliore spiegazione della tua soluzione. siamo qui per sapere come arrivare alle risposte la prossima volta che incontriamo questo problema, non come copiarle. –

+0

Questa perdita non pMemBitmap? – Pruyque