2013-04-04 3 views
5

Ich verwende Delphi mit aktivierten VCL-Stilen und ich möchte die Farbe des TSplitter für mein Formular ändern. Ich überschreibe TSplitter.Paint in einer Interposer-Klasse, um eine dunklere Farbe als die Standard-VCL-Stile cBtnFace Farbe zu malen, aber es gibt erhebliche Flackern auf dem Formular bei der Größenänderung. Gibt es eine Möglichkeit, dieses Flackern zu entfernen?Delphi TSplitter flimmern Problem

Ich habe diese Dinge versucht, das Flimmern zu versuchen und zu reduzieren, aber keine gearbeitet haben:

  1. Deaktivieren VCL Stile (TSplitter.StyleElements := []).

  2. Ändern des Objektobjekts des VCL-Styles-Bitmap-Style-Designers für "Splitter", aber das Ändern dieses Objektelements ändert nicht die Darstellung des Splitters.

  3. Der Versuch, die WM_ERASEBKGND Nachricht auf TControl Objekte zu verarbeiten, aber ich war nicht in der Lage das Verfahren in meiner Klasse Einfügestück aufgerufen werden zu lassen.

    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; 
    

noch andere Ideen für immer auf einem TSplitter des flackernden los? Es gibt keine DoubleBuffer-Eigenschaft für TSplitter oder etwas ähnliches von dem, was ich sagen kann.

UPDATE

Leider kann ich die Code-Basis nicht teilen, aber ich kann Ihnen sagen, dass dies der richtige Weg ist die UI-Anwendung ist Setup, wenn die TSplitter flackert:

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) 

Es gibt Auch eine Symbolleiste und ein Hauptmenü am oberen Rand des Formulars, aber der Rest der UI-Komponenten sind auf alClient festgelegt (oder OnResized, um das Leerzeichen zu füllen).

Ich nahm an, da die BackgroundPanel hinter dem LeftPanel ist, TSplitter und RightPanel (dh Steuerung -> In den Hintergrund), würde die DoubleBuffered = True und ParentBackground = False auf dem BackgroundPanel helfen, das Flimmern von allen Komponenten auf einem sofortigen zu reduzieren/entfernen UI-Ebene davor (dh die TSplitter). Aber das scheint nicht der Fall zu sein.

Vielleicht werde ich versuchen, eine TPanel als Eltern von LeftPanel platzieren, TSplitter und RightPanel und legen Sie seine DoubleBuffered = True und ParentBackground = False. Ich muss das später versuchen und zurückkommen. Also, es würde wie folgt aussehen:

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 

Schließlich sollte ich das Doppel beachten Pufferung der TForm verlangsamt deutlich unter der Benutzeroberfläche, wenn (eine schwarze Spur auf der rechten Seite des Fensters) Ändern der Größe, nicht, wenn dabei andere UI Dinge wenn die Größe der App nicht geändert wird.

UPDATE 2

Leider, während mein Ansatz über (einen Hintergrund Mutter TPanel Erstellen), um das Flimmern auf dem TSplitter fixiert, es verursacht auch andere seltsame UI Probleme, vielleicht von denen einige @ David Heffernan spielte auf in die Kommentare. Im Moment habe ich das Flimmerproblem einfach verlassen, da der Splitter nur 1 Pixel breit ist und nur auf Breite + Höhe flackert.

+0

Ich warte immer noch auf die 'TFlickerFreeForm' oder' TFlickerFreeControl' eingeführt werden. –

+0

Weit gehende und manchmal unzureichende Lösung, aber haben Sie versucht, 'DoubleBuffered' zu aktivieren? –

+0

@JerryDodge Es gibt keine DoubleBuffered-Eigenschaft auf "TSplitter", wenn Sie das meinen (unten in meiner Frage). Ich habe versucht, 'DoubleBuffered' auf übergeordneten UI-Objekten ohne Erfolg zu aktivieren. – spurgeon

Antwort

3

Das Steuerelement TSplitter möglicherweise keine DoubleBuffered -Eigenschaft, aber diese Eigenschaft sollte auf der obersten Steuerelement, wo Sie Flimmern auftreten implementiert werden - in den meisten Fällen das Formular. Solange alle Steuerelemente ParentDoubleBuffered als Standard aktiviert haben, erhalten alle diese Änderung ebenfalls.

DoubleBuffered nicht immer Flicker beheben, und in einigen Situationen kann es schlimmer machen. Sie können nur die Größe DoubleBuffered während der Größenänderung berücksichtigen und diese nach der Größenänderung wieder deaktivieren. Diese Eigenschaft sollte nur für die Steuerelemente verwendet werden, die gerade skaliert werden. Wenn Sie beispielsweise die Größe des Formulars ändern, aktivieren Sie DoubleBuffered auf dem Formular. Wenn Sie jedoch nur den Inhalt eines Bereichs ändern, aktivieren Sie ihn nur für diesen Bereich (und alle untergeordneten Steuerelemente).

In Bezug auf die Leistungseinbuße Ihrer Anwendung aufgrund dieser Änderung, können Sie auch eine Markierung bei der Größenänderung in Betracht ziehen, die jede Programmausführung pausiert, die es möglicherweise durchnässt (alles was neu gezeichnet wird wie Etiketten, Bilder, etc.). Dies kann auch die Lösung für Ihr Problem sein (eigentlich könnte eine zweite Antwort sein).