TTreeView - Verander Expand en Collapse Image?

Is het mogelijk om de Expandable en Collapse Image te gebruiken met de standaard TTreeView?

Ik bedoel niet Node-afbeeldingen, ik bedoel de kleine pijlen naast Nodes die kinderen hebben, zoals zo:

enter image description here

In het ideale geval zou ik willen dat de pijlen worden weergegeven als + en - Symbolen, zoals de Delphi-structuurstructuur voor componenten:

enter image description here

Als het mogelijk is om dit te veranderen, hoe zou ik het dan moeten doen?

Werkdemo op basis van het antwoord van David

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, Themes, uxTheme;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TMyTreeView = class(TTreeView)
  protected
    procedure CreateWnd; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyTreeView }

procedure TMyTreeView.CreateWnd;
begin
  inherited;
  if ThemeServices.Enabled and CheckWin32Version(6, 0) then
    SetWindowTheme(Handle, nil, nil);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  MyTree: TMyTreeView;
  Node: TTreeNode;
begin
  MyTree := TMyTreeView.Create(nil);
  with MyTree do
  begin
    Parent  := Self;
    Height  := 100;
    Width   := 100;
    Left    := 30;
    Top     := 30;

    Node := Items.Add(nil, 'Item');
    Items.AddChild(Node, 'Item');
    Node := Items.AddChild(Node, 'Item');
    Items.AddChild(Node, 'Item');
  end;
end;

end.

Het resultaat:

enter image description here

6

2 antwoord

Boomweergaven in post-Vista Windows hebben twee alternatieve thema's. Het thema dat u wilt vermijden staat bekend als het thema Verkenner. U wilt het standaardthema gebruiken. Een besturingselement moet zich aanmelden om het thema Verkenner te krijgen. Dit gebeurt via de SetWindowTheme API. Het VCL-boomstructuurbeheer roept dit op om zich aan te melden. Dit gebeurt aan het einde van de CreateWnd -methode.

U kunt terugkeren naar het standaardthema door de wijziging als volgt ongedaan te maken:

type
  TMyTreeView = class(TTreeView)
  protected
    procedure CreateWnd; override;
  end;

procedure TMyTreeView.CreateWnd;
begin
  inherited;
  if StyleServices.Enabled and TOSVersion.Check(6) and StyleServices.IsSystemStyle then
    SetWindowTheme(Handle, nil, nil);
end;

Deze code is geschreven voor XE2. Als je een eerdere Delphi hebt, dan denk ik dat je het zo wilt:

  if ThemeServices.Enabled and CheckWin32Version(6, 0) then
    SetWindowTheme(Handle, nil, nil);
9
toegevoegd
Je kunt de functie gewoon bellen vanuit het formulier OnCreate om het uit te testen. De CreateWnd-aanpak is wat u nodig hebt om "het goed te doen".
toegevoegd de auteur David Heffernan, de bron
zeer goed geïnformeerd :) Ik zal het laatste van uw geposte oplossing moeten proberen ..
toegevoegd de auteur user741875, de bron
werkt heel erg bedankt, ik zal het topbericht bewerken met de manier waarop ik je antwoord geïmplementeerd heb.
toegevoegd de auteur user741875, de bron

Ik toevoeging aan Davids antwoord. Plaats de volgende code in een extra eenheid en voeg deze toe aan het gebruik na de ComCtrls-eenheid. Op die manier kunt u de standaard TTreeView gebruiken en het thema veranderen wanneer u maar wilt. Of registreer het in uw eigen pakket als u dat wilt.

type
  TTreeView = class(ComCtrls.TTreeView)
  private
    procedure SetExplorerTheme(const Value: Boolean);
  public
    property ExplorerTheme: Boolean write SetExplorerTheme;
  end;

procedure TTreeView.SetExplorerTheme(const Value: Boolean);
begin
  if ThemeServices.ThemesEnabled and CheckWin32Version(6, 0) then
    if Value then
      SetWindowTheme(Handle, 'Explorer', nil)
    else
      SetWindowTheme(Handle, nil, nil);
end;

In nooit Delphi-versies kun je ook een klassenhelper gebruiken om de extra overerving te vermijden.

3
toegevoegd
Dit is geen klassenhelper. Klasse helpers zijn specifieke code construct (type THelper = klasse helper voor THelpedClass of iets dergelijks, ik ben niet zeker van de exacte syntax hier, omdat ik ze niet zoveel gebruik). Wat u in uw voorbeeld aan het doen bent, staat algemeen bekend als een interceptorklasse .
toegevoegd de auteur Marjan Venema, de bron
Achteraf misschien niet, maar het feit dat je je opmerking hebt verplaatst naar "vermijd verwarring" zegt veel ... :-)
toegevoegd de auteur Marjan Venema, de bron
Het is belangrijk om dit in CreateWnd te doen omdat de vensteringang opnieuw kan worden gemaakt.
toegevoegd de auteur David Heffernan, de bron
@Marjan Correct. En wat meer is, als u een interceptor gaat gebruiken, is CreateWnd direct beschikbaar om te worden genegeerd.
toegevoegd de auteur David Heffernan, de bron
Heb ik gezegd dat de code ergens een klassenhelper is?
toegevoegd de auteur Stefan Glienke, de bron