Domanda

nel tentativo di creare animazioni palla con GDI, ma non riesco a farlo funzionare. Ho creato una palla con questo

   Graphics graphics(hdc);

Pen penna (colore (255, 0, 0, 255));    graphics.DrawEllipse (e penna, sf, 0, 10, 10); Ho while che loop e aggiunge 1 al valore sf fondamentalmente simili sf ++; che provo per ridisegnare la finestra (che non funziona) così male finire con più di un cerchio; / qui è il ciclo (il ciclo è int WM_PAINT)

while(sd==1)//sd equals 1
    {
        sf++;
        onPaint(hdc);
        InvalidateRect (hWnd, NULL, TRUE);// this should repaint the window but it doesn't
        UpdateWindow(hWnd);
    }

grazie in anticipo Rami

È stato utile?

Soluzione

Al fine di raggiungere l'animazione vorrei suggerire di utilizzare un timer. Ad esempio:

int OnCreate(HWND window, WPARAM wParam, LPARAM lParam)
{
   SetTimer(window, TIMER_ID, 1000, 0);
   return 0;
}

Ora la finestra riceverà messaggi WM_TIMER ogni secondo (1000 ms). Si dovrebbe gestirli:

int OnTimer(HWND window, WPARAM wParam, LPARAM lParam)
{
   if(TIMER_ID == wParam)
   {
      /*do stuff*/
      InvalidateRect(window, NULL, TRUE);//force window to repaint
   }
   return 0;
}

, allora è necessario gestire il messaggio WM_PAINT per fare il disegno

int OnPaint(HWND window, WPARAM wParam, LPARAM lParam)
{
   PAINTSTRUCT ps;
   HDC dc = BeginPaint(&ps);
   Graphics graphics(hdc);
   graphics.Draw...
   EndPaint(&ps);
   return 0;
}

Altri suggerimenti

Ti rendi conto che si sta incrementando sf in un ciclo con un condizionale di (sd == 1), giusto? Quella volontà naturalmente solo ciclo essere inserito all'infinito o mai più perché il valore della deviazione standard non viene modificato in alcun modo. Hai usato il debugger a tutti qui? Perché avete bisogno di un tale ciclo in ogni caso? Non si dovrebbe essere chiamata OnPaint in un ciclo.

Se si desidera più di un cerchio, proprio tutti disegnare prima di ritornare dalla funzione. Mantenere una raccolta di dati che verranno utilizzati per disegnare i cerchi nel gestore OnPaint.

InvalidateRect invia un messaggio WM_ERASEBKGND, e se non si dispone di un hbrBackground (pennello per ridisegnare lo sfondo) membro della struttura WNDCLASS definito quando si crea la finestra non sarà ridisegnare lo sfondo a meno che non gestire il messaggio WM_ERASEBKGND da soli .

Se questo non è il problema, allora forse perché si sta chiamando UpdateWindow direttamente invece di polling e la gestione dei messaggi, il messaggio non viene mai WM_ERASEBKGND gestito. Prova sovrascrivendo il cerchio precedente, con il colore di sfondo prima di disegnare la nuova.

O chiamare SendMessage con WM_ERASEBKGRND come il messaggio.

Ho trovato un esempio su MSDN, che mostra come disegnare roba in puro Win32.

Non si dovrebbe chiamare invalidate o UpdateWindow in WM_PAINT, come UpdateWindow invia una nuova WM_PAINT-evento, e invalida ottenere accumulato fino al Avanti evento WM_PAINT.

Si dovrebbe dividere il codice in due funzioni, una per eseguire il movimento e l'altro per disegnare il vostro cerchio nella posizione attuale.

Il tuo Mover-funzione può essere chiamato da qualsiasi luogo (forse in una funzione di gestione del timer?) E dovrebbe terminare con

InvalidateRect (hWnd, NULL, TRUE);
UpdateWindow(hWnd);

Al fine di contrassegnare la zona client per redrawal e informare il finestra per ridisegnare se stessa.

Il tuo Draw () -. Funzione dovrebbe leggere la posizione impostata con la funzione di motore, e solo un disegnare un cerchio intorno a questa posizione

(Nota a margine: se si vuole ridurre al minimo lo sfarfallio e ottenere animazioni fluide, date un'occhiata a doppio buffer una volta a ottenere l'animazione di base installato e funzionante)

Aggiorna

ti mancava il comando UpdateWindow nel vostro Update-funzione Il vostro OnPaint-funzione viene chiamata solo quando un WM_PAINT-messaggio viene ricevuto dalla vostra applicazione, quindi è necessario inviare quelli.

UpdateWindow serve a questo scopo

VOID update(HDC hdc,HWND hWnd) 
{ 
    sf++; 
    FillRect(hdc,rect,(HBRUSH)(COLOR_WINDOW+1)); 
    InvalidateRect (hWnd, NULL, TRUE); 
    UpdateWindow(hWND);//<- This Line sends a wm_paint-message to your window in order to make it redraw itself
} 
//i didn't do any changes to the onPaint functon but here is the code for it 
VOID onPaint(HDC hdc) 
{ 
    Graphics graphics(hdc); 
    Pen pen(Color(255, 0, 0, 255)); 
    graphics.DrawEllipse(&pen, sf , 0, 10, 10); 
} 

//here is the while loop 
while(sd==1) 
{   onPaint(hdc); 
    update(hdc,hWnd); 
} 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top