AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

TreeView CustomDrawItem - Windows 7 Themes

Ein Thema von NickelM · begonnen am 6. Apr 2012 · letzter Beitrag vom 15. Apr 2012
Antwort Antwort
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#1

TreeView CustomDrawItem - Windows 7 Themes

  Alt 6. Apr 2012, 08:30
Hallo zusammen,

Ich versuche gerade mit CustomDrawItem den ItemText zu zentrieren. Den Text zeichnen ist ja nicht das Problem. Wenn ich DefaultDraw auf False setzte, ist das "autozeichnen" des Rahmens eines selektierten Items weg. Nun hab ich versucht mit ThemesService, Details := ThemeServices.GetElementDetails(ttItemSelected); den Rahmen wieder zuzeichnen, aber da bekomm ich einen ganz anderen Rahmen. Mit TreeView1.Canvas.FillRect(NodeRect); fülle ich es ja nur mit der Farbe. Dass kann ja nicht stimmen, da es eine Art Farbverlauf bzw. Areo-Style ist (vermute ich zumindest mal ).

Der Aktuelle Code ist:
Delphi-Quellcode:
procedure TForm1.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
  var PaintImages, DefaultDraw: Boolean);
var DesignText : String;
    PosBegin,PosEnd : Integer;
    CSpacer : Boolean;
    NodeRect : TRect;
    TextS : String;
    Details : TThemedElementDetails;
begin
 if Stage = cdPrePaint then
 begin
  PosBegin := Pos('[',Node.Text);
  if PosBegin > 0 then
  begin
    PosEnd := PosEx(']',Node.Text,PosBegin);
    DesignText := LowerCase(Copy(Node.Text,PosBegin+1,PosEnd-PosBegin-1));
    CSpacer := Pos('cspacer',DesignText) > 0;
    if cspacer then
    begin
      DefaultDraw := False;
      TextS := Copy(Node.Text,PosEnd+1,Length(Node.Text));
      NodeRect := Node.DisplayRect(False);
      TreeView1.Canvas.FillRect(NodeRect); //Dafür müsste ich was anderes nehmen, nur was?
      DrawText(TreeView1.Canvas.Handle,
      PChar(TextS),Length(TextS),NodeRect,DT_CENTER or DT_VCENTER);
    end;
  end
  else DefaultDraw := True;
 end
 else
 DefaultDraw := True;
end;
Wie zeichne ich diesen Rahmen? Im Anhang ein Bild mit normal Item und CostomDrawItem von mir, zum Verständnis was ich machen möchte.
Habe auch DrawEdge versucht auch kein Erfolg.

Gruß
NickelM
Miniaturansicht angehängter Grafiken
ownerdraw.jpg  
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.098 Beiträge
 
Delphi 12 Athens
 
#2

AW: TreeView CustomDrawItem - Windows 7 Themes

  Alt 6. Apr 2012, 08:40
Delphi-Quellcode:
    Details := StyleServices.GetElementDetails(State);
    StyleServices.DrawElement(Canvas.Handle, Details, R);
Tipp (da du ja die VCL-Quellcodes hast) :

Strg+Linksklick auf TThemedElementDetails
und in der Unit nach TThemedElementDetails suchen und schauen, ob es was zum Zeichnen gibt (z.B. Funktionen mit "Draw" im Namen, welche sowas als Parameter annehmen)

altenativ:
Strg+Shift+F => in Verzeichnissen suchen => Filter: *.pas;*.dfm;*.dpr => Verzeichnis: C:\Program Files (x86)\Embarcadero => Unterverzeichnisse durchsuchen
Du hast ein "TThemedElementDetails" und willst wissen, was man damit macht.
und dann abgucken, bei dem was du findest
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 6. Apr 2012 um 08:48 Uhr)
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#3

AW: TreeView CustomDrawItem - Windows 7 Themes

  Alt 6. Apr 2012, 12:48
Naja, MSDN hab ich schon auch durchgeschaut, hab nicht das richtige gefunden.
Nochmal zum verständnis:
Mit welchem Befehl "emuliere" bzw. zeichne ich den Rahmen für einen selected TreeView Item. Das gleiche wie beim Windows 7 Startmenü links in der Liste, wenn ihr über die Items geht. Genau das suche ich. Nur wenn ich, wie schon erwähnt, den "angeblichen" Item-Theme(nämlich ttItemSelected, die anderen machen kein Unterschied) auswähle, bekomm ich nur von dem Control den Rahmen, nicht vom Item. Unter XP ist das einfach, da es nur einfarbig ist. Bei Windows 7 hat halt das TreeView diesen Style. Und ich weis halt nicht wie ich daran komme. Genau dies möchte ich gerne wissen, ob jemand das schonmal gemacht hat und hinbekommen hat.

