2013-04-04 18 views
5

Używam Delphi z włączonymi stylami VCL i chciałbym zmienić kolor wtyczki dla mojego formularza. Zastępuję TSplitter.Paint w klasie interposer, aby malować ciemniejszy kolor niż domyślny kolor VCL cBtnFace, ale przy zmianie rozmiaru występuje znaczące migotanie w formularzu. Czy istnieje sposób na usunięcie tego migotania?Problem migotania Delphi TSplitter

Próbowałem te rzeczy, aby spróbować zmniejszyć migotanie, ale żaden z nich nie pracował:

  1. Wyłączenie style VCL (TSplitter.StyleElements := []).

  2. Zmiana stylów VCL Element obiektu Projektant stylu mapy bitowej dla "Splittera", ale modyfikacja tego elementu obiektu nie zmienia wyglądu splittera.

  3. Próbując przetworzyć wiadomość WM_ERASEBKGND na TControl obiektów, ale nie udało mi się dostać procedura się nazywać w mojej klasie wrzutek.

    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; 
    

jakieś inne pomysły na pozbycie się migotania na TSplitter? Nie ma właściwości DoubleBuffer dla TSplitter lub czegoś podobnego z tego, co mogę powiedzieć.

UPDATE

Niestety, nie mogę podzielić kodzie, ale mogę powiedzieć, że jest to sposób, w jaki interfejs aplikacji jest ustawiony gdy TSplitter migocze:

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) 

Jest również pasek narzędzi i menu główne u góry formularza, ale pozostałe składniki interfejsu użytkownika są ustawione na alClient (lub OnResized, aby wypełnić obszar).

Sądziłem, że skoro BackgroundPanel jest za LeftPanel, TSplitter i RightPanel (tj sterowania -> na spód), z DoubleBuffered = True i ParentBackground = False na BackgroundPanel pomogłoby zmniejszyć/usunąć migotanie od jakichkolwiek elementów na natychmiastowe Warstwa interfejsu użytkownika przed nią (tj. TSplitter). Ale wydaje się, że tak nie jest.

Może spróbuję umieszczenie TPanel jako rodzic LeftPanel, TSplitter i RightPanel i ustawić jej DoubleBuffered = True i ParentBackground = False. Będę musiał spróbować później i wrócić. Tak, to będzie wyglądać następująco:

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 

Wreszcie Należy zauważyć, że podwójne buforowanie TForm znacznie spowalnia UI podczas zmiany rozmiaru (czarny szlak po prawej stronie okna), nie robiąc inne rzeczy UI gdy aplikacja nie zmienia rozmiaru.

UPDATE 2

Niestety, podczas gdy moje podejście powyżej (tworząc tło rodzica TPanel) stałe migotanie na TSplitter, ale również inne problemy spowodowane dziwne UI, być może z których niektóre @David Heffernan nawiązywał w komentarze. Na razie właśnie opuściłem problem z migotaniem, ponieważ splitter ma tylko szerokość 1px i miga tylko na zmianie szerokości i wysokości.

+0

Wciąż czekam na wprowadzenie 'TFlickerFreeForm' lub' TFlickerFreeControl'. –

+0

Poszukiwane i czasami niewystarczające rozwiązanie, ale czy próbowałeś włączyć 'DoubleBuffered'? –

+0

@JerryDodge Nie ma właściwości DoubleBuffered na 'TSplitter' jeśli to masz na myśli (na dole mojego pytania). Próbowałem włączanie "DoubleBuffered" na obiektach nadrzędnego interfejsu użytkownika bezskutecznie. – spurgeon

Odpowiedz

3

Element sterujący TSplitter może nie mieć właściwości DoubleBuffered, ale ta właściwość powinna zostać zaimplementowana w górnej najwyżej położonej kontrolce miejsca migotania - w większości przypadków formularza. Dopóki wszystkie kontrolki będą nadal włączone domyślnie, wszystkie one również uzyskają tę zmianę.

DoubleBuffered nie zawsze naprawia migotanie, aw niektórych sytuacjach może pogorszyć sytuację. Możesz rozważyć użycie tylko DoubleBuffered podczas zmiany rozmiaru, a następnie wyłączyć go po zmianie rozmiaru. Ta właściwość powinna być używana tylko w przypadku tych elementów sterujących, które w rzeczywistości są zmieniane. Na przykład, zmieniając rozmiar formularza, włącz DoubleBuffered w formularzu. Ale zmieniając rozmiar tylko zawartości panelu, włącz go tylko dla tego panelu (i wszystkich jego kontrolek podrzędnych).

Jeśli chodzi o spadek wydajności aplikacji ze względu na tę zmianę, można również rozważyć zastosowanie flagi podczas zmiany rozmiaru, która wstrzyma wykonywanie dowolnego programu, który może go uszkodzić (wszystko, co odrysowuje, takie jak etykiety, obrazy, itp.). To samo w sobie może być również rozwiązaniem twojego problemu (może to być druga odpowiedź).