2013-07-08 33 views
7

Próbuję emulować menu widoku drzewa lewego okna Outlook dla mojej aplikacji. Używam CustomDraw, ponieważ chcę tylko zmienić niektóre proste właściwości czcionki i tła.Niestandardowe losowanie wybranego elementu TTreeView

Oto, czego chcę:

Outlook 2013 sidebar menu

Jednak zawsze dotrzesz domyślny wybrany rysunek zarówno dla wybranych i gorących monitorowanych węzłów. Nie mam Windows 7 lub XP, aby zobaczyć, czy jest to normalne zachowanie, czy jest to coś związanego z moim systemem operacyjnym (Windows 8).

Oto co mi chodzi:

Bad imitation of an Outlook 2013 style sidebar menu

Oto mój kod:

procedure TMainForm.TreeView1CustomDrawItem(Sender: TCustomTreeView; 
    Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean); 
begin 
    if Node.Level = 1 then 
    Sender.Canvas.Font.Size := Sender.Canvas.Font.Size + 2; 

    if cdsHot in State then 
    Sender.Canvas.Brush.Color := $00F7E6CD 
    else if (cdsSelected in State) or (cdsFocused in State) or 
    (cdsChecked in State) then 
    Sender.Canvas.Brush.Color := $00F2F2F2 
    else 
    Sender.Canvas.Brush.Color := $00DEDEDE; 
    DefaultDraw := true; 
end; 

Jak mogę narysować innego koloru tła dla wybranych i gorących przedmiotów?

+1

Uważam, że trzeba odłączyć sterowanie, aby działało. Wyłącz kompozycje uruchomieniowe dla aplikacji lub przynajmniej wywołaj "SetWindowTheme" z pustymi ciągami w widoku drzewa. –

+0

Być może możesz zacząć od VirtualStringTree? –

+0

Właściwie, myślę, że nie mam racji. Dokumenty wyraźnie wspominają o paskach narzędzi, które musisz wyłączyć style wizualne, wywołując SetWindowTheme, ale nie wspominając o żadnej innej kontroli. [Link] (http://msdn.microsoft.com/en-us/library/windows/desktop/ff919569%28v=vs.85%29.aspx). –

Odpowiedz

12

Spróbuj wykonać następujące czynności:

enter image description here

type 
    TTreeView = class(Vcl.ComCtrls.TTreeView) 
    protected 
    procedure CreateWnd; override; 
    end; 


uses uxtheme; 

procedure TTreeView.CreateWnd; 
begin 
    inherited; 
    SetWindowTheme(Handle, nil , nil); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 

    TreeView1.Font.Name := 'Segoe UI'; 
    TreeView1.HotTrack := True; 
    TreeView1.Font.Size := TreeView1.Font.Size + 1; 
    TreeView1.Color := $00DEDEDE; 

end; 

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView; 
    Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean); 
begin 

    if cdsFocused in State then begin 
    Sender.Canvas.Brush.Color := $00F2F2F2; 
    Sender.Canvas.Font.Color := clblack; 
    Sender.Canvas.Font.Style := Sender.Canvas.Font.Style + [fsBold]; 
    end else if cdsHot in State then 
    Sender.Canvas.Brush.Color := $00F7E6CD 
    else 
    Sender.Canvas.Brush.Color := $00DEDEDE; 

end; 

Objaśnienie:

Dokumentacja Microsoft na ten temat jest bardzo rozmyte, co mogę z całą pewnością powiedzieć, że ilekroć akcja (Wybór, śledzenie na gorąco, deselekcja itp. ...) jest wykonywany na elemencie (węźle), konkretna wiadomość jest wysyłana, ta wiadomość zawiera stan węzła za pośrednictwem flagi parametrów, która na samym końcu wewnętrznie decyduje o tym, jak element powinien być aktualizowany wizualnie w oparciu o bieżący motyw systemu Windows.

Jest to prawdopodobna przyczyna, dla której wyłączenie kompozycji składnika TreeView powoduje usunięcie domyślnego motywu prostokąta zaznaczenia &. Dokumentacja dla Control state flags wspiera tę teorię w częściowej.

+1

Jakiekolwiek wyjaśnienie, dlaczego musisz wyłączyć motywy na kontrole, aby zabarwić? –

+0

Ponieważ w przypadku motywów wybrane elementy są w zasadzie zamaskowane. Jego kolory są rysowane, ale pod aktualnym tematycznym obszarem selekcji. – Peter

+0

To nie jest poprawne, ale nie o to też chciałem zapytać. Niepoprawne, ponieważ te kolory są zwracane za pomocą elementów clrText i clrTextBk struktury NMTVCUSTOMDRAW, które mają być używane przez system podczas rysowania. System albo używa tych kolorów, albo nie, nie ma obrazu. Ale w każdym razie, co miałem zamiar zadać to czy masz jakieś referencje MS dla wyłączenia tematów na kontroli? W przeciwnym razie obserwowane zachowanie jest również zachowaniem, które obserwuję. –