Gruß NickelM
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Benutzerbild von Gollum
Gollum

Registriert seit: 14. Jan 2003
Ort: Boxberg
456 Beiträge
 
Delphi 10.1 Berlin Professional
 
#4

AW: TreeView CustomDrawItem - Windows 7 Themes

  Alt 10. Apr 2012, 10:27
Hallo,

was passiert, wenn Du in den PaintOptions folgendes hinzufügst?
Delphi-Quellcode:
 
  [toThemeAware,toUseBlendedImages,toUseBlendedSelection]
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#5

AW: TreeView CustomDrawItem - Windows 7 Themes

  Alt 12. Apr 2012, 22:21
Dies scheint aber nur bei VirtualTreeView möglich zusein. Zumindest in meiner Delphi Version ist dies nicht verfügbar. Ich schaue mir mal den Code von VirtualTreeView an, weil ich möchte ungern wegen sowas diese Komponente einbinden.
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.098 Beiträge
 
Delphi 12 Athens
 
#6

AW: TreeView CustomDrawItem - Windows 7 Themes

  Alt 12. Apr 2012, 22:38
Selbst Embarcadero weiß inzwischen wie super die TTreeView funktioniert
und nutztn für die IDE selber auch den VirtualTreeView.
http://www.delphipraxis.net/166309-m...ml#post1160829

Nja, die VTV ist vielleicht etwas schwerer bediehnbar, aber dafür kann die auch eine Menge.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (12. Apr 2012 um 22:42 Uhr)
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#7

AW: TreeView CustomDrawItem - Windows 7 Themes

  Alt 15. Apr 2012, 09:36
Habe es hinbekommen. Mit ein bischen Tricksen aber es geht. Wenn es interessiert hier eine kleine Doku.
Natürlich kann man dies nach belieben erweitern:
Delphi-Quellcode:
//Beim Items hinzufügen, die ihr selber Zeichnen wollt:
//Anstelle von 'Test' könnt ihr auch Variablen einfügen
var Text : PChar;
GetMem(Text,(Length('Test')+1)*SizeOf(Length));
StrPCopy(Text,'Test');
TreeView1.Items.Add(nil,'').Data := Text;
//Beim OnAdvancedCustomDrawItem
procedure TForm1.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
  var PaintImages, DefaultDraw: Boolean);
var NodeRect,TextRect : TRect;
    TextP : PChar;
    NewText : String;
    UndPos : Integer;
begin
  if (Stage = cdPrePaint) then
  begin
    If Node.Data <> nil then //Falls ihr noch normale Einträge habt, müsst ihr die If-Anweisung schreiben
    TextP := Node.Data;
    PaintImages := False; //Falls ihr eine ImageList eingefügt habt, und keine Bilder zeichen lassen wollt
  end;
  if (Stage = cdPostPaint) then
  begin
    If Node.Data <> nil then //Falls ihr noch normale Einträge habt, müsst ihr die If-Anweisung schreiben
    TextP := Node.Data;
    TextRect := Node.DisplayRect(True); //Um den linken Seitenabstand vom "normalen" Textanfang zubekommen
    NodeRect := Node.DisplayRect(False); //Gesammten Zeilen-Rect abfragen
    NodeRect.Left := TextRect.Left - 16; //NodeRect Left aktualisieren
    //NodeRect.Left := TextRect.Left; //Falls ihr die Bilder zeichnen lasst, müsst ihr diese Zeile steht die oben drüber nehmen
    SetBkMode(TreeView1.Canvas.Handle,TRANSPARENT);
    
    //Kleine Hilfsfunktion, da sonst das & Zeichen nicht angezeigt wird
    UndPos := Pos('&',TextP);
    if UndPos > 0 then
      NewText := StringReplace(TextP,'&','&&',[rfReplaceAll])
    else
      NewText := TextP;

    DrawText(TreeView1.Canvas.Handle,PChar(NewText),Length(NewText),
    NodeRect,TextFlags); //Für TextFlags halt die entsprechenden Flags einsetzten
    //Weitere Zeichenoperationen
    end;
  end;
end;
Ich muss zugeben, es nicht wirklich schön, aber es funktioniert.
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz