Domanda

Okay, quindi nella mia richiesta, ci sono un sacco di WinAPI e pochi controlli personalizzati. Yay ...

Ora, normalmente, sarà solo silenzio stessi ridisegnare per le animazioni, cambiamento di stato, ecc .... e tutto funziona bene.

Ma io ho un metodo di classe Window chiamato fix (). Questo è chiamato ogni volta che l'intero fabbisogno della finestra per essere aggiornato. Si ridimensiona i controlli e invalida la finestra.

Quando questo accade, lo sfondo è disegnata, quindi il controllo scheda, poi tutti gli altri sulla parte superiore. Questo cause molto irritante lampeggiante, soprattutto quando il ridimensionamento della finestra (a causa di chiamate costanti a fix ()).

Quello che ho cercato:

  • WS_EX_COMPOSITED. Questo solo doppio buffer i singoli controlli. Il suo un miglioramento, ma il tremolante rimane inevitabilmente.
  • Spegnimento disegno di sfondo. risolve certo il problema, e in realtà rende le cose peggiori.

Quindi: ho bisogno di una tecnica / metodo / a che mi permette di raddoppiare-buffer della finestra nella sua interezza. Ho pensato che la gestione del messaggio WM_PAINT da solo potrebbe essere una soluzione, ma non saprei da dove cominciare. Ho la sensazione orribile questo non è nemmeno possibile ...

Si prega di aiuto, questo è un problema critico. Sarò molto sollevato quando questo piccolo problema stupido è stato risolto.

È stato utile?

Soluzione

E 'in questo momento che uno ha realizzato la profondità di Microsofts disprezzo per gli sviluppatori nativi. in realtà si potrebbe iniziare a nutrire illusioni paranoiche che Microsoft ha volutamente rotto pittura nativo al fine di costringere gli sviluppatori nativi di trasferirsi in WPF.

In primo luogo, considerare WS_EX_COMPOSITED. WS_EX_COMPOSITED sembra essere la senape: - si dice che impone un bottone per l'ordine vernice superiore per controlli figlio, e in fondo che i messaggi WM_PAINT vengono gestite in un batch. Si dice che è stato aggiunto in Windows 2000 (5.0) e, poche righe verso il basso, che non funziona con la composizione del desktop abilitati. cioè smette di funzionare come di Windows Vista (6.0), a meno che Aero Glass sia spento e che è intenzione di farlo?

Poi, ci sono due possibili "hack" per cercare di ottenere sfarfallio pittura al lavoro:

  • In primo luogo, è necessario mimimize la quantità dei ritocchi. WS_EX_CLIPCHILDREN | WS_EX_CLIPSIBLINGS sono necessarie per garantire che qualsiasi particolare area della finestra è dipinta una sola volta. BeginDeferWindowPos è necessario anche in batch le operazioni di ridimensionamento per assicurare che gli stati transitori - dove una finestra sovrappone a un altro -. non avvengono (vale a dire quando la finestra A è stata ridimensionata, ma finestra B non ha)

Naturalmente, quando si sta cercando di disegnare una finestra di dialogo dalla pelle, o utilizzare caselle di gruppo, o controlli struttura a schede, o un qualsiasi numero di altre restrizioni, WS_EX_CLIPSIBLINGS è solo non è appropriato.

  • WM_SETREDRAW è un messaggio di magia. Non v'è alcuna API per accedere a questa funzionalità: WM_SETREDRAW è direttamente gestita dal DefWindowProc per segnare essenzialmente alla finestra come nascosto per tutta la durata. Dopo WM_SETREDRAW, FALSE viene inviato, chiamate a GetDC / GetDCEx / GetWindowDC etc utilizzando l'handle della finestra padre (e tutti i suoi figli) restituirà un DC che non disegnare sullo schermo. Questo vi dà la possibilità di fare un sacco di cose per le finestre figlio, quando si è fatto inviare un WM_SETREDRAW,TRUE, (e poi ridipingere la finestra manualmente). Tutte le finestre bambino - naturalmente -. Vernice nel proprio tempo, e dopo che la finestra padre ha fatto il suo sfondo di cancellazione, quindi WM_SETREDRAW è nessun tipo di panacea

Dopo la rottura WS_EX_COMPOSITED, di WinForms In .NET e WPF ri-scritto i comandi da terra fino a non utilizzare i controlli nativi, in modo da poter cuocere in pittura tamponata lì. E alpha supporto troppo.

Altri suggerimenti

Hm. Prima la gente correre e vicino questo argomento come duplicato, sarà meglio menzione che il problema non è il doppio buffer per sé, ma sfarfallio quando riposizionamento controlli, per i quali "manuale" doppio buffering è solo una delle diverse soluzioni.

Potrebbe essere che per esempio BeginDeferWindowPos e amici possono correggere il tremolio.

Disclaimer: una volta conosceva quasi tutti i dettagli delle API Win16, ma è stato alcuni anni da quando ho fatto la programmazione a livello di API

.

Saluti e hth.,

- Alf

Senza codice faccio fatica a immaginare che cosa è la situazione attuale ... Ma si può provare a gestire WM_ERASEBKGND, restituisce TRUE ogni volta che li hai ricevuto per saltare cancellazione.

WM_ERASEBKGND maniglia per la vostra finestra e nell'attuazione escludere i rettangoli di ciascuno dei vostri controlli figlio, quindi riempire lo sfondo restante in modo appropriato e dire il quadro che hai dipinto lo sfondo urself restituendo true. Fate la stessa cosa per tutti gli altri controlli figlio che a loro volta contengono altri controlli come il controllo scheda nel tuo caso.

qui per un esempio utilizzando MFC.

NET c'è ControlStyle.AllPaintingInWmPaint Questo dovrebbe essere impostato su ogni finestra contenitore (quindi la finestra principale e le linguette). Non riuscivo a trovare un WinAPI equivalente. Ma ciò che fa è quello di spostare il dipinto dello sfondo da WM_ERASEBKGND a WM_PAINT. sottrae anche l'area del controllo figlio dal padre per evitare lo sfarfallio, Potrebbe essere che avete bisogno di farlo manualmente.

Sono sorpreso WS_EX_COMPOSITED non aiuta. Che dovrebbe funzionare, se si imposta che sulla finestra di livello superiore, e non chiamare RedrawWindow sui comandi secondari.

Anche essere sicuri di test con e senza DWM / Aero. È possibile ottenere risultati diversi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top