2013-04-04 9 views
5

Sto usando Delphi con gli stili VCL abilitati e vorrei cambiare il colore del TSplitter per il mio modulo. Eseguo l'override di TSplitter.Paint in una classe interposer per dipingere un colore più scuro rispetto agli stili VCL predefiniti con il colore cBtnFace, ma quando si ridimensiona si verifica uno sfarfallio significativo sul modulo. C'è un modo per rimuovere questo sfarfallio?Delphi Problema di sfarfallio del TSplitter

ho provato queste cose per cercare di ridurre il tremolio, ma nessuno hanno lavorato:

  1. Disattivazione stili VCL (TSplitter.StyleElements := []).

  2. Modifica dell'elemento dell'oggetto Designer stile bitmap VCL Stili per "Splitter", ma la modifica di questo elemento oggetto non modifica l'aspetto dello splitter.

  3. Cercando di elaborare il messaggio WM_ERASEBKGND sugli oggetti TControl, ma non sono stato in grado di richiamare la procedura nella mia classe interposer.

    procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND; 
    ... 
    procedure TSplitter.WMEraseBkgnd(var Msg: TWMEraseBkgnd); 
    begin 
        // this is never invoked by the TSplitter 
        Msg.Result := 1; 
    end; 
    

Tutte le altre idee per sbarazzarsi del tremolio su un TSplitter? Non esiste una proprietà DoubleBuffer per TSplitter o qualcosa di simile da quello che posso dire.

UPDATE

Purtroppo, non posso condividere il codice di base, ma vi posso dire che questo è il modo in cui l'interfaccia utente dell'applicazione è di configurazione quando i TSplitter sfarfallii:

TForm (DoubleBuffered = False) 
-> BackgroundPanel (DoubleBuffered = True, ParentBackground = False) 
-> -> A TGradient, image and label to fill the BackgroundPanel 
-> LeftPanel (ParentBackground = False`, no flickering) 
-> -> LeftPanelFrame and frame content (selective double buffering) 
-> TSplitter 
-> RightPanel (ParentBackground = False, no flickering) 
-> -> RightPanelFrame and frame content (selective double buffering) 

C'è anche una barra degli strumenti e un menu principale nella parte superiore del modulo, ma il resto dei componenti dell'interfaccia utente sono impostati su alClient (o OnResized per riempire lo spazio).

ho pensato che dato che il BackgroundPanel è dietro l'LeftPanel, TSplitter, e RightPanel (vale a dire, di controllo -> Porta), il DoubleBuffered = True e ParentBackground = False sul BackgroundPanel contribuirebbe a ridurre/rimuovere il tremolio da qualsiasi componente su un immediato Livello UI di fronte ad esso (ad esempio, lo TSplitter). Ma questo non sembra essere il caso.

Forse proverò mettendo un TPanel come genitore di LeftPanel, TSplitter e RightPanel e impostare il suo DoubleBuffered = True e ParentBackground = False. Dovrò provarlo più tardi e tornare indietro. Quindi, sarebbe simile a questa:

TForm 
-> BackgroundPanel (DoubleBuffered = True, ParentBackground = False) 
-> -> A TGradient, image and label to fill the BackgroundPanel 
-> EncapsulatingPanel (DoubleBuffered = True, ParentBackground = False) 
-> -> LeftPanel (ParentBackground = False) 
-> -> -> LeftPanelFrame and frame content 
-> -> TSplitter 
-> -> RightPanel (ParentBackground = False) 
-> -> -> RightPanelFrame and frame content 

Infine, Vorrei sottolineare che il doppio buffer l'TForm rallenta sostanzialmente verso il basso l'interfaccia utente durante il ridimensionamento (una pista nera a destra della finestra), non quando a fare altre cose UI quando l'app non sta ridimensionando.

UPDATE 2

Purtroppo, mentre il mio approccio di cui sopra (la creazione di un fondo genitore TPanel) fissato lo sfarfallio sul TSplitter, ma ha anche causato altre questioni strano UI, forse alcuni dei quali @ David Heffernan allude a i commenti Per ora, ho appena lasciato il problema dello sfarfallio, poiché lo splitter è largo solo 1px e sfarfalla solo in larghezza + ridimensionamento in altezza.

+0

Sto ancora aspettando di introdurre 'TFlickerFreeForm' o' TFlickerFreeControl'. –

+0

Soluzione esagerata e talvolta insufficiente, ma hai provato a abilitare 'DoubleBuffered'? –

+0

@JerryDodge Non c'è alcuna proprietà DoubleBuffered su 'TSplitter' se è questo che intendi (parte inferiore della mia domanda). Ho provato a abilitare 'DoubleBuffered' sugli oggetti dell'interfaccia utente padre senza alcun risultato. – spurgeon

risposta

3

Il controllo TSplitter potrebbe non avere una proprietà DoubleBuffered, ma questa proprietà dovrebbe essere implementata sul controllo più in alto di dove si verifica lo sfarfallio, nella maggior parte dei casi, il modulo. Finché tutti i controlli hanno ParentDoubleBuffered ancora abilitati come predefiniti, acquisiranno anche questa modifica.

DoubleBuffered non risolve sempre lo sfarfallio e in alcune situazioni può peggiorare le cose. È possibile prendere in considerazione solo l'utilizzo di DoubleBuffered durante il ridimensionamento e quindi disattivarlo al termine del ridimensionamento. Questa proprietà dovrebbe essere utilizzata solo su quei controlli che vengono effettivamente ridimensionati. Ad esempio, quando si ridimensiona il modulo, abilitare DoubleBuffered nel modulo. Ma quando ridimensionate solo il contenuto di un pannello, abilitatelo solo per quel pannello (e tutti i suoi controlli figlio).

Per quanto riguarda il calo delle prestazioni dell'applicazione a causa di questa modifica, è possibile prendere in considerazione l'implementazione di un flag durante il ridimensionamento che interrompe l'esecuzione di qualsiasi programma che potrebbe impantanarsi (qualsiasi cosa che ridisegna come etichette, immagini, eccetera.). Questo suo sé può anche essere la soluzione al tuo problema (in realtà potrebbe essere una seconda risposta).

Problemi correlati